summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>1999-11-09 01:28:42 +0000
committerJason Molenda <jmolenda@apple.com>1999-11-09 01:28:42 +0000
commit38cff793ca34c134f3aaf46fff9da28aea7ead26 (patch)
tree360ca0b89a925adcc1c5d8753bf9280d07323c27
parent5105cd16e03c05dec76a04163956ed15c89a8aa6 (diff)
downloadgdb-38cff793ca34c134f3aaf46fff9da28aea7ead26.tar.gz
import dejagnu-1999-11-08 snapshot
-rw-r--r--dejagnu/AUTHORS4
-rw-r--r--dejagnu/COPYING340
-rw-r--r--dejagnu/ChangeLog5332
-rw-r--r--dejagnu/INSTALL183
-rw-r--r--dejagnu/Makefile.am50
-rw-r--r--dejagnu/Makefile.in412
-rw-r--r--dejagnu/NEWS3
-rw-r--r--dejagnu/README283
-rw-r--r--dejagnu/TODO8
-rw-r--r--dejagnu/aclocal.m4137
-rw-r--r--dejagnu/baseboards/README15
-rw-r--r--dejagnu/baseboards/a29k-udi.exp23
-rw-r--r--dejagnu/baseboards/arc-sim.exp37
-rw-r--r--dejagnu/baseboards/arm-ice.exp48
-rw-r--r--dejagnu/baseboards/arm-sim.exp52
-rw-r--r--dejagnu/baseboards/basic-sim.exp51
-rw-r--r--dejagnu/baseboards/cf.exp73
-rw-r--r--dejagnu/baseboards/cygmon.exp31
-rw-r--r--dejagnu/baseboards/cygwin.exp12
-rw-r--r--dejagnu/baseboards/d10v-sim.exp48
-rw-r--r--dejagnu/baseboards/d10v.exp56
-rw-r--r--dejagnu/baseboards/d30v-sim.exp33
-rw-r--r--dejagnu/baseboards/danlite-elf.exp42
-rw-r--r--dejagnu/baseboards/dos.exp25
-rw-r--r--dejagnu/baseboards/fr30-cygmon.exp31
-rw-r--r--dejagnu/baseboards/fr30-elf.exp40
-rw-r--r--dejagnu/baseboards/fr30-sim.exp34
-rw-r--r--dejagnu/baseboards/h8300-sim.exp44
-rw-r--r--dejagnu/baseboards/h8300.exp68
-rw-r--r--dejagnu/baseboards/i386-bozo.exp51
-rw-r--r--dejagnu/baseboards/i960-cyclone.exp47
-rw-r--r--dejagnu/baseboards/i960-sim.exp28
-rw-r--r--dejagnu/baseboards/jmr3904-sim.exp14
-rw-r--r--dejagnu/baseboards/m32r-elf.exp40
-rw-r--r--dejagnu/baseboards/m32r-sim.exp34
-rw-r--r--dejagnu/baseboards/m68k-emc.exp35
-rw-r--r--dejagnu/baseboards/mcore-elf.exp35
-rw-r--r--dejagnu/baseboards/mcore-moto-sim.exp125
-rw-r--r--dejagnu/baseboards/mcore-pe.exp35
-rw-r--r--dejagnu/baseboards/mcore-sim.exp37
-rw-r--r--dejagnu/baseboards/mips-idt.exp31
-rw-r--r--dejagnu/baseboards/mips-lnews-sim.exp5
-rw-r--r--dejagnu/baseboards/mips-lsi-sim.exp8
-rw-r--r--dejagnu/baseboards/mips-sim.exp30
-rw-r--r--dejagnu/baseboards/mips64-sim.exp29
-rw-r--r--dejagnu/baseboards/mips64vr4100-sim.exp33
-rw-r--r--dejagnu/baseboards/mn10200-cygmon.exp32
-rw-r--r--dejagnu/baseboards/mn10200-sim.exp45
-rw-r--r--dejagnu/baseboards/mn10300-cygmon.exp32
-rw-r--r--dejagnu/baseboards/mn10300-sim.exp41
-rw-r--r--dejagnu/baseboards/msparc-cygmon.exp1
-rw-r--r--dejagnu/baseboards/op50n.exp36
-rw-r--r--dejagnu/baseboards/powerpc-bug.exp29
-rw-r--r--dejagnu/baseboards/powerpc-bug1.exp5
-rw-r--r--dejagnu/baseboards/powerpc-sim.exp28
-rw-r--r--dejagnu/baseboards/powerpcle-sim.exp28
-rw-r--r--dejagnu/baseboards/rom68k-idp.exp69
-rw-r--r--dejagnu/baseboards/sh-hms-sim.exp48
-rw-r--r--dejagnu/baseboards/sh-hms.exp47
-rw-r--r--dejagnu/baseboards/sparc64-sim.exp31
-rw-r--r--dejagnu/baseboards/sparclet-aout.exp48
-rw-r--r--dejagnu/baseboards/sparclite-coff.exp41
-rw-r--r--dejagnu/baseboards/sparclite-cygmon.exp6
-rw-r--r--dejagnu/baseboards/sparclite-sim-le.exp47
-rw-r--r--dejagnu/baseboards/sparclite-sim.exp37
-rw-r--r--dejagnu/baseboards/strongarm-cygmon.exp41
-rw-r--r--dejagnu/baseboards/tic80-sim.exp28
-rw-r--r--dejagnu/baseboards/tx39-dve.exp48
-rw-r--r--dejagnu/baseboards/tx39-sim.exp8
-rw-r--r--dejagnu/baseboards/unix.exp8
-rw-r--r--dejagnu/baseboards/usparc-cygmon.exp48
-rw-r--r--dejagnu/baseboards/v850-sim.exp31
-rw-r--r--dejagnu/baseboards/vr4100-ddb.exp33
-rw-r--r--dejagnu/baseboards/vr4100-sim.exp12
-rw-r--r--dejagnu/baseboards/vr4111-sim.exp12
-rw-r--r--dejagnu/baseboards/vr4300-ddb.exp19
-rw-r--r--dejagnu/baseboards/vr4300-sim.exp12
-rw-r--r--dejagnu/baseboards/vr4300.exp41
-rw-r--r--dejagnu/baseboards/vr5000-ddb.exp40
-rw-r--r--dejagnu/baseboards/vx4300.exp25
-rw-r--r--dejagnu/baseboards/vx68k.exp25
-rw-r--r--dejagnu/baseboards/vx960.exp29
-rw-r--r--dejagnu/baseboards/vxsparc.exp25
-rw-r--r--dejagnu/baseboards/x86-cygmon.exp11
-rwxr-xr-xdejagnu/config.guess960
-rw-r--r--dejagnu/config/README34
-rw-r--r--dejagnu/config/arc.exp20
-rw-r--r--dejagnu/config/arm-ice.exp20
-rw-r--r--dejagnu/config/base-config.exp48
-rw-r--r--dejagnu/config/base68k.exp323
-rw-r--r--dejagnu/config/bug.exp29
-rw-r--r--dejagnu/config/cfdbug.exp31
-rw-r--r--dejagnu/config/cygmon.exp22
-rw-r--r--dejagnu/config/d10v.exp20
-rw-r--r--dejagnu/config/ddb-ether.exp190
-rw-r--r--dejagnu/config/ddb.exp96
-rw-r--r--dejagnu/config/dos.exp484
-rw-r--r--dejagnu/config/dve.exp22
-rw-r--r--dejagnu/config/gdb-comm.exp566
-rw-r--r--dejagnu/config/gdb_stub.exp638
-rw-r--r--dejagnu/config/h8300.exp20
-rw-r--r--dejagnu/config/i386-bozo.exp46
-rw-r--r--dejagnu/config/i960.exp221
-rw-r--r--dejagnu/config/m32r-stub.exp20
-rw-r--r--dejagnu/config/m32r.exp20
-rw-r--r--dejagnu/config/m68k-emc.exp52
-rw-r--r--dejagnu/config/mips-idt.exp24
-rw-r--r--dejagnu/config/mn10200-eval.exp22
-rw-r--r--dejagnu/config/mn10300-eval.exp22
-rw-r--r--dejagnu/config/netware.exp214
-rw-r--r--dejagnu/config/powerpc-bug.exp20
-rw-r--r--dejagnu/config/proelf.exp27
-rw-r--r--dejagnu/config/rom68k.exp32
-rw-r--r--dejagnu/config/sh.exp20
-rw-r--r--dejagnu/config/sim.exp124
-rw-r--r--dejagnu/config/slite.exp20
-rw-r--r--dejagnu/config/sparclet.exp26
-rw-r--r--dejagnu/config/tic80.exp81
-rw-r--r--dejagnu/config/udi.exp158
-rw-r--r--dejagnu/config/unix.exp134
-rw-r--r--dejagnu/config/vr4100.exp21
-rw-r--r--dejagnu/config/vr4300.exp21
-rw-r--r--dejagnu/config/vr5000.exp21
-rw-r--r--dejagnu/config/vrtx.exp50
-rw-r--r--dejagnu/config/vxworks.exp511
-rwxr-xr-xdejagnu/configure1594
-rw-r--r--dejagnu/configure.in24
-rw-r--r--dejagnu/contrib/README16
-rwxr-xr-xdejagnu/contrib/test-g++89
-rwxr-xr-xdejagnu/contrib/test-tool378
-rwxr-xr-xdejagnu/contrib/testit1149
-rw-r--r--dejagnu/doc/.cvsignore2
-rw-r--r--dejagnu/doc/Makefile.am47
-rw-r--r--dejagnu/doc/Makefile.in338
-rw-r--r--dejagnu/doc/README2
-rwxr-xr-xdejagnu/doc/configure860
-rw-r--r--dejagnu/doc/configure.in5
-rw-r--r--dejagnu/doc/dejagnu.texi3572
-rw-r--r--dejagnu/doc/overview.sgml439
-rw-r--r--dejagnu/doc/ref.sgml4242
-rw-r--r--dejagnu/doc/runtest.1118
-rw-r--r--dejagnu/doc/user.sgml2355
-rw-r--r--dejagnu/example/Makefile.am5
-rw-r--r--dejagnu/example/Makefile.in314
-rw-r--r--dejagnu/example/calc/Makefile.in110
-rw-r--r--dejagnu/example/calc/calc.129
-rw-r--r--dejagnu/example/calc/calc.c65
-rw-r--r--dejagnu/example/calc/calc.h.in18
-rwxr-xr-xdejagnu/example/calc/configure1031
-rw-r--r--dejagnu/example/calc/configure.in20
-rw-r--r--dejagnu/example/calc/testsuite/calc.test/calc.exp79
-rw-r--r--dejagnu/example/calc/testsuite/config/unix.exp68
-rw-r--r--dejagnu/i960glue.c19
-rwxr-xr-xdejagnu/install-sh250
-rw-r--r--dejagnu/lib/debugger.exp244
-rw-r--r--dejagnu/lib/dg.exp909
-rw-r--r--dejagnu/lib/framework.exp887
-rw-r--r--dejagnu/lib/ftp.exp246
-rw-r--r--dejagnu/lib/kermit.exp180
-rw-r--r--dejagnu/lib/libgloss.exp835
-rw-r--r--dejagnu/lib/mondfe.exp213
-rw-r--r--dejagnu/lib/remote.exp1265
-rw-r--r--dejagnu/lib/rlogin.exp173
-rw-r--r--dejagnu/lib/rsh.exp258
-rw-r--r--dejagnu/lib/standard.exp42
-rw-r--r--dejagnu/lib/target.exp789
-rw-r--r--dejagnu/lib/targetdb.exp113
-rw-r--r--dejagnu/lib/telnet.exp243
-rw-r--r--dejagnu/lib/tip.exp184
-rw-r--r--dejagnu/lib/util-defs.exp101
-rw-r--r--dejagnu/lib/utils.exp441
-rw-r--r--dejagnu/lib/xsh.exp322
-rwxr-xr-xdejagnu/mkinstalldirs32
-rwxr-xr-xdejagnu/runtest117
-rw-r--r--dejagnu/runtest.exp1809
-rw-r--r--dejagnu/site.tmpl48
-rw-r--r--dejagnu/stub-loader.c7
-rw-r--r--dejagnu/tcl-mode.el2223
-rw-r--r--dejagnu/testglue.c147
-rw-r--r--dejagnu/testsuite/Makefile.am5
-rw-r--r--dejagnu/testsuite/Makefile.in207
-rw-r--r--dejagnu/testsuite/config/default.exp79
-rw-r--r--dejagnu/testsuite/lib/libsup.exp220
-rw-r--r--dejagnu/testsuite/runtest.all/clone_output.test68
-rw-r--r--dejagnu/testsuite/runtest.all/config.test138
-rw-r--r--dejagnu/testsuite/runtest.all/default_procs.tcl94
-rw-r--r--dejagnu/testsuite/runtest.all/libs.exp92
-rw-r--r--dejagnu/testsuite/runtest.all/options.exp93
-rw-r--r--dejagnu/testsuite/runtest.all/remote.test217
-rw-r--r--dejagnu/testsuite/runtest.all/stats-sub.exp35
-rw-r--r--dejagnu/testsuite/runtest.all/stats.exp53
-rw-r--r--dejagnu/testsuite/runtest.all/target.test247
-rw-r--r--dejagnu/testsuite/runtest.all/topdir/subdir1/subfile11
-rw-r--r--dejagnu/testsuite/runtest.all/topdir/subdir1/subfile22
-rw-r--r--dejagnu/testsuite/runtest.all/topdir/subdir1/subsubdir1/subsubfile12
-rw-r--r--dejagnu/testsuite/runtest.all/topdir/subdir2/subfile22
-rw-r--r--dejagnu/testsuite/runtest.all/utils.test118
-rw-r--r--expect/CHANGES.2to358
-rw-r--r--expect/CHANGES.3to4115
-rw-r--r--expect/CHANGES.4to5263
-rw-r--r--expect/ChangeLog887
-rw-r--r--expect/Dbg.c1291
-rw-r--r--expect/Dbg.h60
-rw-r--r--expect/DbgMkfl.in232
-rw-r--r--expect/Dbg_cf.h.in21
-rw-r--r--expect/Dbgconfig.in117
-rwxr-xr-xexpect/Dbgconfigure1913
-rw-r--r--expect/FAQ1547
-rw-r--r--expect/HISTORY3042
-rw-r--r--expect/INSTALL253
-rw-r--r--expect/Makefile.in834
-rw-r--r--expect/NEWS562
-rw-r--r--expect/README366
-rw-r--r--expect/aclocal.m4621
-rwxr-xr-xexpect/configure6684
-rw-r--r--expect/configure.in1256
-rw-r--r--expect/example/Makefile75
-rw-r--r--expect/example/README141
-rwxr-xr-xexpect/example/archie36
-rwxr-xr-xexpect/example/autoexpect347
-rw-r--r--expect/example/autoexpect.man207
-rwxr-xr-xexpect/example/autopasswd11
-rwxr-xr-xexpect/example/beer.exp116
-rw-r--r--expect/example/beer.exp.out119
-rw-r--r--expect/example/beer.out119
-rw-r--r--expect/example/carpal26
-rwxr-xr-xexpect/example/chess.exp52
-rw-r--r--expect/example/chesslib++.c84
-rw-r--r--expect/example/chesslib.c80
-rw-r--r--expect/example/chesslib2.c84
-rwxr-xr-xexpect/example/cryptdir63
-rw-r--r--expect/example/cryptdir.man42
-rwxr-xr-xexpect/example/decryptdir63
-rw-r--r--expect/example/decryptdir.man42
-rwxr-xr-xexpect/example/dislocate342
-rw-r--r--expect/example/dislocate.man100
-rwxr-xr-xexpect/example/dvorak29
-rwxr-xr-xexpect/example/expectd.proto80
-rwxr-xr-xexpect/example/ftp-inband295
-rwxr-xr-xexpect/example/ftp-rfc34
-rwxr-xr-xexpect/example/gethostbyaddr326
-rwxr-xr-xexpect/example/irsh11
-rwxr-xr-xexpect/example/kibitz406
-rw-r--r--expect/example/kibitz.man266
-rwxr-xr-xexpect/example/lpunlock95
-rwxr-xr-xexpect/example/mkpasswd203
-rw-r--r--expect/example/mkpasswd.man95
-rwxr-xr-xexpect/example/passmass189
-rw-r--r--expect/example/passmass.man88
-rw-r--r--expect/example/passwd.cgi105
-rw-r--r--expect/example/passwd.html25
-rwxr-xr-xexpect/example/read1char8
-rw-r--r--expect/example/reprompt20
-rwxr-xr-xexpect/example/rftp339
-rwxr-xr-xexpect/example/rlogin-cwd14
-rwxr-xr-xexpect/example/rlogin-display18
-rw-r--r--expect/example/robohunt80
-rwxr-xr-xexpect/example/rogue.exp17
-rwxr-xr-xexpect/example/telnet-cwd13
-rw-r--r--expect/example/telnet-in-bg18
-rwxr-xr-xexpect/example/term_expect488
-rwxr-xr-xexpect/example/timed-read6
-rwxr-xr-xexpect/example/timed-run7
-rwxr-xr-xexpect/example/tknewsbiff515
-rw-r--r--expect/example/tknewsbiff.man412
-rwxr-xr-xexpect/example/tkpasswd630
-rwxr-xr-xexpect/example/tkterm409
-rwxr-xr-xexpect/example/unbuffer7
-rw-r--r--expect/example/unbuffer.man41
-rwxr-xr-xexpect/example/virterm634
-rwxr-xr-xexpect/example/vrfy27
-rwxr-xr-xexpect/example/weather81
-rwxr-xr-xexpect/example/xkibitz208
-rw-r--r--expect/example/xkibitz.man170
-rwxr-xr-xexpect/example/xpstat269
-rw-r--r--expect/example/xrlogin22
-rw-r--r--expect/exp_clib.c1202
-rw-r--r--expect/exp_closetcl.c22
-rw-r--r--expect/exp_command.c3709
-rw-r--r--expect/exp_command.h355
-rw-r--r--expect/exp_console.c68
-rw-r--r--expect/exp_event.c1081
-rw-r--r--expect/exp_event.h19
-rw-r--r--expect/exp_glob.c266
-rw-r--r--expect/exp_int.h34
-rw-r--r--expect/exp_inter.c2256
-rw-r--r--expect/exp_log.c261
-rw-r--r--expect/exp_log.h28
-rw-r--r--expect/exp_main_exp.c60
-rw-r--r--expect/exp_main_sub.c892
-rw-r--r--expect/exp_main_tk.c445
-rw-r--r--expect/exp_memmove.c25
-rw-r--r--expect/exp_noevent.c180
-rw-r--r--expect/exp_poll.c880
-rw-r--r--expect/exp_printify.c56
-rw-r--r--expect/exp_printify.h6
-rw-r--r--expect/exp_prog.h19
-rw-r--r--expect/exp_pty.c275
-rw-r--r--expect/exp_pty.h17
-rw-r--r--expect/exp_regexp.c1253
-rw-r--r--expect/exp_regexp.h8
-rw-r--r--expect/exp_rename.h22
-rw-r--r--expect/exp_select.c290
-rw-r--r--expect/exp_simple.c467
-rw-r--r--expect/exp_strf.c616
-rw-r--r--expect/exp_trap.c558
-rw-r--r--expect/exp_tstamp.h2
-rw-r--r--expect/exp_tty.c764
-rw-r--r--expect/exp_tty.h29
-rw-r--r--expect/exp_tty_comm.c36
-rw-r--r--expect/exp_tty_in.h100
-rw-r--r--expect/exp_win.c205
-rw-r--r--expect/exp_win.h20
-rw-r--r--expect/expect.c3035
-rw-r--r--expect/expect.h78
-rw-r--r--expect/expect.man2591
-rw-r--r--expect/expect_cf.h.in114
-rw-r--r--expect/expect_comm.h172
-rw-r--r--expect/expect_tcl.h47
-rw-r--r--expect/expectk.man42
-rwxr-xr-xexpect/fixcat21
-rwxr-xr-xexpect/fixline113
-rwxr-xr-xexpect/install-sh238
-rw-r--r--expect/libexpect.man690
-rwxr-xr-xexpect/mkinstalldirs32
-rw-r--r--expect/pkgIndex.in10
-rw-r--r--expect/pty_sgttyb.c248
-rw-r--r--expect/pty_termios.c752
-rw-r--r--expect/pty_unicos.c419
-rw-r--r--expect/tests/README91
-rw-r--r--expect/tests/all10
-rw-r--r--expect/tests/cat.test26
-rw-r--r--expect/tests/defs136
-rw-r--r--expect/tests/expect.test96
-rw-r--r--expect/tests/pid.test36
-rw-r--r--expect/tests/spawn.test65
-rw-r--r--expect/tests/stty.test26
-rw-r--r--expect/testsuite/ChangeLog49
-rw-r--r--expect/testsuite/Makefile.in103
-rw-r--r--expect/testsuite/config/default.exp107
-rwxr-xr-xexpect/testsuite/configure1385
-rw-r--r--expect/testsuite/configure.in25
-rw-r--r--expect/testsuite/exp_test.c33
-rw-r--r--expect/testsuite/expect.tests/expect-tests.exp104
-rw-r--r--expect/vgrindefs30
-rw-r--r--tcl/cygwin/Makefile.in1089
-rwxr-xr-xtcl/cygwin/configure5574
-rw-r--r--tcl/cygwin/configure.in1388
-rw-r--r--tcl/cygwin/tclConfig.sh.in133
-rw-r--r--tcl/doc/EvalObj.391
-rw-r--r--tcl/doc/ObjSetVar.3162
-rw-r--r--tcl/generic/panic.c99
-rw-r--r--tcl/generic/regexp.c1355
-rw-r--r--tcl/library/http2.0/http.tcl462
-rw-r--r--tcl/library/http2.0/pkgIndex.tcl11
-rw-r--r--tcl/library/opt0.1/optparse.tcl1099
-rw-r--r--tcl/library/opt0.1/pkgIndex.tcl7
-rw-r--r--tcl/tests/all22
-rw-r--r--tcl/tests/defs460
-rw-r--r--tcl/tests/iOUtil.test300
-rw-r--r--tcl/unix/porting.notes412
-rw-r--r--tcl/win/pkgIndex.tcl11
-rw-r--r--tcl/win/tcl16.rc37
-rw-r--r--tcl/win/tclWin16.c347
-rw-r--r--tcl/win/winDumpExts.c503
365 files changed, 115331 insertions, 0 deletions
diff --git a/dejagnu/AUTHORS b/dejagnu/AUTHORS
new file mode 100644
index 00000000000..3d634ad8f45
--- /dev/null
+++ b/dejagnu/AUTHORS
@@ -0,0 +1,4 @@
+The primary maintainer and creator of DejaGnu is Rob Savoye.
+ rob@welcomehome.org
+ www.welcomehome.org/rob.html
+
diff --git a/dejagnu/COPYING b/dejagnu/COPYING
new file mode 100644
index 00000000000..eeb586b392a
--- /dev/null
+++ b/dejagnu/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/dejagnu/ChangeLog b/dejagnu/ChangeLog
new file mode 100644
index 00000000000..376cdec1691
--- /dev/null
+++ b/dejagnu/ChangeLog
@@ -0,0 +1,5332 @@
+1999-11-04 Nick Clifton <nickc@cygnus.com>
+
+ * baseboards/arm-sim.exp: Underscore no longer needed for arm-pe
+ ports.
+
+Tue Oct 12 11:44:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/libgloss.exp (process_multilib_options): Add support for
+ generic gdb variable option - ``gdb:VARIABLE=VALUE''.
+
+1999-09-28 Angela Marie Thomas <angela@cygnus.com>
+
+ * lib/rsh.exp (rsh_download, rsh_upload): Use rcp_prog if set.
+
+1999-09-15 Stan Shebs <shebs@andros.cygnus.com>
+
+ * baseboards/d10v.exp: Request disable of X- and Z-packets
+ from GDB, all D10V boards respond incorrectly to these.
+
+1999-08-31 Doug Evans <devans@casey.cygnus.com>
+
+ * lib/target.exp (default_link): New local proc only--Ls.
+ Use it to pick out -L arguments in $ldflags.
+ Strip -Wl, from $ldscript.
+
+1999-07-12 Felix Lee <flee@cygnus.com>
+
+ * config/i960.exp: complain if 'sx' not found.
+
+1999-07-12 Drew Moseley <dmoseley@cygnus.com>
+
+ * baseboards/strongarm-cygmon.exp: Rename the StrongARM boards as
+ follows:
+ EBIX-DB -> SA-IOP
+ EBSA285 -> EBSA-285
+ BRUTUS -> SA1100DP
+ SA1100-MULTIMEDIA -> SA1100MM
+
+1999-06-08 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/framework.exp (record_test): Remove weird recursion and
+ make sure exit_status is properly set to 1.
+
+1999-06-08 Felix Lee <flee@cygnus.com>
+
+ * lib/telnet.exp (telnet_open): need to match '(Advanced or Simple)'
+
+1999-06-06 Felix Lee <flee@cygnus.com>
+
+ * lib/utils.exp (getdirs): When -all, return parents of
+ subdirectories too.
+
+1999-06-03 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * lib/remote.exp (standard_send): Add -- to protect strings that
+ start with a '-'; also added a verbose 3 statement with the send
+ command that is being issued.
+
+Fri May 21 17:36:56 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/target.exp: Don't import CC_FOR_TARGET, CXX_FOR_TARGET or
+ F77_FOR_TARGET from environment.
+
+Thu May 20 10:28:23 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/target.exp: Do not import CFLAGS_FOR_TARGET,
+ LDFLAGS_FOR_TARGET and ASFLAGS_FOR_TARGET from external
+ environment. GNUMAKE in conjunction with the top level Makefile
+ will set/export these variables according to the needs of the
+ target libraries. Such a configuration may not be applicable to
+ testsuites.
+
+1999-05-17 Keith Seitz <keiths@cygnus.com>
+
+ * baseboards/mcore-elf.exp: New file.
+ * baseboards/mcore-pe.exp: New file.
+ * baseboards/mcore-sim.exp: Don't run gdb's float tests
+ and increase timeout.
+
+1999-05-09 Nick Clifton <nickc@cygnus.com>
+
+ * baseboards/mcore-moto-sim.exp: New file: Support Motorola's
+ proprietry MCore simulator.
+
+1999-05-07 Stan Shebs <shebs@andros.cygnus.com>
+
+ From HP's WDB group:
+ * lib/target.exp: Add ability to pick CC_FOR_TARGET,
+ CFLAGS_FOR_TARGET, etc from env vars, add ability to use HP F77
+ compiler.
+
+1999-05-05 Stan Shebs <shebs@andros.cygnus.com>
+
+ * lib/utils.exp (getdirs): Add option -all to get subdirs too.
+
+1999-05-05 Jason Merrill <jason@yorick.cygnus.com>
+
+ * baseboards/sparclite-sim.exp: Set needs_status_wrapper.
+ * baseboards/sparclite-sim-le.exp: Likewise.
+
+1999-05-05 Angela Marie Thomas <angela@cygnus.com>
+
+ * baseboards/strongarm-cygmon.exp: Use "boardtype" instead of "name"
+ to avoid variable name clash in lib/target.exp. Add support for
+ ebsa and ebix boards.
+
+1999-05-04 Stan Shebs <shebs@andros.cygnus.com>
+
+ Finer control over test runs, from HP's WDB group:
+ * runtest.exp: Look for MULTIPASS in env also, define variable or
+ env var PASS to choose particular pass in multipass, search for
+ subdirs recursively, and if ignoredirs is set, skip over those
+ directories.
+ (--directory): New argument to limit test running to
+ a single directory.
+ (usage): Document, fix tabbing.
+
+Mon May 3 11:14:37 1999 Jim Wilson <wilson@cygnus.com>
+
+ * config/dos.exp (dos_load): Look for cygwin1.dll in addition to
+ cygwin.dll. New variable dll_name for use in download command.
+ * lib/libgloss.exp (winsup_include_flags): Change windows to windows.h.
+
+1999-04-27 Felix Lee <flee@cygnus.com>
+
+ * testsuite/runtest.all/stats.exp: make sure tmpdir is set
+
+ * baseboards/Makefile.am: deleted.
+ * config/Makefile.am: deleted.
+ * lib/Makefile.am: deleted.
+ * configure.in: delete references to the above.
+ * Makefile.am: install things correctly.
+
+ * testsuite/Makefile.am: set DEJATOOL.
+
+ * configure, Makefile.in, */Makefile.in: regenerated.
+
+ * runtest.exp: fix location of config.guess.
+
+1999-04-26 Felix Lee <flee@cygnus.com>
+
+ * lib/libgloss.exp (libgloss_link_flags): remove bogus -L flag.
+
+1999-04-23 Angela Marie Thomas <angela@cygnus.com>
+
+ * baseboards/cf.exp: gdb protocol is case-sensitive.
+
+1999-04-19 Nick Clifton <nickc@cygnus.com>
+
+ * baseboards/Makefile.am (boards): Add mcore-sim.exp
+
+1999-04-13 Angela Marie Thomas <angela@cygnus.com>
+
+ * baseboards/sh-hms-sim.exp: Pass "-m 18" to standalone sim.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * baseboards/mcore-sim.exp: New file: Definitions for MCore
+ simulator support.
+
+1999-04-07 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d30v-sim.exp (cflags): Add -Wa,-C to suppress
+ warnings about symbols being the same as registers.
+
+Fri Apr 2 13:13:51 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * lib/target.exp (prune_warnings): Ignore cc1, cc1plus warnings when
+ called with -g and -mabi=32.
+
+1999-03-28 Angela Marie Thomas <angela@cygnus.com>
+
+ * baseboards/x86-cygmon.exp: New file.
+
+1999-03-19 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * lib/libgloss.exp (get_multilibs): Handle MULTILIB_MATCHES.
+
+1999-03-18 James Ingham <jingham@cygnus.com>
+
+ * baseboards/strongarm-cygmon.exp: Add a baseboard for the
+ strongARM boards.
+
+Fri Mar 12 14:01:31 1999 Jim Wilson <wilson@cygnus.com>
+
+ * baseboards/d10v-sim.exp, baseboards/d10v.exp (ldflags): Add
+ libgloss_link_flags.
+ * lib/libgloss.exp (libgloss_link_flags): Map d10v to libnosys.
+
+1999-03-12 Nick Clifton <nickc@cygnus.com>
+
+ * baseboards/arm-sim.exp: Set timeout to 800.
+
+1999-03-01 Jim Wilson <wilson@cygnus.com>
+
+ * baseboards/cf.exp: New file for coldfire.
+ * config/cfdbug.exp: Likewise.
+ * config/base68k.exp (base68k_ld): Don't call remote_binary if
+ no_binary_mode set. Send return and wait for prompt before sending
+ download command.
+
+Sun Feb 28 23:26:36 1999 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: AC_EXEEXT, not AM_EXEEXT. Require Autoconf 2.13.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+1999-02-25 Felix Lee <flee@cygnus.com>
+
+ * config/dos.exp (dos_send): rewrite. add short delay.
+
+1999-02-18 Nick Clifton <nickc@cygnus.com>
+
+ * baseboards/arm-sim.exp: Disable uses_underscores for COFF
+ targets as the linker now works correctly.
+
+1999-02-11 Nick Clifton <nickc@cygnus.com>
+
+ * lib/remote.exp (proc remote_exec): Display timeout in log
+ message.
+
+ * lib/target.exp (proc default_target_compile): Add support for
+ timeout option.
+
+ * baseboards/arm-sim.exp: Set gcc,timeout to 500.
+
+1999-02-10 Nick Clifton <nickc@cygnus.com>
+
+ * config/dos.exp: Fix typo: need_status_wrapper ->
+ needs_status_wrapper.
+
+1999-02-09 Nick Clifton <nickc@cygnus.com>
+
+ * baseboards/arm-sim.exp: Enable uses_underscores for the COFF
+ based targets.
+
+1999-02-06 Felix Lee <flee@cygnus.com>
+
+ * runtest.exp: Don't trap SEGV.
+
+Fri Feb 5 15:43:59 1999 Jeffrey A Law (law@cygnus.com)
+
+ * lib/target.exp (prune_warnings): Prune +vcompatwarnings output
+ from the HP linker.
+
+1999-02-02 Felix Lee <flee@cygnus.com>
+
+ * lib/libgloss.exp (find_nm): new function.
+
+1999-01-31 Felix Lee <flee@cygnus.com>
+
+ * Makefile.am: Add cygnus option. Add doc to SUBDIRS
+ * doc/Makefile.am: Add cygnus option. Add info_TEXINFOS.
+ * Makefile.in, */Makefile.in: Regenerated.
+
+1999-01-29 Felix Lee <flee@cygnus.com>
+
+ * baseboards/fr30-cygmon.exp: New file.
+
+ * config/gdb_stub.exp (gdb_stub_load): Fix another typo.
+
+Fri Jan 29 17:16:25 1999 Edith Epstein <eepstein@sophia.cygnus.com>
+
+ * lib/remote.exp: Added check for value of $outp.
+
+ * lib/target.exp: Ignore some hppa specific warning messages. Added
+ checks for CC_FOR_TARGET and CXX_FOR_TARGET. Check for redirection
+ and optimization flags.
+
+1999-01-26 Frank Ch. Eigler <fche@cygnus.com>
+
+ * configure.in: Define BOARDS/CONFIG for automake.
+ * baseboards/Makefile.am: Use $(boards) for public files.
+ * config/Makefile.am: Use $(config) for public files.
+
+ * configure: Regenerated.
+ * Makefile.in: Regenerated.
+ * doc/Makefile.in: Regenerated.
+ * baseboards/Makefile.in: Regenerated.
+ * config/Makefile.in: Regenerated.
+ * example/Makefile.in: Regenerated.
+ * lib/Makefile.in: Regenerated.
+
+ * testsuite/aclocal.m4: Deleted obsolete file.
+ * testsuite/configure.in: Deleted obsolete file.
+
+Sun Jan 17 17:11:52 1999 Jeffrey A Law (law@cygnus.com)
+
+ * lib/target.exp (prune_warnings): Ignore osf4 NFS messages.
+
+Fri Jan 15 14:19:31 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * lib/libgloss.exp (get_multilibs): Multilib directories can
+ contain '=', too.
+
+Thu Jan 14 00:10:25 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * lib/target.exp (prune_warnings): Ignore -g not supported
+ warnings. Ignore o32 as warning when called with -O3 (IRIX 6).
+
+1999-01-07 Felix Lee <flee@cygnus.com>
+
+ * runtest.exp (setup_target_hook): add missing globals.
+
+1998-12-31 Felix Lee <flee@cygnus.com>
+
+ * config/dos.exp (dos_spawn): ignore optional args.
+
+ * lib/ftp.exp (ftp_upload): ftp error messages vary.
+
+1998-12-30 Rob Savoye <rob@chinadoll.welcomehome.org>
+
+ * doc/{overview,user,ref},sgml: New manual in DocBook format. This
+ includes most of the old manual, but is tottally up to date.
+ * /doc/Makefile.am, baseboards/Makefile.am, config/Makefile.am,
+ example/Makefile.am, lib/Makefile.am, Makefile.am,
+ testsuite/Makefile.am: New Makefiles for automake support.
+ * /doc/Makefile.in, baseboards/Makefile.in, config/Makefile.in,
+ example/Makefile.in, lib/Makefile.in, Makefile.in,
+ testsuite/Makefile.in: New Makefiles for autoconf as generated by
+ automake.
+ * runtest.exp: Look for config.guess in a libexec directory.
+ * config.guess: Add so it gets installed correctly.
+ * Most Files: Update copyright message, add 1998 and 1999.
+
+1998-10-19 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/rsh.exp(rsh_exec): Check the board info before blindly
+ setting RSH to remsh.
+ * lib/remote.exp(remote_reboot): Don't close the shell connection,
+ or all the remote procedures stop working.
+
+1998-12-29 Ken Raeburn <raeburn@cygnus.com>
+
+ * lib/framework.exp (istarget): Do string compare on first
+ argument, not tcl list containing first argument, against actual
+ target name.
+
+1998-12-29 Felix Lee <flee@cygnus.com>
+
+ * runtest.exp: option --a=b=c wasn't handled right.
+
+ * lib/ftp.exp (ftp_download): ftp error messages vary.
+
+Fri Dec 18 21:48:25 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb-comm.exp(quit_gdb): Don't close connection to the
+ host if it's remote.
+ (gdb_comm_go_idle): The "No exec file" prompt has mysteriously
+ changed; detect either.
+
+1998-12-11 Felix Lee <flee@cygnus.com>
+
+ * contrib/test-tool: diagnostic if no test summary,
+ and add summary headers, in case of multiple test runs.
+
+ * contrib/test-tool: don't print location of log file if it's not
+ really there.
+
+1998-12-10 Felix Lee <flee@cygnus.com>
+
+ * lib/remote.exp (remote_download): in the non-remote case, try to
+ make the copy writable as well as readable.
+
+1998-12-09 Felix Lee <flee@cygnus.com>
+
+ * contrib/test-tool: spit out test summary first.
+
+1998-12-07 James E Wilson <wilson@wilson-pc.cygnus.com>
+
+ * baseboards/i960-sim.exp: New file.
+
+Thu Dec 3 14:03:27 1998 Dave Brolley <brolley@cygnus.com>
+
+ * baseboards/fr30-elf.exp: New file.
+ * baseboards/fr30-sim.exp: New file.
+
+1998-11-30 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * lib/libgloss.exp (get_multilibs): Multilib options can contain '='.
+
+1998-11-27 Felix Lee <flee@cygnus.com>
+
+ * config/gdb-comm.exp (gdb_comm_reload): give up after N reboot
+ failures.
+
+Mon Nov 23 10:19:06 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lib/target.exp (prune_warnings): Kill NFS server not responding
+ warnings too.
+
+1998-11-18 Jim Wilson <wilson@cygnus.com>
+
+ * baseboards/tx39-dve.exp: Add cygmon support.
+
+1998-11-05 Jim Wilson <wilson@cygnus.com>
+
+ * baseboards/vx960.exp (cflags): Set to -mca if cpu is I960CA.
+ * config/vxworks.exp (vxworks_unld): Don't run unld if os is
+ vxworks5.0.
+ (vxworks_load): Sed out carriage returns.
+
+Thu Oct 15 16:33:01 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * lib/remote.exp (remote_spawn): Properly pass trailing args
+ to call_remote.
+
+Tue Oct 13 21:04:04 1998 Felix Lee <flee@cygnus.com>
+
+ * config/vxworks.exp: grok preload_obj_flags. recognize
+ "Operation Fault" messages from the board. increase reboot_delay
+ so we don't interrupt the countdown-to-autoboot
+ * i960glue.c: add missing file.
+
+Mon Oct 12 20:08:06 1998 Mark Alexander <marka@cygnus.com>
+
+ * baseboards/danlite-elf.exp: New file.
+
+1998-10-11 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/powerpc{,le}-sim.exp (needs_status_wrapper): Don't
+ set, normal exit returns the appropriate status.
+
+Thu Oct 8 13:49:04 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * lib/standard.exp (${tool}_load): Clear up argument order.
+
+ * config/sim.exp: Fix typo in inpfile computation.
+
+ * lib/remote.exp (remote_spawn): Pass $args to call_remote.
+
+Fri Oct 2 00:02:51 1998 Tom Tromey <tromey@cygnus.com>
+
+ * config/unix.exp (unix_load): Pass `--' to verbose when
+ displaying program output.
+ * lib/remote.exp (standard_load): Pass `--' to verbose when
+ displaying program output.
+
+1998-09-29 Felix Lee <flee@cygnus.com>
+
+ * config/gdb_stub.exp: watch for the exitcodes generated by the
+ testglue wrapper. workaround for failing to hit _exit breakpoint.
+
+1998-09-18 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * testsuite/runtest.all/options.exp: Also pass --srcdir to the
+ child runtest being tested, so it doesn't try to execute the
+ config files.
+
+Thu Sep 17 18:03:16 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * runtest.exp: Allow // at beginning of path spec since
+ this is a valid Windows (Posix?) construction.
+
+Tue Sep 15 17:06:17 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/gdb-comm.exp: Catch RDI_open failure.
+
+Mon Sep 14 20:00:57 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * baseboards/m68k-emc.exp: New file.
+ * config/m68k-emc.exp: New file.
+
+1998-09-12 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/powerpc{,le}-sim.exp: Call process_multilib_options
+ so multilib tests can be run.
+
+Fri Sep 4 09:26:47 1998 Nick Clifton <nickc@cygnus.com>
+
+ * lib/utils.exp (proc prune): Initialise $tmp to an empty list.
+
+Mon Aug 31 13:43:47 1998 Tom Tromey <tromey@cygnus.com>
+
+ * lib/libgloss.exp (find_gcj): Renamed from find_gjavac; compiler
+ now named `gcj'.
+
+Tue Aug 25 13:31:18 1998 Anthony Green <green@cygnus.com>
+
+ * lib/libgloss.exp (find_gjavac): New function.
+
+1998-08-25 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/framework.exp(check_conditional_xfail): Add spaces to the
+ search pattern, so it doesn't match just part of an option.
+
+1998-08-24 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * runtest: Update copyright date.
+ * runtest.exp: Add compiler_flags as a new global variable.
+ * lib/framework.exp: Add new proc, check_conditional_xfail. This
+ is like xfail, only it looks in all the compiler options for
+ options to determine the actual test result state.
+ (pass,fail): If there is a conditional xfail setup, check the
+ condition to determine the actual test result state.
+ * lib/target.exp(default_target_compile): Set the global
+ compiler_opts to the compiler flags used to invoke the compiler.
+
+Sat Aug 1 08:02:15 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/mn10200-eval.exp: New file.
+ * baseboards/mn10200-cygmon.exp: New file.
+
+Wed Jul 8 11:41:21 1998 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/mn10200-sim.exp: Update for recent mn10200 newlib/libgloss
+ changes.
+
+Fri Jun 5 11:29:26 1998 Felix Lee <flee@cygnus.com>
+
+ * config/gdb_stub.exp (gdb_stub_load): fix typo
+
+Thu Jun 4 14:16:32 1998 Felix Lee <flee@zog.cygnus.com>
+
+ * config/gdb_stub.exp (gdb_stub_wait): watch for "Program exited",
+ which may happen on segv or similar.
+ (gdb_stub_start,gdb_stub_wait): need to save exit_brnum and
+ abort_brnum.
+ (gdb_stub_ld): delete old breakpoints when loading a new program.
+ (gdb_stub_spawn): return the right result.
+
+ * baseboards/d10v-sim.exp: add process_multilib_options.
+
+Tue Jun 2 01:51:47 1998 Mark Alexander <marka@cygnus.com>
+
+ * baseboards/sparclite-sim-le.exp: New file.
+
+Mon Jun 1 00:15:34 1998 Angela Marie Thomas (angela@cygnus.com)
+
+ * config/sim.exp (spawn_sim): Pass sim,options to the standalone
+ simulator if set.
+ * baseboards/sparclite-sim.exp: Set sim,options and
+ gdb,target_sim_options.
+
+Mon Jun 1 01:40:26 1998 Felix Lee <flee@zog.cygnus.com>
+
+ * runtest.exp(iterate_target_variants_two): concat multiple globs
+ correctly.
+
+Tue May 26 17:56:57 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/dos.exp(dos_send): Handle text without newlines
+ properly.
+
+Sun May 17 17:08:46 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/sh-hms-sim.exp: Need to pass "18" to the target sim
+ command in GDB.
+
+ * baseboards/sparclite-sim.exp: Need to pass "-sparclite" to the
+ target sim command in GDB.
+
+Thu May 14 12:03:36 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_exec): Add optional timeout
+ parameter. Move local execution code to...
+ (local_exec): New procedure.
+
+Wed May 13 18:41:23 1998 John Metzler <jmetzler@cygnus.com>
+
+ * runtest.exp (main) : Add printout of schedule of variations
+
+Fri May 8 14:36:49 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * baseboards/basic-sim.exp (find_sim): Check $SIM first.
+ (setup_sim): Rename arg `name' to `subdir_name'. Print message
+ of simulator found.
+
+Tue Apr 28 14:12:01 1998 Mark Alexander <marka@cygnus.com>
+
+ * lib/libgloss.exp (libgloss_link_flags): Recognize sparc86x target.
+
+Sun Apr 19 09:29:44 1998 Mark Alexander <marka@cygnus.com>
+
+ * baseboards/sparclite-sim.exp: New file.
+
+Tue Apr 14 09:55:37 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/telnet.exp: Look for "VxWorks Boot"; be a bit more picky about
+ looking for "account name" prompt.
+
+Mon Apr 6 13:14:52 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/ddb-ether.exp(remote_wait): If we see "Exception Cause"
+ from the board, reboot it.
+
+Thu Apr 2 18:22:33 1998 Jim Wilson <wilson@cygnus.com>
+
+ * lib/target.exp (prune_warning): Extend regexp for Irix6 warnings
+ to handle all 3 linker names.
+
+Thu Apr 2 15:39:38 1998 Felix Lee <flee@zog.cygnus.com>
+
+ * config/sim.exp(sim_spawn): code for remote host was wrong.
+
+Tue Mar 31 00:31:53 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/dos.exp: Disable GDB interrupt tests if we're testing
+ on a DOS host.
+
+Mon Mar 30 23:44:19 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/dos.exp(dos_send): Don't send string if we've already
+ sent it once.
+
+Thu Mar 26 11:34:18 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_exec): Need to look at the result from
+ wait if we used spawn.
+
+Wed Mar 25 22:20:25 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_exec): More attempts at working around
+ tcl/expect's inadequacies in dealing with processes.
+
+1998-03-25 Brendan Kehoe <brendan@cygnus.com>
+
+ * contrib/test-g++: Only do the libg++ tests if the directory exists.
+
+Wed Mar 25 12:24:25 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/basic-sim.exp(find_sim): Search for the sim rather than
+ assuming tool_root_dir points to the right place.
+
+Tue Mar 24 16:07:51 1998 Stu Grossman <grossman@bhuna.cygnus.co.uk>
+
+ * configure doc/configure example/configure example/calc/configure
+ testsuite/configure: Regenerate with autoconf 2.12.1 to fix shell
+ issues for NT native builds.
+
+Sun Mar 15 23:25:06 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/target.exp(default_target_compile): If the compiler produced
+ no output and the compiler execution failed, return a string
+ signifying this. (This is the wrong fix, but...)
+
+ * lib/remote.exp(remote_exec): Don't append arbitary strings to
+ the output from the program; callers must check the exit status.
+ Also, when killing a runaway process, try sending a SIGINT before
+ sending a SIGTERM (may help to terminate gcc properly).
+
+Mon Mar 9 01:54:39 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_exec): Use spawn directly, rather than
+ trying to potentially manage multiple spawn processes on the same
+ host.
+
+Sun Mar 8 21:40:40 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_exec): Use remote_spawn and remote_wait
+ if the machine is local.
+
+Fri Mar 6 23:28:59 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/sparclite-cygmon.exp: New file.
+
+Wed Mar 4 18:05:46 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/basic-sim.exp(find_sim): Don't search tool_root_dir
+ because it's always the root of the tree.
+ (setup_sim): Don't pass tool_root_dir to find_sim.
+
+Tue Mar 3 00:08:53 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/unix.exp: Tell the benchmark code to use alarms.
+ * baseboards/basic-sim.exp(find_sim): Use tool_root_dir.
+ * baseboards/i960-cyclone.exp: Ditto.
+ * baseboards/op50n.exp: Ditto.
+ * baseboards/rom68k-idp.exp: Ditto.
+ * baseboards/sparclet-aout.exp: Ditto.
+
+Mon Mar 2 21:54:30 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/utils.exp(runtest_file_p): Be a bit more lenient about
+ what files we match.
+
+ * lib/telnet.exp: Clean up regexps.
+
+ * lib/target.exp(default_target_compile): Use tool_root_dir.
+ (target_link, default_link): New functions.
+
+ * lib/remote.exp: Wrap close statements with catch.
+
+ * lib/framework.exp(cleanup): Remove unused global declaration.
+
+ * config/unix.exp(unix_load): Unset LD_LIBRARY_PATH and
+ SHLIB_PATH after loading.
+
+ * config/sim.exp(sim_spawn, sim_wait): New functions.
+
+ * config/i960.exp(i960_spawn, i960_wait): New functions.
+ (i960_load): Use spawn and wait.
+
+ * config/gdb-comm.exp: Use tool_root_dir instead of objdir.
+ * config/ddb.exp: Ditto.
+
+ * config/gdb_stub.exp: Use tool_root_dir.
+ (gdb_stub_spawn, gdb_stub_wait): New functions.
+ (gdb_stub_load): Use spawn and wait.
+
+ * config/dos.exp(dos_send): Send strings one line at a time.
+ (dos_file): Delete files using del instead of rm.
+
+ * config/ddb-ether.exp(ddb_ether_spawn, ddb_ether_wait): New functions.
+
+ * config/cygmon.exp: Set send_initial_cr.
+
+ * runtest.exp: Must process tool_root_dir option in multiple
+ places (should be fixed!)
+
+Mon Feb 23 09:08:43 1998 Mark Alexander <marka@cygnus.com>
+
+ * baseboards/mn10300-sim.exp: Use libgloss when compiling/linking,
+ and new linker script sim.ld when linking.
+ * baseboards/mn10300-cygmon.exp: New file for MN10300 Cygmon.
+ * config/mn10300-eval.exp: New file for MN10300 eval board.
+
+Thu Feb 19 18:23:17 1998 John Metzler <jmetzler@cygnus.com>
+
+ * baseboards/mips64vr4100-sim.exp
+ Defines simulated test target for mips46vr4100-*-elf
+
+Wed Feb 18 15:29:12 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp: Use tool_root_dir instead of base_dir or
+ objdir when searching for uninstalled libraries or executables.
+
+ * runtest.exp(tool_root_dir): New variable.
+
+Sat Feb 14 15:06:25 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vxworks.exp(${board}_init): If we don't get useful info
+ from the 'p' command in the VxWorks boot ROM, reboot the board.
+ (vxworks_exec): Check more closely for problems executing the
+ testcase.
+
+Mon Feb 9 16:48:55 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(get_multilibs): If the compiler doesn't exist,
+ return nothing.
+ (find_ld): New function.
+
+ * config/powerpc-bug.exp: New file.
+
+ * baseboards/powerpc-bug.exp: Load the generic powerpc-bug
+ configuration.
+
+Mon Feb 2 15:44:10 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * contrib/test-tool (patterns): Glob pattern to match log files.
+ Add appropriate glob for new logfile naming scheme.
+
+Sun Feb 1 14:29:16 1998 Joseph H. Buehler <jhpb@sarto.gaithersburg.md.us>
+
+ * runtest: Handle finding runtest.exp better automounted
+ environments.
+
+Mon Jan 19 10:37:13 1998 Mark Alexander <marka@cygnus.com>
+
+ * config/dve.exp: New file to support Densan boards.
+ * baseboards/tx39-sim.exp: New file to support TX39 simulator.
+ * baseboards/tx39-dve.exp: New file to support Densan TX39 board.
+
+Tue Jan 13 01:21:14 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * lib/libgloss.exp: Handle setting of LD_LIBRARY_PATH/SHLIB_PATH
+ when testing with installed libraries.
+
+1998-01-12 Brendan Kehoe <brendan@cygnus.com>
+
+ * contrib/test-tool (todayname): Refer to and use ChangeLog.egcs
+ instead of ChangeLog.fsf.
+
+Mon Jan 5 17:25:25 1998 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d30v-sim.exp ({c,ld}flags): Set libgloss flags in
+ addition to newlib flags.
+
+Sun Dec 28 11:06:49 1997 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in: Change "gxx_includedir" to "gxx_include_dir".
+
+Tue Dec 23 14:46:44 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb-comm.exp(gdb_comm_load): Use "signal 0" instead of
+ continue. Check for testcase_timeout board feature to determine
+ how long we wait before we decide the testcase has gone into
+ an infinite loop.
+
+ * baseboards/cygmon.exp: Set shell_prompt and send_initial_cr.
+
+ * lib/libgloss.exp(libgloss_link_flags): Add case for sparc64.
+
+ * baseboards/usparc-cygmon.exp: New file.
+
+Sat Dec 13 18:43:16 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d30v-sim.exp (ldflags): Fix typo.
+
+Thu Dec 11 20:23:28 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/unix.exp (unix_load): Set LD_LIBRARY_PATH and SHLIB_PATH
+ for native tests if ld_library_path is defined.
+ * lib/libgloss.exp (g++_link_flags): Build up ld_library_path.
+ (libstdc++_link_flags): Likewise.
+
+Thu Dec 11 12:35:12 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d30v-sim.exp (ldflags): Also set stack to end of
+ default 8 meg external area.
+
+Wed Dec 10 16:11:47 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb-comm.exp(gdb_comm_load): Add more possible error
+ messages.
+
+ * lib/remote.exp(standard_close): Make sure we close both file
+ descriptors, if there are two.
+
+Wed Dec 10 14:35:05 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d30v-sim.exp (ldflags): Add -mextmem to allow testing
+ larger tests.
+
+Tue Dec 9 21:38:03 1997 Fred Fish <fnf@cygnus.com>
+
+ * lib/libgloss.exp (get_multilibs): Use previously set value
+ of "target_board" rather than "board", since it may not exist.
+
+Tue Dec 9 10:54:34 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(standard_wait): We have to call wait, even though
+ it can't possibly work.
+
+Mon Dec 8 11:55:33 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_spawn): Use -leaveopen.
+ (standard_wait): If we used -leaveopen, call close ourselves.
+ (standard_close): Ditto.
+
+ * lib/libgloss.exp(get_multilibs): Remove bogus tests for board
+ variable. Only set the board's multitop variable if we didn't
+ get an explicit list of multilib options to use.
+
+Sun Dec 7 08:29:40 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_spawn): Fix typo.
+ (standard_wait): If the process was created with a pipeline, we
+ have to use close instead of wait.
+
+Fri Dec 5 14:21:18 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_spawn): If the "spawn -open" command
+ fails, clean up after the command we just spawned.
+
+Thu Dec 4 11:32:06 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_open): Use catch.
+
+Tue Dec 2 22:44:42 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_close): Move close statement after we
+ determine the PID. Look at fileid_pid feature.
+ (remote_spawn): If we're invoking a pipeline, stash the PID we
+ get in the board's fileid_pid feature.
+
+Sun Nov 30 19:09:49 1997 Jeffrey A Law (law@cygnus.com)
+
+ * lib/target.exp (prune_warning): Prune some unwanted warnings
+ from the HP assembler and gcc when using the HP assembler.
+
+Fri Nov 28 10:42:30 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d30v-sim.exp: Re-enable trampolines.
+
+Tue Nov 25 09:24:13 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d30v-sim.exp: Re-enable using label values.
+
+Mon Nov 24 09:56:20 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/cygmon.exp, baseboards/cygmon.exp,
+ baseboards/msparc-cygmon.exp: New files.
+
+ * config/i960.exp: Don't call perror.
+
+Sun Nov 16 20:55:59 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d30v-sim.exp: Turn off trampolines and label values
+ temporarily.
+
+Thu Nov 13 22:51:42 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d30v-sim.exp: New file for d30v support.
+
+Wed Nov 12 23:45:48 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/unix.exp(unix_load): Call remote_spawn and remote_wait
+ instead of using exec.
+
+ * lib/remote.exp(remote_wait): Use $dest, not host.
+
+Tue Nov 4 17:39:58 1997 Jim Wilson <wilson@cygnus.com>
+
+ * lib/target.exp (default_target_compile): Put math library
+ before linker script.
+
+Sun Oct 26 20:00:34 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/base68k.exp(base68k_wait): New procedure.
+ (base68k_load): Use remote_spawn and remote_wait.
+
+Sat Oct 25 21:48:36 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/base68k.exp(base68k_spawn): New procedure.
+
+Fri Oct 24 10:55:17 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb-comm.exp: Add missing -re. If we get an EXIT message
+ from the remote system, we know that we've exited gdb.
+
+ * lib/remote.exp(standard_wait): Keep the timer running even if we
+ get output from the remote program.
+
+ * config/dos.exp(dos_wait): Ditto.
+
+Fri Oct 17 22:20:35 1997 Jeffrey A Law (law@cygnus.com)
+
+ * lib/libgloss.exp (find_g77): No longer need --driver stuff.
+
+Wed Oct 15 21:13:39 1997 Philippe De Muyter <phdm@macqel.be>
+
+ * runtest (mypath): Scan $PATH to set mypath if $0 does not give it.
+
+Mon Oct 13 11:09:09 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/base68k.exp(base68k_load): Don't call exp_continue
+ outside of an expect statement.
+
+Sun Oct 12 21:29:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Replace datadir with dejadatadir throughout.
+
+Mon Oct 6 10:52:25 1997 Jeffrey A Law (law@cygnus.com)
+
+ * lib/libgloss.exp (find_g77): New function.
+
+Fri Oct 3 14:13:30 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/vr4100-ddb.exp: Fix start addresses.
+
+ * config/vxworks.exp: Remove 'set timeout' statements.
+
+ * runtest.exp: Always output board name of target.
+
+Tue Sep 30 15:35:03 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/arm-sim.exp: No longer uses underscores.
+ * baseboards/arm-ice.exp: Ditto.
+
+Tue Sep 30 12:47:19 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/remote.exp (standard_file, cmp): Ensure file exists before
+ computing file size.
+
+Sun Sep 28 14:30:52 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/powerpc-sim.exp: The simulator directory is
+ named "ppc", not "powerpc".
+
+ * config/mips-idt.exp: Set the "syn-garbage-limit" gdb
+ value to 0.
+
+Sat Sep 27 22:11:45 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(get_multilibs): Return the multilib directory
+ that matches closest to the specified set of options.
+
+Fri Sep 26 10:20:56 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(find_binutils_prog): Changed from find_objdump.
+
+ * lib/remote.exp(remote_load): Use objcopy instead of objdump.
+
+Thu Sep 25 10:54:55 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/h8300.exp: Use global prefix_dir instead of
+ explicitly putting a pathname in the file.
+ * baseboards/i386-bozo.exp: Ditto.
+ * baseboards/i960-cyclone.exp: Ditto.
+
+Wed Sep 24 13:06:47 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/ddb.exp: Close the connection to the board after we've
+ initialized it.
+
+ * testglue.c: Add support for atexit() and _exit() if VXWORKS
+ is defined.
+
+ * lib/libgloss.exp(build_wrapper): Define VXWORKS if is_vxworks
+ target feature is set.
+
+ * config/vxworks.exp: Set is_vxworks and gdb,nosignals target
+ features.
+
+Tue Sep 23 17:56:43 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_load): If is_simulator board feature is
+ set, don't try to cache executables for this target.
+
+ * baseboards/basic-sim.exp: Set is_simulator board feature.
+
+Thu Sep 18 20:31:57 1997 Jeffrey A Law (law@cygnus.com)
+
+ * lib/libgloss.exp (libio_include_flags): If we can't find
+ _G_config.h, look for iostream.list in the same directory.
+
+1997-09-18 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * contrib/test-tool: Put all of the failure stuff up above the
+ pass stuff.
+
+Tue Sep 16 22:15:20 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_load): Skip all the caching code if the
+ REMOTELOAD_CACHE env variable isn't set. Use objdump to get only
+ the executable contents, so we avoid problems with timestamps in
+ the executable.
+ (remote_expect): Check remote_suppress_flag instead of
+ suppress_flag.
+
+ * config/tic80.exp: Set gdb,use_breakpoint_for_stub. Don't
+ bother skipping the float tests, as the gdb stub now traps
+ FPU errors.
+ * config/dos.exp: If there is a timeout, try to interrupt
+ the remote job.
+ (dos_interrupt_job): Return a null string on success.
+ (dos_copy_download): Make the files on the destination world-writable
+ as well.
+ (dos_copy_upload): Ditto.
+
+Fri Sep 12 11:10:42 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * testsuite/runtest.all/options.exp: Commented out failing strace
+ test--test is probably failing because of a TCL8 interaction.
+
+Thu Sep 11 18:13:11 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/tic80-board.exp: Added support for running gdb.
+
+ * config/dos.exp(dos_exec): Add support for an output file.
+
+ * lib/remote.exp(remote_load): Only cache executables that
+ pass. Allow use of a checksum program in place of caching the
+ entire executable.
+
+ * lib/libgloss.exp(find_objdump): New procedure.
+
+ * config/gdb_stub.exp: Don't loop forever in gdb_stub_ld.
+ (gdb_stub_retry_ld): New procedure.
+
+Wed Sep 10 12:58:11 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/tic80.exp: Add new procedure tic80_ld. Call
+ tic80_ld from tic80_load. Add settings for gdb testing.
+
+ * lib/remote.exp: Add missing quotes around eval arguments.
+
+Tue Sep 9 14:45:24 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/tic80.exp: Remove bogus call to "fix" program.
+ Add timeout to remote_wait.
+
+Tue Sep 9 11:40:01 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/arc.exp: New file.
+ * baseboards/arc-sim.exp: New file.
+
+Fri Sep 5 15:17:38 1997 Jeffrey A Law (law@cygnus.com)
+
+ * lib/libgloss.exp (get_multilibs): Search for "libraries" directory
+ as the toplevel multilib directory too.
+ (libstdc++_link_flags, libstdc++_include_flags): New functions.
+
+Wed Sep 3 16:55:52 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(standard_file): cmp now returns 0 on "files
+ identical", some other value if the files are different.
+
+ * baseboards/sh-hms-sim.exp: Need to pass -mieee when building
+ testcases that rely on IEEE-compliant behavior.
+ * baseboards/sh-hms.exp: Ditto.
+
+ * lib/remote.exp(remote_load): Remove spurious debug output.
+ Use "remote_file cmp" instead of invoking cmp directly.
+ (standard_file): Added cmp operation to compare two binary
+ files.
+
+ * lib/libgloss.exp: Add dwarf2 target variant.
+
+ * lib/target.exp: Make sure the CC_FOR_TARGET variable overrides
+ any default compiler.
+
+Tue Sep 2 18:28:53 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb_stub.exp: Detect gratuitous change to sparclet
+ gdb target mode.
+
+ * lib/remote.exp(remote_expect): Added timeout setting.
+
+Tue Sep 2 16:39:21 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * dg.exp (dg-test): New arg -keep-output.
+
+Wed Aug 27 13:16:32 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vxworks.exp: Set the gdb_prompt target feature to be
+ (vxgdb).
+
+Fri Aug 22 13:24:58 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vxworks.exp: Check for negative values from the "value ="
+ return string. If preload_obj is a target feature, load the
+ specified object file after a reboot.
+
+Thu Aug 21 18:06:20 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/vx4300.exp: New file.
+
+Wed Aug 13 12:57:53 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lib/target.exp (prune_warnings): Generalize alpha ld warning.
+ Also handle IRIX 6 linker "I give up" message.
+
+Tue Aug 12 21:44:58 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/framework.exp(clone_output): Don't use lindex on things that
+ aren't really lists.
+
+Mon Aug 11 20:51:08 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_expect): Nasty ugliness to work around
+ change in behavior of lrange in tcl8.
+
+Sat Aug 9 00:59:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/netware.exp (${board}_init): Change ld.new to ld-new.
+
+Wed Aug 6 18:41:24 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lib/libgloss.exp (libio_include_flags): Look for _G_config.h, not
+ libio.a.
+
+Wed Aug 6 00:41:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/libgloss.exp (find_gas): Look for as-new, not as.new.
+
+Sat Aug 2 20:44:55 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb-comm.exp: Look for "Program exited with" exit status,
+ even though this should *never* appear (we're setting a breakpoint
+ in _exit and abort, duh).
+
+Fri Aug 1 15:56:06 1997 Felix Lee <flee@yin.cygnus.com>
+
+ * runtest.exp: "runtest gcc.c-torture/execute/execute.exp" didn't
+ work because expected global vars weren't set.
+
+Wed Jul 30 09:05:41 1997 Felix Lee <flee@yin.cygnus.com>
+
+ * lib/ftp.exp (ftp_download): and needed an -re flag. and changed
+ "Timeout" to "421", to catch other premature disconnects.
+
+Wed Jul 30 00:15:04 1997 Felix Lee <flee@cygnus.com>
+
+ * lib/ftp.exp (ftp_download): "Timeout ..." pattern wasn't listed
+ early enough to ever get matched.
+
+Mon Jul 28 21:20:59 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(get_multilibs): Iterate through the list of
+ compiler-specified options looking for a match, rather than
+ farting around with regexps.
+
+Mon Jul 28 15:28:09 1997 Felix Lee <flee@cygnus.com>
+
+ * lib/ftp.exp (ftp_upload): return localfilename, not
+ remotefilename.
+
+Mon Jul 28 15:28:09 1997 Felix Lee <flee@cygnus.com>
+
+ * config/base68k.exp (base68k_ld): need global objdir.
+
+Tue Jul 22 10:24:54 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * runtest.exp: More cleanups for setting isremote board feature.
+ Leave the previous setting alone if the board already has one.
+
+ * lib/framework.exp(is_remote): Add debugging info.
+
+ * lib/remote.exp(remote_spawn): If the local spawn fails, return
+ -1 instead of falling through.
+
+Mon Jul 21 14:30:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/target.exp(list_targets): Deleted, no longer meaningful.
+ (default_target_compile): Use warning instead of perror when
+ download fails. Delete an existing a.out object file if we're
+ running on a remote host.
+
+ * lib/libgloss.exp(libgloss_ld): Deleted, not used.
+
+ * config/dos.exp(dos_copy_download): If the local file doesn't
+ exist, don't try to download it.
+
+ * runtest.exp: Change tests for setting isremote board feature.
+ We assume the board is remote unless the name is the same as
+ the local hostname or we're defining the build board.
+
+Wed Jul 16 12:45:30 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/dos.exp(dos_copy_upload): If the remote file doesn't
+ exist, don't try to upload it.
+
+ * baseboards/basic-sim.exp: Don't transform the simulator name
+ using the target alias if no_transform_name is set on the host.
+
+ * lib/kermit.exp: Don't try to unset the file descriptor if it
+ isn't set.
+
+Mon Jul 7 12:01:54 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/m32r-sim.exp(ldflags): Use libgloss_link_flags, not
+ libgloss_include_flags.
+ * baseboards/m32r-elf.exp: Ditto.
+
+Sat Jul 5 18:42:52 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(libgloss_link_flags): Add sparclet->sparc CPU
+ mapping. (This needs to be fixed.)
+
+Thu Jul 3 15:34:21 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/ddb.exp: Use base68k instead of gdb-comm.
+
+ * stub-loader.c: Renamed from sparclet-loader.c.
+ * config/gdb_stub.exp: Refer to stub-loader.c now.
+
+Tue Jul 1 17:48:43 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * runtest.exp: Allow boards_dir to be a list of directories to
+ search for board descriptions.
+
+Mon Jun 30 19:12:14 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * baseboards/arm-ice.exp: Board doesn't do I/O, signals,
+ or call functions from GDB.
+
+Mon Jun 30 18:32:44 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/arm-ice.exp: New file.
+ * baseboards/arm-ice.exp: New file.
+
+Sun Jun 29 22:12:51 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/arm-sim.exp: New file.
+
+ * lib/libgloss.exp(process_multilib_options): Added pe object format.
+
+ * baseboards/armpe-sim.exp: Removed file.
+
+Sat Jun 28 13:37:27 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb_stub.exp: Use gdb_opts feature instead of a random
+ check if the host is remote.
+
+ * runtest.exp: Use the no_transform_name feature instead of
+ looking for a specific host triplet.
+
+ * baseboards/*-sim.exp: Use load_base_board_description, not
+ load_board_description.
+
+ * lib/target.exp(default_target_compile): If we're compiling
+ with the C++ compiler, include g++_include_flags and
+ g++_link_flags as appropriate.
+
+Fri Jun 27 15:17:12 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ (load_board_description): Set the board feature isremote if the
+ board appears to be remote.
+ Call setup_build_hook with the local hostname.
+
+ * lib/target.exp(push_build): New procedure.
+
+ * lib/framework.exp(is_remote): Detect if the board name specified
+ is the name of the build or host, and handle appropriately.
+
+ * lib/remote.exp(check_for_board_status): Be a bit more aggressive
+ about stripping trailing CRLFs.
+
+ * config/dos.exp(dos_exec): Add support for an input file.
+ (dos_load): Pass program arguments and input file to remote_exec.
+
+Wed Jun 25 20:01:37 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/target.exp(target_compile): Always add the target's cflags
+ spec. Use find_g++ to find a compiler if we've been asked to use a
+ C++ compiler.
+
+ * lib/remote.exp(remote_spawn): Wrap open and spawn
+ statements with catch.
+
+ * lib/libgloss.exp(g++_link_flags): Add -L options to point to the
+ correct libiberty and librx directories.
+ (find_g++): New routine.
+
+ * lib/kermit.exp: Loosen up the regexp matching the connect
+ string.
+
+ * lib/ftp.exp: Look for a "Timeout after..." message from
+ ftp.
+
+ * config/sparclet.exp: The gdb prompt is "gdbslet".
+
+ * config/gdb_stub.exp: If running on a remote host, add --command
+ gdbinit to the gdb command line. Use the gdb_is_running target
+ feature to keep track of whether or not we started gdb. Replace
+ errors with warnings in many cases.
+ (gdb_stub_load): Always set a breakpoint on exit if the
+ target feature always_break_exit is set. Retry the testcase
+ if it times out.
+ (gdb_stub_close): New routine.
+
+ * baseboards/sparclet-aout.exp: varargs and label values
+ apparently don't work. Always set a breakpoint at
+ exit() even if we can break at _exit instead.
+
+ * sparclet-loader.c: Add global variable "remote_debug"
+ initialized to 0.
+
+ * runtest.exp: If running on a DOS host, don't canonicalize
+ the tool names.
+
+ * config/i386-bozo.exp(${board}_reboot): Return 1.
+
+Mon Jun 23 14:55:13 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb_stub.exp: Clean up a few regexps. Check for either
+ the breakpoint function name (preferred) or the breakpoint number.
+
+Sun Jun 22 12:31:02 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(standard_file): Add dirname, join, and absolute
+ operators.
+ (unix_clean_filename): New procedure.
+
+ * runtest.exp(lookfor_file): Call 'remote_file build dirname'
+ instead of appending "/..".
+
+ * lib/framework.exp(is_remote): Really fix the problem with
+ "unix/cpu=v8" this time. Minor cleanups.
+
+Wed Jun 18 21:21:00 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/ddb-ether.exp(ddb_ether_try): Fix typo.
+
+Tue Jun 17 16:18:00 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/base68k.exp: Wait for an entire line before appending
+ it to the result buffer.
+ (base68k_load): Check every optional argument, and don't allow
+ any (yet). Use -re in front of regular expressions.
+
+ * lib/framework.exp(is_remote): Strip off any variant info from
+ the board name before determining if the board is remote.
+
+Tue Jun 17 02:32:07 1997 Bob Manson <manson@farmer>
+
+ * config/gdb-comm.exp(gdb_comm_load): Check for parameters we don't
+ support, and return UNSUPPORTED as appropriate. Don't set a
+ breakpoint in exit if we can set one in _exit.
+ * config/gdb_stub.exp: Ditto.
+
+Mon Jun 16 16:07:32 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/dos.exp(dos_wait): Add timeout parameter.
+
+ * lib/remote.exp(remote_expect): Add timeout parameter.
+ (remote_wait): Ditto.
+ (standard_wait): Ditto. Also give up if the program outputs
+ more than 512,000 bytes.
+
+ * config/vxworks.exp: Use timeout parameter instead of setting
+ timeout variable.
+ * config/dos.exp: Ditto.
+ * config/ddb.exp: Ditto.
+ * lib/mondfe.exp: Ditto.
+ * lib/rlogin.exp: Ditto.
+ * lib/telnet.exp: Ditto.
+ * config/base68k.exp: Ditto.
+ * config/i386-bozo.exp: Ditto.
+ * config/gdb-comm.exp: Ditto.
+ * config/gdb_stub.exp: Ditto.
+ * config/i960.exp: Ditto.
+ * config/ddb-ether.exp: Ditto.
+ * config/sim.exp: Ditto.
+
+Fri Jun 13 19:54:24 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * contrib/test-tool: Default to assuming a standard tree
+ structure. Don't die if we don't have a previous file to
+ diff against--diff against /dev/null instead.
+
+ * config/m32r.exp: Misc fixes.
+
+ * config/m32r-stub.exp: New file.
+
+ * config/gdb_stub.exp: Download the loader program to the host
+ before we try to load it.
+
+ * config/dos.exp: Move the cygwin exception check to a point
+ earlier in the expect sequence.
+ (dos_copy_upload): New routine.
+
+Thu Jun 12 19:05:21 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * testglue.c (write_int): write_int takes two args.
+
+ * lib/target.exp(target_compile): Must insert spaces when
+ appending flags.
+
+ * lib/remote.exp(remote_reboot): Print a message stating that
+ the board is being rebooted.
+
+ * config/dos.exp(dos_exec): Call remote_wait instead of
+ doing it ourselves.
+ (dos_wait): Minor cleanups.
+
+Wed Jun 11 10:07:10 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/dos.exp: Look for "cygwin except" string and reboot
+ the board if we see it. Make sure we get output from the
+ right place.
+ (dos_exec): We always need to return a result list.
+
+ * lib/target.exp(target_compile): Strip extra newlines/CRs from
+ the start of the compiler output.
+
+ * config/dos.exp: Make sure we can have multiple spawned commands
+ open to the board without reusing the same batch file name. Use
+ the new conninfo board feature to hold the name of the batch file
+ being used for the current connection.
+ (dos_interrupt_job): New procedure.
+
+ * config/tic80.exp, baseboards/tic80-board.exp: New files.
+
+ * lib/remote.exp(remote_swap_conn): New procedure.
+ (remote_pop_conn,remote_push_conn): The conninfo board feature
+ is used to store data specific to the current connection; make
+ sure we update it correctly when we push and pop connections.
+
+Fri Jun 6 14:24:36 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb-comm.exp: Fix typo (missing call to list).
+
+ * lib/libgloss.exp(g++_link_flags): Put spaces in appropriate
+ places. If we don't have a multilib pathname to use, try
+ global $objdir instead.
+ (g++_include_flags): Don't bother checking to see if the libraries
+ are there, just look for the source directories.
+
+Thu Jun 5 18:09:55 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/ddb.exp: Fix typo.
+
+ * lib/remote.exp(remote_close): Use nasty ugly shell stuff to kill
+ the program being closed.
+ (remote_expect): Make sure expect fails if there isn't a
+ connection open to the requested board.
+
+ * lib/libgloss.exp(winsup_include_flags,winsup_link_flags): New
+ functions.
+
+ * baseboards/dos.exp: Fix link flags and prompt regexp.
+
+ * config/dos.exp(dos_load): New function.
+
+Tue Jun 3 12:04:15 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/unix.exp: Add call to process_multilib_options.
+
+ * runtest.exp: Clean up target iteration expansion.
+
+ * testglue.c: Add #ifndef NO_UNISTD_H test.
+
+ * config/vxworks.exp: Try to boot the system into the desired OS.
+
+ * lib/telnet.exp(telnet_open): Remove the option of passing
+ the port #. If the first optional argument is "raw", return
+ immediately rather than trying to look for a shell prompt.
+
+ * lib/util-defs.exp: Remove expect_before statement.
+
+ * config/gdb-comm.exp(gdb_comm_add_breakpoints): Check for "No
+ symbol table" message from gdb.
+
+ * config/vxworks.exp(*_load): Don't set global exec_output
+ variable. We return a list of two members, the first containing
+ the pass/fail string, and the second containing the output
+ from the executable.
+ * lib/dg.exp(dg-test): Ditto.
+
+ * config/rom68k.exp: Fix shell_prompt value (add a space at the
+ end).
+
+ * baseboards/h8300.exp: Put back magic linker script brain-damage.
+
+ * baseboards/mips-sim.exp: Check for ecoff object file format,
+ and use idtecoff.ld instead of idt.ld.
+
+ * config/dos.exp(dos_wait): Wait for a shell prompt from
+ the board before returning.
+
+ * config/i960.exp: Detect if the board starts spewing nonsense,
+ and reboot it if it does.
+ * config/base68k.exp: Ditto. Also tighten up the checks for
+ a shell prompt.
+
+ * lib/remote.exp: Add a bit more debugging output. Use -9 when
+ killing the process.
+
+Mon Jun 2 09:50:33 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(standard_close): Check the return value from
+ catch. Fix quoting on the after command.
+
+ * baseboards/rom68k-idp.exp: Look for a.out object file format.
+
+ * baseboards/vr4300-sim.exp: Look for ecoff object file format.
+ * baseboards/vr4300-ddb.exp: Ditto.
+ * baseboards/mips-idt.exp: Ditto.
+
+ * lib/libgloss.exp: Set the board's obj_format feature according
+ to the specified object file format. Handle "stabs" variant.
+
+ * baseboards/i960-cyclone.exp: Mark the board as being unreliable.
+
+ * config/i960.exp: Check for a couple of common failure modes and
+ reboot the board as needed. Also reboot if the testcase fails and
+ the board is marked as "unreliable".
+
+Sun Jun 1 16:48:30 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/base68k.exp: Add base68k_ld procedure. Clean up a few
+ regexps.
+
+ * baseboards/rom68k-idp-aout.exp: We need to pass the load offset
+ to gdb's load command.
+
+ * baseboards/rom68k-idp.exp: Use -msoft-float by default.
+
+ * lib/telnet.exp: If dont_wait_for_prompt is set, don't bother
+ trying to get a prompt back before returning.
+
+ * config/i960.exp(${board}_init): Send several CRs in order to get
+ a prompt from the board (fun with autobaud). Set
+ dont_wait_for_prompt. Clear exec_output.
+
+Sat May 31 00:29:33 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/base68k.exp: Handle various errors more gracefully.
+
+ * config/dos.exp(dos_start_command): Flush any pending output
+ before sending the new command to be run. Make regexp for
+ prompt more strict.
+
+ * contrib/test-tool: Add support for compressed log files.
+ (Can't compress ChangeLog files yet.)
+
+Fri May 30 15:08:15 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(build_wrapper): New procedure.
+
+ * config/base68k.exp: Check for use_vma_offset target feature.
+ Make sure we keep in sync with the remote target.
+
+ * baseboards/rom68k-idp-aout.exp: Try using objcopy again.
+ Make sure we link with -N.
+
+ * testglue.c: Handle m68k-aout specially.
+
+Thu May 29 19:57:47 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * testglue.c: Include sys/unistd.h.
+
+ * lib/telnet.exp: Use $connhost correctly.
+
+ * lib/remote.exp(remote_wait, remote_raw_wait, standard_wait): New
+ procedures.
+
+ * config/sim.exp(sim_load): Use remote_wait to wait on the
+ spawned child.
+
+ * config/dos.exp(dos_spawn): Make sure we can return an exit
+ status from the spawned command.
+ (dos_wait): New procedure.
+
+Thu May 29 15:08:07 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/rom68k-idp-aout.exp: Status wrapper seems to be
+ working in devo.
+
+Wed May 28 12:34:28 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/sparc64-sim.exp: New file.
+
+ * baseboards/vx68k.exp: New file.
+
+ * lib/libgloss.exp(newlib_link_flags): Also look for the linker
+ script directory that's part of ld, and include it if it
+ exists.
+
+Tue May 27 20:00:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(libgloss_link_flags): If we're building
+ for a powerpc target, the cpu is rs6000, not powerpc.
+
+Sat May 24 11:31:26 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb-comm.exp: Strip off "Continuing." response
+ from gdb. Set the height and width to 0 so GDB doesn't
+ try to scroll.
+
+Fri May 23 12:02:29 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/i960-cyclone.exp: It's noargs now.
+
+ * lib/remote.exp(call_remote): Make sure we set the
+ board's database name entry if we tried to load it.
+
+ * lib/libgloss.exp(process_multilib_options): Look for aout and
+ elf board variants, and set is_aout/is_elf as appropriate.
+
+ * lib/targetdb.exp(set_currtarget_info,unset_currtarget_info):
+ New functions.
+
+ * config/gdb-comm.exp: Check for gdb_sect_offset target feature;
+ if it's set, adjust the sections in the executable with the
+ .sect command.
+
+ * config/i386-bozo.exp: New file.
+ * baseboards/i386-bozo.exp: New file.
+
+Thu May 22 15:24:48 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/op50n.exp: Set gdb,timeout to 9 minutes.
+
+ * config/base68k.exp: Display the output from the board in
+ verbose mode.
+
+ * config/proelf.exp: Use base68k to load programs instead of
+ GDB.
+
+ * baseboards/hppa-proelf.exp: Renamed to baseboards/op50n.exp.
+
+ * lib/libgloss.exp: Make sure we don't include the libio
+ stdio directory.
+
+Wed May 21 22:58:05 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/i960-cyclone.exp: Link with i960.ld linker
+ script.
+
+Tue May 20 19:03:54 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sim.exp: Check for magic CHILDKILLED nonsense from
+ wait.
+
+Mon May 19 13:07:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/i960-cyclone.exp: New file.
+ * config/i960.exp: New file.
+
+Tue May 20 17:55:39 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/sim.exp: Set "slow_simulator".
+
+Tue May 20 08:54:55 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/*: Change "gdb,noargs" to just "noargs".
+
+Mon May 19 13:07:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/telnet.exp: Backquote the braces in "VxWorks Boot"
+ correctly this time.
+
+ * lib/remote.exp: Use catch to wrap exp_pid calls.
+
+Sat May 17 21:44:08 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(standard_close): Don't wait forever on close; if
+ it's a process, give it a SIGTERM after 10 seconds.
+ (remote_spawn): Make sure stderr and stdout all go to the same
+ place.
+
+Sat May 17 19:10:36 1997 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (install): Add missing ';' to datadir for...done.
+
+Fri May 16 23:30:27 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/powerpc-sim.exp: Can't call functions from within
+ GDB.
+
+Wed May 14 20:59:11 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp: Add spaces before options passed to
+ the compiler.
+
+Fri May 16 10:11:54 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/mn10200-sim.exp: Remove redundant setting of
+ "cflags".
+ * baseboards/mn10300-sim.exp: Likewise.
+
+Thu May 15 14:26:20 1997 Mike Meissner <meissner@cygnus.com>
+
+ * baseboards/tic80-sim.exp (gcc,no_varargs): Set to 1, the TIC80
+ doesn't support varargs.
+
+Tue May 13 11:51:06 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Makefile.in (install): Take out errant semicolon.
+
+Mon May 12 21:48:52 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(find_gas): New procedure.
+
+ * lib/target.exp(default_target_compile): Look for
+ CC_FOR_TARGET and CFLAGS_FOR_TARGET global variables.
+ (target_assemble,default_target_assemble): New procedures.
+
+Thu May 8 21:53:03 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * runtest.exp: Add more informative startup messages describing
+ the various files that are being loaded.
+ (setup_target_hook): Give a warning if a target board is the local
+ machine and a "non-native" test is being run; check if the user
+ has set their DEJAGNU variable.
+
+Tue May 6 14:27:11 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * runtest.exp(lookfor_file): Use .. instead of [file dirname].
+
+Mon May 5 22:06:14 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/vxsparc.exp: New file.
+
+ * config/vxworks.exp: Look for [VxWorks Boot] prompt.
+ * lib/telnet.exp: Ditto.
+
+Fri May 2 15:19:00 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_spawn): Add new argument for readonly
+ or writeonly processes, and use open to create a pipeline when
+ it is given.
+ * config/sim.exp(sim_load): Use it.
+
+Fri May 2 10:47:40 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/tic80-sim.exp: New file.
+
+Thu May 1 14:42:51 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/d10v.exp: Set gdb,short_int.
+ * baseboards/d10v-sim.exp: Ditto.
+ * baseboards/h8300.exp: Ditto.
+ * baseboards/h8300-sim.exp: Ditto.
+
+ * lib/remote.exp(remote_download): Ignore "files are identical"
+ error from cp.
+
+ * testglue.c: Renamed from test-glue.c.
+
+Tue Apr 29 17:42:22 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/h8300-sim.exp: Remove magic linker script braindamage.
+ Set gdb,noinferiorio, gdb/noresults, gcc,stacksize and no_long_long.
+ * baseboards/h8300.exp: Similarly.
+
+Tue Apr 29 12:56:53 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/rlogin.exp: Misc cleanups.
+
+ * lib/libgloss.exp(g++_include_flags): Don't skip if native. We're
+ also building multilib versions of the libraries now, so don't
+ pass a null argument to get_multilibs.
+ (g++_link_flags): Ditto.
+
+Mon Apr 28 12:14:27 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/telnet.exp: Default to /usr/kerberos/bin/telnet if it
+ exists.
+
+ * lib/target.exp(target_compile): Add use_at target feature, to
+ support using the @file syntax of GCC on a go32 host.
+
+ * lib/rlogin.exp(rlogin_open): Don't try to open a connection if
+ we already have one open. Use hostname and shell_prompt features of
+ target. Remove gratuitous $type variable. Don't use $board here.
+ Don't die if we get Kerberos login failures; the destination may
+ not support kerberos.
+ (rlogin_spawn): New function.
+
+ * lib/libgloss.exp(g++_include_flags): Use spaces in
+ appropriate places when appending flags.
+
+Fri Apr 25 19:03:55 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sim.exp(sim_load): Stop using bash/ulimit. If an input
+ file is supplied, feed it into the simulator using
+ remote_transmit.
+
+Thu Apr 24 14:37:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(g++_include_flags): Make sure libg++/src
+ is part of the include path.
+
+ * lib/telnet.exp(telnet_open): Look for "simple or advanced"
+ prompt from ataman. Use $connhost instead of $hostname
+ correctly. Check for hostname feature of target machine.
+
+Fri Apr 18 16:43:39 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/sh-hms.exp: Set exit_statuses_bad.
+
+ * lib/telnet.exp: Handle more unexpected responses from telnet.
+ Don't give a warning if we don't get a prompt back after sending
+ the escape character.
+
+ * config/gdb-comm.exp: Check for SIGTRAP; retry if we get one.
+ Also reboot if the program gets any other signal. Check for
+ exit_statuses_bad on the target.
+
+ * config/base68k.exp: Retry if we didn't get a real exit status.
+
+Thu Apr 10 20:04:14 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/h8300.exp: The board is unreliable, make sure failing
+ commands get retried.
+
+ * Makefile.in: Make sure we copy in any .c stub files.
+
+ * config/dos.exp: Use the pid as part of the file in /tmp;
+ delete the file after we're done. Don't create the file
+ locally until we're ready to download it (in case we're
+ being called recursively).
+
+Thu Apr 10 14:35:02 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/mn10300-sim.c: The mn10300 can perform inferior
+ function calls.
+
+Wed Apr 2 19:35:13 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/h8300.exp: Add appropriate references to linker
+ scripts. Set noinferiorio, and noresults.
+
+Sun Mar 30 00:25:59 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/ddb-ether.exp: Check for "Exception Cause" from the
+ monitor, and also retry 3 times on "invalid executable" message.
+
+ * config/ddb.exp: Add timeout section. Reboot the
+ board if we can't get any sort of a prompt.
+
+ * config/dos.exp(dos_exec): Return an error status
+ when the connection fails to the remote host. Retry
+ connecting several times, and also call remote_reboot
+ as appropriate.
+
+ * lib/ftp.exp: Check return value from ftp_open.
+
+Sat Mar 29 00:42:59 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/*.exp: General cleanup, yet again. Take
+ advantage of the new target variant support.
+
+ * runtest.exp: Fix everyone's favorite bug; now it says
+ "interrupted by user" instead of "segmentation violation"
+ when ^C is pressed.
+
+ * baseboards/vr4300-ddb.exp: Set gdb,noargs and gdb,nosignals.
+
+ * config/dos.exp: Increase timeout on program execution
+ to 5 minutes. Pass target alias to initialization
+ script. Don't delete the remote batch file.
+
+Thu Mar 27 01:38:35 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/framework.exp(is_remote): Use current_target_name, not
+ current_target.
+
+ * baseboards/m32r-sim.exp: Don't set unnecessary options here.
+
+ * lib/target.exp(default_target_compile): Add ldscript
+ option.
+
+ * config/gdb_stub.exp: Check for netport as well as serial. Use
+ gdb,start_symbol as appropriate.
+
+Wed Mar 26 16:45:42 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * runtest.exp(process_target_variants,iterate_target_variants): New
+ procedures, called as part of building up the list of targets
+ to test.
+
+ * lib/libgloss.exp(process_multilib_options,add_multilib_option): New
+ procedures.
+
+ * baseboards/*.exp: Call process_multilib_options instead of setting
+ multilib_flags directly.
+
+Wed Mar 26 16:04:48 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * baseboards/m32r-sim.exp (multilib_flags): Test all code models.
+
+Wed Mar 26 13:55:19 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/a29k-udi.exp: Don't use libio.
+
+Tue Mar 25 15:22:24 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(libgloss_link_flags): Always add a -L
+ pointing to the libgloss source directory, if it exists.
+
+ * lib/telnet.exp(telnet_binary): Thanks, HPsUX.
+ * lib/rsh.exp:(rsh_exec) Likewise, I'm sure.
+
+Mon Mar 24 22:20:18 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/dos.exp: Grab the exit status from the command we
+ executed.
+
+Sat Mar 22 13:07:52 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/mondfe.exp: General cleanups; don't be quite so
+ picky about when a prompt should appear (the last
+ step may not always be clearing the BSS section).
+
+ * config/gdb-comm.exp: Check for response when setting
+ baud rate.
+
+ * config/udi.exp: Don't be quite so picky when checking
+ for "Halt instruction encountered".
+
+ * testsuite/runtest.all/*.test: $srcdir/$subdir, not
+ $srcdir$subdir.
+
+Fri Mar 21 17:36:29 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d10v-sim.exp (sim_time_limit): Bump the default time
+ limit to 10 minutes, since gcc.c-torture/execute/920501-6.c takes
+ quite a while to do 64 bit arithmetic on a 16 bit host.
+
+Fri Mar 21 01:02:39 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/mn10300-sim.exp: The mn10300 can't perform
+ inferior function calls yet.
+
+Thu Mar 20 22:45:18 1997 Jeffrey A Law (law@cygnus.com)
+
+ * testsuite/runtest.all/options.exp: Remove "baud" test.
+
+Tue Mar 18 15:15:16 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/mn10300-sim.exp: Various updates from mn10200-sim.exp.
+
+Mon Mar 17 15:11:03 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * testsuite/runtest.all/stats-sub.exp: Add missing brace.
+
+ * config/sim.exp: If bash isn't in the user's path, then use spawn
+ and expect to try and catch cases where the simulator has gone
+ into an infinite loop.
+
+Thu Mar 13 11:59:52 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * runtest.exp: If running on multiple targets, output a summary
+ for each target. Use log_and_exit instead of log_summary.
+
+ * lib/framework.exp: Use an array (test_count) instead of
+ separate variables for each pass/fail/xpass/... count.
+ (log_and_exit, init_testcounts,incr_count): New procedures.
+
+ * lib/debugger.exp: Call log_and_exit instead of log_summary.
+
+ * lib/libgloss.exp(get_multilibs): Use -all. Substitute " -"
+ with " ", not the null string.
+
+Thu Mar 13 11:21:56 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * baseboards/mips-lsi-sim{,-EL,-sf,-sfEL}.exp: New files.
+
+Wed Mar 12 16:37:03 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/h8300-sim.exp: Add noargs and nosignals.
+ * baseboards/h8300.exp: Ditto.
+
+Tue Mar 11 17:17:43 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb-comm.exp: If we're talking to a remote host,
+ download the executable being loaded before starting GDB.
+ Check for the gdb_opts feature of the host.
+ (gdb_comm_leave): New procedure. If we're talking to a
+ remote host, always start and exit gdb for each download.
+
+ * config/dos.exp: Use remote_expect.
+
+ * config/ddb.exp: If we're talking to a remote host, don't
+ try to init the prompt.
+
+ * baseboards/vr4300-ddb.exp: Don't link in libio.
+
+ * baseboards/vr4100-ddb.exp: Don't link in libio. Do use
+ -msoft-float "just in case".
+
+ * baseboards/sh-hms.exp: We need to pass in the -L options
+ for the libgloss directories so we find the linker scripts.
+
+ * baseboards/dos.exp: Make sure --command gdbinit is passed
+ to gdb.
+
+ * runtest.exp: Prefer target_alias over target_install.
+ * baseboards/basic-sim.exp: Ditto.
+
+Sat Mar 8 12:01:04 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/mn10200-sim.exp: Fix comment.
+
+ * baseboards/sh-hms.exp: Include libgloss so we can find
+ the linker scripts.
+
+ * baseboards/sh-hms-sim.exp: Ditto.
+
+ * config/vxworks.exp: Add additional error checking cases. Remove
+ unused procedure "vxworks_transform_path".
+
+Fri Mar 7 13:53:35 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/vr5000-ddb.exp: Add configury for nullstone.
+ * baseboards/vr4300-ddb.exp: Ditto.
+
+ * config/ddb-ether.exp(ddb_ether_ld): New routine.
+ (ddb_ether_try): Use ddb_ether_ld.
+ (ddb_ether_load): Make sure we return "fail" at the end of the loop.
+
+ * config/bug.exp: Use set_board_info.
+
+ * baseboards/vr4300-sim.exp: Use mips-sim as a base configuration.
+
+ * config/gdb_stub.exp: Use remote_expect.
+
+ * lib/remote.exp(remote_ld, remote_raw_ld, remote_push_conn,
+ remote_pop_conn): New routines.
+
+Thu Mar 6 09:34:39 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/ddb-ether.exp: Use remote_expect and remote_send.
+ * config/vxworks.exp: Ditto.
+
+ * runtest.exp: Remove --baud and --connect options, no longer
+ functional.
+ (setup_target_hook): Use the hostname of the local machine when
+ searching for a board file, if a board wasn't specified with
+ --host_board.
+
+Wed Mar 5 09:37:55 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/base68k.exp: Use $dest instead of target, and remote_send
+ and remote_expect.
+
+ * lib/framework.exp(clone_output): If $sum_file is null, don't try
+ to write to the file.
+
+ * config/ddb-ether.exp(ddb_ether_try): Add -re to regexp pattern.
+
+ * baseboards/mips-sim.exp: New file.
+
+ * runtest.exp: Move loading the libraries and the
+ tool initialization file before the start of the
+ file. Allow the tool to add additional options to runtest.
+ (transform): target_install is now a list kept as part of the
+ board description. Search the list for the current target alias;
+ if found, use in preference to the default target_install entry.
+
+ * lib/targetdb.exp(set_board_info,unset_board_info): New procedures.
+
+ * baseboards/*.exp: Use set_board_info instead of setting entries
+ in the board_info array directly. Also, some general cleanup,
+ removal of useless entries, etc.
+
+Tue Mar 4 22:58:37 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/vr5000-ddb.exp: Set gdb,nosignals and gdb,noargs.
+
+Tue Mar 4 14:43:50 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/powerpc-sim.exp: Set gdb,nosignals.
+
+Mon Mar 3 12:38:28 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/base68k.exp(base68k_load): Send an extra CRLF pair.
+
+ * lib/telnet.exp(telnet_binary): Only send a linefeed to telnet
+ after the command. Don't send an extra CRLF pair after the
+ command.
+
+ * config/ddb-ether.exp: Minor cleanups.
+
+ * lib/remote.exp(remote_expect): New procedure.
+
+Fri Feb 28 17:04:11 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vr5000.exp: Use ddb-ether, as it's faster.
+
+ * baseboards/vr5000-ddb.exp: Use ddb.ld. Add setup info for
+ nullstone. Mark it as unreliable, as it gets random SIGFPEs.
+
+ * runtest.exp(setup_target_hook): Call perror instead of error.
+
+ * config/ddb-ether.exp: New file.
+
+Thu Feb 27 12:58:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/rom68k-idp.exp: Set gdb,noargs gdb,nosignals
+ and gdb,noresults.
+
+ * config/vr5000.exp,baseboards/vr5000-ddb.exp: New files.
+
+ * config/ddb.exp(${board}_init): Don't go into a recursive
+ tailspin.
+
+ * config/gdb-comm.exp(quit_gdb): New procedure.
+ (gdb_comm_load): Use it. Check for board feature
+ "unreliable". If the testcase times out, try rebooting the board
+ and reexecuting before deciding that the testcase is going into an
+ infinite loop.
+
+ * lib/rsh.exp(rsh_exec): Explicitly call sh.
+
+ * lib/telnet.exp(telnet_open): Make sure we wait for the telnet to
+ exit after closing it.
+
+ * test-glue.c: Include stdio.h and string.h.
+
+ * lib/remote.exp(standard_load): program args are in 0, input
+ is in 1.
+
+ * config/vxworks.exp(vxworks_open): Use password, not passwd.
+Sun Feb 23 14:32:34 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/telnet.exp(telnet_open): Add "catch" to the exp_send command
+ after telnet gets a connection refused.
+
+ * lib/framework.exp(record_test): Add global variable pf_prefix,
+ which contains a string that will be prefixed to every pass/fail
+ message.
+
+ * runtest.exp(runtest): Pass the name of the expect script to
+ the tool init function.
+
+ * baseboards/rom68k-idp.exp: Don't include libio.
+
+Sat Feb 22 21:02:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/telnet.exp(telnet_binary): Wait for a prompt after sending
+ the telnet escape character.
+
+Fri Feb 21 13:46:45 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * Makefile.in (install): Install the baseboards and config
+ .exp files.
+
+ * config/vxworks.exp: General cleanup and restructuring.
+ Added vxworks_exec.
+
+Thu Feb 20 17:17:08 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vxworks.exp(vxworks_ld): Unload modules after testing them.
+ Check the results from remote_open; reboot the target if needed.
+
+ * lib/remote.exp(remote_download): Check the result code from "cp".
+
+Wed Feb 19 16:19:04 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/vr4300-sim.exp: Not "setup_sim vr4300", it's
+ mips.
+
+ * config/gdb-comm.exp: Use warning instead of perror in several
+ places.
+
+Wed Feb 19 09:36:06 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/powerpc-bug{,1}.exp: New files for dealing with
+ PPCBUG monitor on ports 0 and 1.
+
+ * baseboards/powerpc-sim.exp (needs_status_wrapper): Delete,
+ simulator can return exit statuses correctly.
+
+Mon Feb 17 16:52:37 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d10v-sim.exp (needs_status_wrapper): Delete,
+ simulator can return exit statuses correctly.
+ (sim_time_limit): Delete, simulator can take more than 10 seconds
+ on some tests.
+
+Thu Feb 13 15:59:28 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * runtest.exp(runtest): Record number of seconds it took to
+ run the testcase.
+
+ * lib/framework.exp(log_summary): Log finish time.
+
+ * lib/remote.exp(check_for_board_status): If $result ends up being
+ empty, don't crash. Also, be a bit more lax about what we're
+ removing from the result being processed.
+
+Thu Feb 13 13:17:19 1997 Michael Meissner <meissner@cygnus.com>
+
+ * baseboards/d10v{,-sim}.exp: D10v has small stack, no trampoline
+ support, and can't do labels as values.
+
+Tue Feb 11 12:54:17 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/mondfe.exp: Use mondfe,name instead of remote_host.
+
+ * config/gdb_stub.exp: Remove bogus global declaration.
+
+ * lib/target.exp(default_target_compile): Append -lm at the end of
+ the argument list, so it is linked in as appropriate.
+
+Tue Feb 11 11:01:33 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/mn10200-sim.exp: Remove gdb,cannot_call_functions.
+
+ * lib/remote.exp (remote_exec): Send PARGS to exec, not ARGS.
+
+ * lib/remote.exp (remote_exec): OUTP comes from argument 2, not
+ argument 1!
+
+Mon Feb 10 16:40:27 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/vxworks.exp: Return $shell_id like we should.
+
+ * baseboards/d10v.exp: Fix.
+
+ * lib/telnet.exp: Don't be quite so verbose.
+
+ * lib/remote.exp(standard_send): Quote the string being sent
+ correctly.
+ (standard_transmit): Change a few verbose message levels.
+
+ * config/dos.exp: Return the result of remote_raw_send.
+ * config/vxworks.exp: Ditto.
+
+Sun Feb 9 20:58:53 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/rom68k-idp.exp: Use objcopy by default, as
+ otherwise gdb won't work with srecords.
+ * baseboards/rom68k-idp-aout.exp: Output srecords directly.
+
+Sat Feb 8 13:40:38 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(libio_include_flags): Use the correct
+ binary directory when including _G_config.h.
+
+ * baseboards/mips-idt.exp: Add -nostdlib. Use idt.ld, not
+ pmon.ld.
+
+ * lib/remote.exp(standard_send): Use catch. Return a success
+ or fail status. Don't use error, use perror.
+
+ * config/vr4100.exp, config/ddb.exp: New files.
+
+ * config/gdb-comm.exp: Try reopening 4 times before failing,
+ rather than just once. Also, if we get a valid status result
+ from the board, use it instead of trying to check the exit
+ code passed to exit().
+
+ * lib/telnet.exp(telnet_open): Don't send the initial cr until
+ we've seen the "Escape character is..." line from telnet. Also,
+ if we got an unexpected EOF from telnet, wait 5 seconds before
+ trying again.
+
+Fri Feb 7 13:22:43 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * runtest.exp: Add --tool_exec and --tool_opt options. Clean
+ up the help messages to correspond with reality a bit better.
+
+ * lib/target.exp(prune_warnings): Merge in all the various
+ random versions of prune_system_crud and prune_warnings.
+ Nuke prune_system_crud without prejudice; replace with calls
+ to prune_warnings.
+
+ * lib/dg.exp: Use prune_warnings instead of prune_system_crud.
+
+Fri Feb 7 09:41:40 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/mn10200-sim.exp: Set gdb,noresults gdb,noinferiorio
+ and no_double.
+
+Thu Feb 6 13:08:50 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp(remote_download): When copying to a local file,
+ make sure the copied file has read permissions for other.
+
+ * baseboards/vx960.exp: New file.
+
+ * config/vxworks.exp: Fix.
+
+ * lib/libgloss.exp(get_multilibs): If a list of multilib options
+ is specified, don't return the cached multilib path.
+
+Wed Feb 5 22:08:03 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/mn10200-sim.exp: Random cleanups.
+ Set gdb,noargs gdb,nosignals and gdb,cannot_call_functions.
+
+Tue Feb 4 21:43:39 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * baseboards/sh-hms.exp: Set gcc,stack_size as well.
+
+ * config/gdb-comm.exp: Add gdb_run_command target feature.
+
+ * baseboards/a29k-udi.exp: Use gcc,stack_size instead of
+ defining STACK_SIZE.
+ * baseboards/armpe-sim.exp: Ditto.
+ * baseboards/mn10200-sim.exp: Ditto.
+ * baseboards/sh-hms-sim.exp: Ditto.
+
+Tue Feb 4 15:51:21 1997 Jim Wilson <wilson@cygnus.com>
+
+ * baseboards/sh-hms-sim.exp (cflags): Add -DSTACK_SIZE=16384.
+
+Mon Feb 3 12:30:02 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/remote.exp: Be a little be more lenient about what matches
+ the exit code returned from the board.
+
+ * baseboards/rom68k-idp-aout.exp: Fix.
+
+ * lib/telnet.exp: Added send_initial_cr board feature.
+ Make sure we respawn telnet if it dies.
+ * config/base68k.exp: Set it.
+ (base68k_load): Set exec_output. If we get a timeout from the
+ board, this is now considered to be a failure.
+
+ * baseboards/sh-hms.exp: This is now the baseboard for a SH board,
+ not the simulator.
+
+ * baseboards/sh-hms-sim.exp: New file.
+ * config/sh.exp: New file.
+ * baseboards/m32r-sim.exp: New file.
+
+Mon Feb 3 07:54:04 1997 Jeffrey A Law (law@cygnus.com)
+
+ * baseboards/mn10200-sim.exp: Add -DSTACK_SIZE=4096 to cflags.
+ Set no_long_long for this target.
+
+Sun Feb 2 15:29:09 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(find_gcc): Don't be quite so choosy about
+ the name of the compiler. But, make sure we look in all the
+ right places.
+
+ * lib/remote.exp(standard_close): Return 0.
+
+ * lib/mondfe.exp(mondfe_close): Return 0 if the connection is
+ already closed.
+
+Sun Feb 2 17:47:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/target.exp: Only mention the compiler exit status if it is
+ non-zero.
+
+Sun Feb 2 00:00:39 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/dos.exp: Use $shell_prompt, not $prompt.
+ * config/netware.exp: Ditto.
+ * lib/rlogin.exp: Ditto.
+ * lib/rsh.exp: Ditto.
+ * lib/telnet.exp: Ditto.
+ * lib/tip.exp: Ditto.
+
+Sat Feb 1 12:38:05 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/unix.exp: It's $dest, not $targetname.
+
+ * runtest.exp: Add global variable boards_dir, which will
+ point to the directory containing the board description
+ files referred to by site.exp.
+
+ * lib/target.exp: Always log output from the compile.
+
+Sat Feb 1 10:36:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/libgloss.exp (libgloss_link_flags): Add slash at the end of
+ the -B option.
+
+Fri Jan 31 11:36:12 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/gdb-comm.exp: Use $spawn_id consistently in expect.
+ Grab output from the board and stuff it into exec_output;
+ also check for status output from the status wrapper.
+
+ * baseboards/vr4300-ecoff-sim.exp: New file.
+
+ * baseboards/mips64-sim.exp: It's basic-sim, not basic-sim.exp.
+
+ * lib/target.exp(default_target_compile): If we end up with no
+ compiler, or if we can't find it and we're compiling locally, give
+ an error and return.
+
+ * lib/libgloss.exp(get_multilibs): If the host is remote, or if we
+ have no compiler, or it can't be found, don't look for multilibs.
+ (find_gcc): Don't even check to see if the compiler exists.
+ (libio_include_flags): Don't bother looking for the include dir if we
+ haven't got libio.a.
+
+Thu Jan 30 11:48:29 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/libgloss.exp(get_multilibs): Options can be all caps too.
+
+ * config/gdb-comm.exp: Remove spurious quote. (Thanks, TCL!)
+ Add dest parameter to gdb_comm_reload calls.
+ Remind me not to reuse code (go_idle).
+
+ * runtest.exp(setup_target_hook): Use the non-generic name of
+ the host when searching for a host-specific target description.
+ (load_board_description): Use append correctly.
+
+ * baseboards/sparclite-coff.exp: New file.
+
+ * config/gdb_stub.exp: Add generic support for GDB stub targets
+ (derived from sparclet.exp).
+ * config/sparclet.exp: Use it.
+ * config/slite.exp: Use it.
+
+ * config/gdb-comm.exp: Rename the rest of the routines while
+ I'm at it.
+
+ * baseboards/d10v-sim.exp: Set gdb,nosignals and gdb,noargs.
+
+ * config/gdb-comm.exp: Change gdb_reload to gdb_comm_reload,
+ gdb_file_cmd to gdb_comm_file_cmd and gdb_add_breakpoint to
+ gdb_comm_add_breakpoint.
+
+ * baseboards/d10v.exp: It's d10v-elf.
+ * baseboards/d10v-sim.exp: Ditto.
+
+ * config/dos.exp: Check for errors when opening a connection.
+
+ * runtest.exp: Remove the slash after $srcdir when generating $subdir.
+
+ * config/m32r.exp: Use load_generic_config, not load_config.
+ * config/proelf.exp: Ditto.
+
+ * runtest.exp(transform): Add missing global declaration.
+
+ * lib/remote.exp(remote_reboot): Call ${board}_init after we
+ reboot the board.
+ (call_remote): If we're not working on a raw connection, look for a
+ protocol specified by the board description and use it.
+
+ * config/unix.exp: Replace ${board} with unix, and set the board's
+ protocol to unix.
+
+ * config/udi.exp: Replace ${board} with udi, and set the board's
+ protocol to udi.
+
+ * config/sim.exp: Replace ${board} with sim, and set the board's
+ protocol to sim.
+
+ * config/dos.exp: Replace ${board} with dos, and set the board's
+ protocol to dos.
+
+ * runtest.exp(load_generic_config): Don't set the generic name of
+ the board if it already has one.
+
+ * config/gdb-comm.exp: Remove definition of ${board}_init, and move
+ initialization to gdb_comm_start. Change $prompt to $gdb_prompt.
+ Look to see if the destination board has defined gdb_prompt, and use
+ it. Change ${board} to gdb_comm, and set the board's protocol as
+ gdb_comm.
+
+ * baseboards/armpe-sim.exp: Fix typo; it's "needs_status_wrapper".
+ * baseboards/d10v-sim.exp: Ditto.
+ * baseboards/vr4300.exp: Ditto.
+ * baseboards/sparclet-aout.exp: Ditto.
+ * baseboards/sh-hms.exp: Ditto.
+ * baseboards/mn10300-sim.exp: Ditto.
+ * baseboards/mn10200-sim.exp: Ditto.
+ * baseboards/m32r-elf.exp: Ditto.
+ * baseboards/h8300.exp: Ditto.
+ * baseboards/h8300-sim.exp: Ditto.
+ * baseboards/vr4300-ddb.exp: Ditto
+ * baseboards/vr4300-ddbecoff.exp: Ditto.
+
+Thu Jan 30 00:00:48 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * baseboards/vr4300-ddb*: New files.
+
+Wed Jan 29 14:19:53 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/sim.exp: Log which simulator is being run.
+
+ * {baseboards,config}/h8300.exp: New files.
+
+ * baseboards/vr4300.exp: Don't need to set generic_name anymore,
+ this is done by load_generic_config.
+ * baseboards/m32r-elf.exp: Ditto.
+ * baseboards/unix.exp: Ditto.
+ * baseboards/v850-sim.exp: Ditto.
+ * baseboards/vr4300-sim.exp: Ditto.
+
+ * config/vr4300.exp: It's load_generic_config now; don't need the
+ .exp suffix either.
+ * config/bug.exp: Ditto.
+ * config/mips-idt.exp: Ditto.
+ * config/rom68k.exp: Ditto.
+
+ * config/gdb-comm.exp(go_idle): Set shell_id before doing an
+ send/expect. Use "remote_send host" instead of send.
+ (gdb_comm_start): GDB and prompt are globals; declare them so.
+ (${board}_load): need to give a boardname to board_info.
+
+ * lib/remote.exp(remote_exec): Add logging.
+
+Wed Jan 29 00:19:01 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ Major revisions for cross-testing and remote hosted testing.
+
+ * runtest.exp: Remove several global variables, including variables
+ that describe target info; this is now kept in the board_info
+ array. Add new options --host_board and --target_board. Remove
+ --name option.
+ (search_and_load_file): New routine.
+ (lookfor_file): New routine.
+ (load_lib): Use search_and_load_file.
+ (setup_target_hook, setup_host_hook): New routines.
+ (load_generic_config, load_tool_target_config, load_tool_init,
+ load_board_description, load_base_board_description): New routines.
+ (runtest): New routine, code moved from main loop.
+
+ * site.tmpl: Update using new format of site.exp.
+
+ * lib/dg.exp(dg-init): Remove call to ${tool}_init, this is now done
+ by runtest.exp.
+ (dg-test): Change the format of the results returned from
+ ${tool}-dg-test to include the output from the test.
+
+ * lib/framework.exp(is_remote): New routine.
+
+ * lib/libgloss.exp: Add libgloss_{link,include}_flags,
+ newlib_{link,include}_flags, libio_{link_include}_flags,
+ g++_{link,include}_flags.
+
+ * lib/remote.exp: Major rewrite. Add remote_* functions,
+ move telnet, rlogin, ftp, kermit, et al to separate files.
+
+ * lib/target.exp(set_target_info, compile, archive, ranlib,
+ link_objects, execute_anywhere, getprompt, make): Deleted.
+ (push_target,push_config,pop_config,pop_target): Don't copy
+ the entries around, just change the name.
+ (target_compile, default_target_compile, reboot_target): New routines.
+
+Fri Jan 3 12:30:07 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * site.tmpl (powerpc*-*-eabi*): Add sample entry.
+
+Thu Dec 12 18:11:24 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/utils.exp (diff): Set list_a and list_b to null so diffing
+ empty files works.
+ * lib/framework.exp (unknown): Set the exit status before calling
+ log_summary.
+
+Thu Dec 5 10:24:27 1996 Fred Fish <fnf@rtl.cygnus.com>
+
+ * runtest.exp: Fix an indentation glitch. Before running a new
+ test case clear any pending errcnt so that the first test in the
+ new test case won't become a spurious "unresolved" test.
+
+Mon Dec 2 21:55:22 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/utils.exp (diff): Notice the file dofferences even if the
+ file lengths are the same.
+ * lib/remote.exp (rsh_exec): Work with both csh and sh.
+ * lib/target.exp (execute_anywhere): Print an error message if
+ START & END aren't found rather than core dump.
+
+Fri Oct 18 20:54:10 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/target.exp (prune_warnings): Fix typo in sunos pattern.
+
+Thu Oct 3 16:00:52 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * doc/Makefile.in (clean): Move config.log to distclean.
+ * example/calc/Makefile.in (clean): Move config.log to distclean.
+ * testsuite/Makefile.in (clean): Move config.log to distclean.
+
+Wed Oct 2 17:46:15 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (distclean): Remove config.cache
+ * doc/Makefile.in (clean): Remove config.log
+ * example/calc/Makefile.in (clean): Remove config.log
+
+Wed Oct 2 16:59:24 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * testsuite/Makefile.in (clean): Remove config.log.
+
+Mon Sep 30 11:23:25 1996 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TKLIB): Typo fix.
+
+Fri Sep 27 12:17:35 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * contrib/test-tool (todayname): Add some echos around the "Here is"
+ lines.
+
+Thu Sep 26 17:09:00 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * contrib/test-tool: For g++, also track ChangeLog.fsf.
+
+Fri Aug 30 10:35:12 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * contrib/test-tool: Don't use cp -p if not supported.
+ Fix first call to grep to extract PASS/FAIL/Ufoo messages.
+
+Fri Aug 23 22:58:56 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/libgloss.exp(libgloss_cflags): Convert the mips part of the
+ target triplet to just "mips", so the libgloss stuff can be found.
+
+Fri Aug 23 13:46:30 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (configure): Delete dependencies.
+ (config.status): Depend on configure.
+ * example/Makefile.in: Likewise.
+ * testsuite/Makefile.in: Likewise.
+
+Thu Aug 15 16:38:52 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lib/libgloss.exp (libgloss_flags): Add trailing slash to -B we
+ added.
+ (newlib_flags): Likewise.
+
+Mon Aug 12 16:07:21 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/libgloss.exp(libgloss_cflags): Convert the hppa part of the
+ target triplet to just "pa", so the libgloss stuff can be found.
+
+Thu Aug 8 17:07:52 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/libgloss.exp(libgloss_flags): Don't look in new config info,
+ just use CFLAGS & LDFLAGS as they're set as the default variables
+ by the config code.
+
+ * lib/libgloss.exp(libgloss_flags): Look for the srcdir too, so we
+ can find the linker script when libgloss isn't installed yet.
+
+Thu Aug 8 15:54:59 1996 Tom Tromey <tromey@charmed.cygnus.com>
+
+ * lib/remote.exp (telnet): Don't exp_send directly after a spawn.
+ Make line-termination-matching regexp more strict. Use "expect",
+ not "catch expect". Loop terminates when prompt is found.
+ login/password check no longer matches everything.
+
+Tue Aug 6 21:08:37 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/libgloss.exp(get_multilibs): New proc to run gcc
+ --print-multi-lib and to parse out the path and option info.
+ (libgloss_flags,newlib_flags): Use get_multilibs, and set the
+ -B and -L paths right based on the -m options passed to the cross
+ compiler.
+
+Wed Jul 31 15:21:08 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/libgloss.exp: Don't return an empty linker script name with
+ -T.
+
+Thu Jul 25 15:19:32 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * runtest: Add another place to look for runtest.exp.
+
+Wed Jul 24 15:41:21 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * runtest.exp: Accept "0-9_-" as legit characters for variable
+ names defined on the command line.
+
+Thu Jul 11 12:45:38 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * runtest: Find runtest.exp in $(prefix)/share, not $(prefix)/lib.
+
+Mon Jul 8 16:05:57 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * contrib/test-tool: Update gcc/g++ testing directory.
+
+Tue Jun 25 10:21:24 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * runtest.exp (load_file): Catch errors in "file exists".
+
+Mon Jun 24 17:26:20 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, infodir, includedir): Use
+ autoconf-set values.
+ (docdir): Removed.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * configure: Rebuilt.
+ * doc/Makefile.in (VPATH, mandir, infodir, INSTALL_PROGRAM,
+ INSTALL_DATA): Use autoconf set values.
+ * doc/configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * doc/configure: Rebuilt.
+ * example/Makefile.in (bindir, libdir, datadir, mandir, infodir,
+ includedir): Use autoconf set values.
+ (docdir): Removed.
+ * example/configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * example/configure: Rebuilt.
+ * example/calc/configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * example/calc/configure: Rebuilt.
+ * testsuite/configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * testsuite/configure: Rebuilt.
+ * testsuite/aclocal.m4: New. Include ../aclocal.m4.
+
+Wed Jun 12 14:18:09 1996 Tom Tromey <tromey@thepub.cygnus.com>
+
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TCLH, CY_AC_PATH_TKH): Use odd names to
+ avoid name clashes with SunOS headers.
+
+Tue Jun 4 17:53:16 1996 Gordon Irlam <gordoni@snuffle.cygnus.com>
+
+ * install-sh: Add MIT copyright. Fix typo.
+
+Fri May 31 14:09:32 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * QuickRef.ps: Removed.
+
+Tue May 28 13:03:48 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * testsuite/configure: Regenerated.
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TCLH): Don't use AC_TRY_RUN.
+ (CY_AC_PATH_TKH): Don't use AC_TRY_RUN.
+
+Tue May 21 11:40:41 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * aclocal.m4 (CY_AC_PATH_TCLH): Guess Tcl version if cross compiling.
+ * testsuite/configure: Regenerated.
+
+Tue May 14 15:38:04 1996 Mark Alexander <marka@andros.cygnus.com>
+
+ * lib/target.exp (compile): Use append instead of lappend
+ to prevent cflags from being surrounded by curly braces.
+
+Wed Apr 10 13:29:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * site.tmpl (h8300*-*-*): Define STACK_SIZE and NO_LONG_LONG.
+
+Mon Apr 8 16:21:15 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * testsuite/Makefile.in (configure): Removed bogus tab.
+
+Tue Feb 20 19:43:47 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * runtest.exp (main loop): Handle a=b=c in $MULTIPASS.
+
+Fri Feb 2 10:25:32 1996 Jeffrey A Law (law@cygnus.com)
+
+ * site.tmpl (hppa*-*-proelf*): Update.
+
+ * lib/target.exp (compile): Add a space before appending $arg
+ to $options.
+
+Thu Feb 1 22:48:15 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * framework.exp (perror, warning): Add an errno global so the
+ error message is from a subroutine is accessible to the calling
+ proc.
+ * remote.exp (rlogin, telnet, rsh): Trap various kerberos message
+ when kinit is needed.
+ * testsuite/runtest.all/libs.exp: Trap untested, unsupported,
+ warnings, and errors too.
+ * testsuite/runtest.all/remote.exp: Look for kerberos messages so
+ those come up untested, rather than failures. This is only cause
+ we're testing by connecting to the localhost.
+
+Mon Jan 29 08:49:14 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/dg.exp (dg-format-linenum): dg-linenum-format is global.
+
+Sun Jan 28 13:28:12 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * lib/dg.exp (dg-test): Update to handle new results from ${tool}_load.
+
+Sat Jan 27 13:04:58 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ From Anthony Green <green@cygnus.com>.
+ * lib/dg.exp (dg-do-what-default, dg-interpreter-batch-mode,
+ dg-linenum-format): New globals.
+ (dg-format-linenum): New proc.
+ (dg-{error,warning,bogus}): Call dg-format-linenum.
+ (dg-test): Set dg-do-what to ${dg-do-what-default}.
+ Use ${dg-linenum-format} in trimming line number field.
+ Don't scan for excess errors or delete output file if testing an
+ interpreter.
+
+ * lib/dg.exp (${tool}-dg-test): Delete default_flags and libs args.
+ (dg-extra-tool-flags): Renamed from dg-default-tool-flags.
+ (dg-runtest): Delete libs arg.
+ (dg-test): Likewise. Merge ${tool_flags} ${dg-extra-tool-flags} when
+ calling ${tool}-dg-test.
+
+Thu Jan 18 19:51:11 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/remote.exp: All tcp/ip connection procs now are consistant
+ with each other. The all take (optionall) "target" or "host" and
+ establish a connection using the config array. plus they all do
+ three retries on each connection.
+ * runtest.exp: Minor formatting changes.
+ * lib/target.exp: Fix a few config bugs.
+ * testsuite/runtest.all/{remote,target}.exp: New test cases for
+ remote.exp and target.exp.
+
+Wed Jan 17 11:32:21 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * testsuite/Makefile.in (check): Find Tcl library directory.
+
+Tue Jan 16 11:11:44 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * testsuite/runtest.all/{remotelib,targetlib,utilslib,framelib}.exp:
+ Removed.
+ * testsuite/runtest.all/{clone_output,config,utils}.test: New
+ files for testing DejaGnu's library procs without runtest. These
+ all run standalone, as well as under DejaGnu.
+ * testsuite/runtest.all/libs.exp: Run standalone DejaGnu tests.
+
+Mon Jan 15 18:16:07 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * tcl-mode.el: Updated to version 1.49.
+
+Thu Jan 11 12:26:06 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * runtest.exp (--help): Fix --build description.
+
+Thu Jan 11 10:08:14 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * testsuite/configure.in: Macro now called CY_AC_PATH_TCLH.
+ * testsuite/configure: Regenerated.
+
+ Changes in sync with expect:
+ * configure.in (ENABLE_GDBTK): Use CY_AC_PATH_TCL and
+ CY_AC_PATH_TK.
+ * aclocal.m4: Replaced with version from expect.
+ * configure: Regenerated.
+
+Fri Jan 5 19:57:06 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * testsuite/lib/libsupp.exp: New support file for testing
+ DejaGnu's libraries.
+ * testsuite/runtest.all/
+ framelib.exp,remotelib.exp,targetlib.exp,utilslib.exp: New test
+ drivers, one for each library.
+ * testsuite/runtest.all/options.exp: Create mini config file so
+ the test cases still work.
+
+Thu Jan 4 22:51:46 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * doc/dejagnu.texi: Add new sections on all the new librry
+ routines. Rewrite config section, lots of other editing changes.
+
+Wed Dec 20 00:49:16 1995 Jeffrey A Law (law@cygnus.com)
+
+ * lib/utils.exp (prune_system_crud): Discard warning about
+ lack of exception sections from osf linker.
+
+Mon Dec 11 09:31:55 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * contrib/test-tool: Use TMPDIR if set.
+
+Fri Dec 1 20:58:03 1995 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * doc/Makefile.in: Don't include the expect and tcl texinfo files
+ anymore, they're incredibly out of date.
+ * doc/dejagnu.texi: Updates for version 1.3.
+
+Wed Nov 29 17:33:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/utils.exp (prune_system_crud): Discard warning about g++ not
+ supporting -g with DWARF.
+
+Wed Nov 29 12:47:22 1995 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * lib/libgloss.exp: Look for newlib and libgloss with the new
+ configure path so stuff fully links again.
+
+Wed Nov 22 13:15:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/utils.exp (prune_system_crud): Discard -g -O warnings from
+ native compilers on OSF/1 and SunOS.
+
+Thu Nov 2 14:50:23 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * runtest.exp: Set host_triplet to $build_triplet if it doesn't
+ exist.
+
+Thu Oct 19 21:34:55 1995 Fred Fish <fnf@cygnus.com>
+
+ * doc/Makefile.in, example/Makefile.in: Remove extraneous tabs
+ from otherwise empty line. Confuses older non-GNU versions of "make".
+
+Tue Oct 17 12:11:40 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * lib/libgloss.exp (newlib_flags): Delete msoft-float support.
+ Pass a -B option instead of a -L option. Add a -I option for the
+ machine dependent header files.
+
+Mon Oct 16 13:27:27 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/target.exp (execute_anywhere): Use -log argument to verbose
+ to eliminate duplicate messages in log file.
+
+Fri Oct 6 20:44:05 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/libgloss.exp (newlib_flags, libgloss_flags): Just return the
+ options so they work if gcc is in your path for a canadaian cross.
+ * lib/remote.exp: Use "current" as an index into the target array
+ rather than "target". Remove the need to
+ target_info(current,prompt).
+ * lib/target.exp (prune_warnings): Filter out the other warning we
+ can safely ignore. Also strip out "\r" characters added by a
+ remote command.
+ (remote_open) Look for output between START and END rather than a
+ prompt.
+
+Fri Sep 29 12:36:43 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/targets.exp (prune_warnings): Only check for ld.so warning
+ on sunos systems. Check against host, not target.
+ * lib/debugger.exp:
+ * runtest.exp: Set target_abbrev to default to "unix" rather than
+ "-unset-".
+
+Wed Sep 27 10:10:48 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/targets.exp (prune_warnings): Remove certain host specific
+ warnings from the compiler and linker.
+ (compile,archive,ranlib): Use prune_warnings, and make comp_output
+ a global incase the final error message is wanted to display.
+
+Tue Sep 26 23:58:16 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/framework.exp (warning, perror): Take an optional numeric
+ value to set the count to. A "0" effectively resets after the
+ message so it doesn't have side effects on unrelated tests.
+
+Fri Sep 22 13:02:00 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * runtest.exp (srcdir): Mark trailing '/' as deprecated,
+ and append it outside the main loop.
+
+Wed Sep 20 13:25:40 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New synonym for realclean. Run
+ target in subdirectories before current directory.
+ * example/Makefile.in (maintainer-clean): Likewise.
+ * doc/Makefile.in (maintainer-clean): New synonym for realclean.
+ * example/calc/Makefile.in (maintainer-clean): Likewise.
+ * testsuite/Makefile.in (maintainer-clean): Likewise.
+
+Wed Sep 20 11:28:09 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * testsuite/runtest.all/subdirs*: Add subdirs and bogus test files
+ to use for testing the getdirs and find procs.
+ * testsuite/runtest.all/libs.exp: New test driver for library
+ procs.
+
+Tue Sep 19 16:58:57 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lib/remote.exp (remote_open): If we can't find netdata in the
+ path, return a shell_id of -1.
+
+Mon Sep 18 10:24:51 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/utils.exp (getdir): Stip out CVS, RCS, and a few other
+ directories we don't need.
+
+ * runtest.exp: Get $tool dirs first, then process the subdirs.
+ * lib/utils.exp (getdir,find): Search for directories and files
+ the old way.
+
+ * testsuite/runtest.all/options.exp: Fix broken options and add
+ tests for new options.
+
+Sat Sep 9 16:14:55 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lib/vxworks.exp (vxworks_spawn): Add `global checktask'.
+
+Sat Sep 9 08:54:01 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/utils.exp: (diff) Fix to return correct value. Also make the
+ output clearer for the differences found, and scan the whole file.
+
+Fri Sep 8 13:57:44 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lib/remote.exp (download): Use verbose, not puts, when saying
+ how many lines we downloaded.
+
+Thu Sep 7 10:56:41 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/utils.exp (find): Fix so it doesn't get duplicate
+ directories.
+
+Wed Sep 6 20:51:40 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/libgloss.exp: New file. Find linker scripts and search paths
+ for the linker for libgloss supported targets.
+ * lib/framework.exp: Set default output file to testrun.sum and
+ testrun.log if --tool wasn't specified.
+ * lib/remote.exp: Change from "current" to "target" for
+ target_info index.
+
+Tue Sep 5 22:05:52 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * runtest.exp: Extract the vaules for *_cpu, *_vendor, and *_os
+ from the config triplets. Tweak a few comments. Init files can now
+ also be named $target_os.exp.
+ * lib/target.exp: Add procs to find libgloss so we can produce a
+ fully linked executable. Tweak a few comments, fixed push_target.
+
+Thu Aug 31 21:16:08 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/utils.exp: (getdirs) now ignores directories named CVS, RCS,
+ and SCCS.
+ * runtest.exp: --tool is now optional. init files can also be
+ named using the target_os part of target_triplet
+
+Thu Aug 31 02:52:57 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * runtest.exp: Don't set target_triplet if already set.
+
+Wed Aug 30 21:34:16 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * runtest.exp: Use $*_triplet rather than $arg_*_triplet so
+ configfile settings don't get trashed.
+
+ * runtest.exp: Fix argument processing for --host, --build, and
+ --target.
+
+Mon Aug 28 23:39:17 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * lib/target.exp: New file containing most of the new config code.
+ * lib/framework.exp: Fix ishost, istarget, isnative to use new
+ config subsystem. Add is3way, isbuild.
+ * lib/utils.exp: Add diff, setenv, getenv, unsetenv procs that
+ function like the Unix commands of the same name.
+ * lib/remote.exp: Add support to use the new config subsystem.
+ * runtest.exp: Add support for handling the new config subsystems.
+
+Fri Aug 4 15:37:55 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/dg.exp (dg-test): Also watch for unsupported from
+ ${tool}-dg-prune.
+
+Wed Aug 2 21:36:10 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/dg.exp (dg-test): Watch for untested/unresolved markers
+ from ${tool}-dg-prune.
+
+ * runtest.exp (init section): Delete host, target.
+ Document host_triplet, target_triplet, target_alias.
+
+Tue Aug 1 11:34:46 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * runtest.exp (target_abbrev): Provide initial value in case
+ $DEJAGNU not set and global config file doesn't exist.
+
+Fri Jul 28 11:43:59 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lib/vxworks.exp (checktask): New variable, default to `fp'.
+ (vxworks_spawn): Use it.
+
+ * lib/vx29k.exp: Delete file.
+
+Fri Jul 28 00:24:40 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * site.tmpl: Make gdbserver the default for cross tests;
+ no easy way to make it conditional on lynx here.
+
+Thu Jul 27 16:21:05 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/{mh-linux, mh-sysv4}: Removed.
+
+ * Makefile.in (configure): Removed rule that automatically
+ rebuilds configure script. Users might not have autoconf.
+ * configure.in: Use AC_PROG_CC instead of AC_SUBST, but still
+ set CC to ${CC-cc} before that as per cygnus conventions.
+ * configure: Regenerated with autoconf 2.4.2.
+
+Wed Jul 26 19:41:56 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * lib/vx29k.exp: Copy of vxworks.exp, but without `filesys:' and
+ using the `tt' command instead of `fp'.
+
+Wed May 10 18:33:21 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * site.tmpl: Create rule for Oki targets. Make Winbond rule more
+ specific.
+
+Wed May 10 14:50:12 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * lib/bug.exp (bug_load): send two carriage returns to leave
+ s-record download mode.
+ (bug_execute): set exec_output.
+
+Thu May 4 11:48:12 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * lib/remote.exp (remote_open): If $reboot is set, call
+ reboot_hook proc if it exists.
+ Added experimental new connect type "netdata".
+
+Wed May 3 15:40:55 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * runtest.exp: Redo argument parsing so that arguments of the form
+ --foo=bar are processed correctly.
+
+Sat Apr 29 12:59:18 1995 Doug Evans <dje@chestnut.cygnus.com>
+
+ * lib/dg.exp: New file.
+
+ * runtest.exp (verbose): New option -log.
+
+Wed Apr 26 12:40:23 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * runtest.exp (main loop): Set multipass_name.
+ * lib/framework.exp (record_test): Print multipass_name if not empty.
+
+ * lib/framework.exp (record_test): Handle UNTESTED, UNRESOLVED,
+ and UNSUPPORTED.
+ (untested, unresolved, unsupported): Call record_test.
+ * lib/util-defs.exp: Whitespace and verbosity cleanup.
+ * testsuite/Makefile.in (site.exp): Set tmpdir.
+ (realclean): rm -rf tmpdir.
+ * testsuite/config/default.exp: Whitespace cleanup.
+ * testsuite/runtest.all/options.exp: Likewise.
+ * testsuite/runtest.all/stats.exp: New file.
+ * testsuite/runtest.all/stats-sub.exp: New file.
+
+ * runtest.exp: Parse --tool in time for config files to use it.
+
+Mon Apr 24 14:15:21 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * site.tmpl: Re-install hppro config lost in previous change.
+
+Mon Apr 24 11:29:51 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * runtest.exp (multipass): New global.
+ (main loop): Make multiple passes if MULTIPASS set.
+ (VAR= processing): Allow A=b=c.
+
+Sun Apr 23 10:29:37 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * site.tmpl: Revert last change, GDB isn't the only program that
+ uses dejagnu for testing.
+
+Fri Apr 21 15:46:42 1995 Stu Grossman (grossman@rtl.cygnus.com)
+
+ * site.tmpl: Change configs for monitor-based GDB targets to use
+ common startup file.
+
+Fri Apr 21 12:16:56 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * lib/remote.exp (kermit, rlogin, rsh, telnet, tip): Don't set
+ connectmode.
+ (telnet): Send "\r\n" before attempting to match prompt.
+ (remote_open): split apart $netport into host and port,
+ and pass those values to the telnet proc.
+
+Wed Apr 19 17:30:40 1995 Stu Grossman (grossman@cygnus.com)
+
+ * site.tmpl: Add support for m68k-cpu32bug-coff.
+
+Sat Apr 15 17:44:57 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/utils.exp (prune_system_crud): Only define if not already
+ defined.
+
+Tue Mar 28 17:45:37 1995 Stu Grossman (grossman@cygnus.com)
+
+ * site.tmpl: Add nosignals flag to indicate targets that can't
+ use signals. Change a bunch of append commands to set commands.
+
+Tue Mar 28 15:50:44 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * lib/remote.exp (remote_open, remote_close): New procs.
+ (download): changed to not convert contents of file to
+ s-records, as file is already supposed to contain s-records.
+
+Fri Mar 24 15:40:39 1995 Stu Grossman (grossman@cygnus.com)
+
+ * site.tmpl: Add m68k-est-coff.
+
+Fri Mar 24 13:44:52 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * doc/dejagnu.texi (Posix): Remove 3 words accidentally repeated.
+
+Thu Mar 23 22:12:07 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * aclocal.m4: Split AC_PATH_T* into two pieces, one for headers
+ and one for libraries.
+ * testuite/configure.in: Use CY_PATH_TCLH so we don't get a
+ warning looking for the libraries.
+
+Wed Mar 22 21:04:26 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * testuite/configure.in: Use CY_PATH_TCL so we can set TCL_LIBRARY
+ right and run the selftests with a freshly built expect.
+ * aclocal.m4: New support for autoconf.
+ * configure.in, doc/configure.in: Use AC_PROG_INSTALL.
+ * Makefile.in, doc/Makefile.in: Use mkinstalldirs and a BSD style
+ install program.
+ * mkinstalldirs, install-sh: Borrowed from autoconf to install
+ without using special Cygnus install program.
+ * testsuite/Makefile.in: Take out a bogus dependacy for exp_test.
+
+Tue Mar 21 09:18:15 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/vxworks.exp (vxworks_transform_path): New proc.
+ (vxworks_ld): Clarify return codes. Call vxworks_transform_path
+ on argument. Handle preset passwords. Clean up main loop.
+ (vxworks_spawn): Clarify return codes. Poll board until program
+ exits. Watch for AbOrT abort() marker. Only print remaining buffer
+ contents on failure.
+
+ * contrib/test-tool: Watch for framework errors that prevent
+ $tool.sum from being created.
+
+ * runtest.exp: Treat $DEJAGNU as a global config file (which it is).
+ Don't exit if there isn't a global config file, just warn the user.
+ Error if $DEJAGNU is defined but file doesn't exist.
+
+Sun Mar 19 12:01:06 1995 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * runtest.exp: Don't use site.tmpl as a global config file. It is
+ only useful as an example.
+
+Fri Mar 17 14:41:26 1995 Mike Stump <mrs@cygnus.com>
+
+ * contrib/test-tool: Don't include expected failures in the tests
+ that now fail, but worked before section.
+
+Thu Mar 16 16:52:23 1995 Mike Stump <mrs@cygnus.com>
+
+ * contrib/test-tool: Treat expected failure to unexpected failure
+ as a test that still doesn't work.
+
+Thu Mar 16 11:29:57 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * Makefile.in, example/Makefile.in, example/calc/Makefile.in,
+ testsuite/Makefile.in, doc/Makefile.in: Don't rebuild the
+ configure scripts automatically. Change how recursion works. Add
+ .PHONY targets.
+
+Wed Mar 15 16:07:25 1995 Stu Grossman (grossman@cygnus.com)
+
+ * site.tmpl (m68k-*-coff): Add config for talking to IDP board.
+
+Wed Mar 15 16:32:41 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * Makefile.in, example/Makefile.in, example/calc/Makefile.in,
+ testsuite/Makefile.in, doc/Makefile.in: Add rules to rebuild the
+ configure scripts.
+
+Tue Mar 14 20:24:19 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * configure, example/configure, example/calc/configure,
+ testsuite/configure, doc/configure: New autoconf scripts.
+ * configure.in, example/configure.in, example/calc/configure.in,
+ testsuite/configure.in, doc/configure.in: Rewritten to be autoconf
+ based.
+ * Makefile.in, example/Makefile.in, example/calc/Makefile.in,
+ testsuite/Makefile.in, doc/Makefile.in: Rewritten to use autconf
+ variables.
+
+Fri Mar 10 06:57:53 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * contrib/test-tool: Only call date once and put the result in a
+ variable. This should help behavior when run around midnight.
+
+Tue Mar 7 11:49:59 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * contrib/test-tool (testdir): binutils tests are in `.'.
+
+Tue Feb 28 09:46:42 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * doc/dejagnu.texi (Posix): Clarify discussion of expected
+ failures. Add note about what POSIX requires with respect to
+ UNRESOLVED. Editorial changes (e.g. samp -> code).
+
+Tue Feb 21 22:46:52 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * contrib/test-tool (tool): If we're testing g++, also do a make
+ check for each of libg++, libio, and libstdc++.
+
+Fri Feb 17 14:06:50 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * lib/vxworks.exp (vxworks_ld): Update pattern used to match a
+ successful load.
+
+Fri Feb 10 10:25:53 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * contrib/test-tool: Put errors and warnings into the output.
+
+Mon Feb 6 16:34:51 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * runtest.exp (transform): Return a name based on target_alias,
+ not on target_triplet.
+ (target_alias): Default to target_triplet, not host_triplet.
+
+Thu Feb 2 11:29:49 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * lib/framework.exp (setup_xfail): Clear xfail_prms. Before this
+ change, if setup_xfail was called without a PRMS number,
+ xfail_prms would have a value from the previous (completely
+ unrelated, perhaps even for a different target) setup_xfail.
+
+Tue Jan 24 11:23:40 1995 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * doc/runtest.1: Fix typos and formatting bugs.
+
+Wed Jan 11 13:09:22 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * contrib/test-tool: Treat expected things as "pass" only if
+ -expectedpass given.
+
+Fri Jan 6 10:57:12 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * contrib/test-tool: Pass 3 -v's to runtest. Don't pass -a.
+ Save output in test-$tool.log if -keepoutput given.
+
+Fri Dec 30 12:46:06 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * runtest.exp: catch takes only two arguments; quote accordingly.
+
+Sun Dec 4 01:14:49 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * contrib/test-tool: Handle gas, gld, and binutils.
+ Treat XFAIL as PASS, XPASS as FAIL.
+ Always pass options to `comm' as first argument.
+
+ * lib/remote.exp (*): Rename `retries' to `tries'.
+ (rsh): Mark as deprecated.
+ (rcp_download): Distinguish between failure and success in verbose
+ message. Call proc verbose, don't use global.
+ (rsh_exec): New proc.
+
+ * lib/framework.exp (warning_threshold, perror_threshold): New vars.
+ (record_test): Use them.
+ (reset_vars): Reset them.
+ (get_warning_threshold, set_warning_threshold): New procs.
+
+Mon Nov 14 00:21:05 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/framework.exp: Lots of formatting cleanup.
+ (unknown): Delete unnecessary calls to close_logs, cleanup, exit.
+ (warning, perror): errorInfo is global.
+ (note): New proc.
+
+ * runtest.exp: Document perror vs send_error quandary.
+ (unresolvedcnt): Initialize.
+ (configfile): Use consistently in place of site.exp.
+ (verbose): Call clone_output instead of perror.
+ (load_file): New proc.
+ (argument parsing): Always call send_error for error messages.
+ (all loading of files, except testcases): Consistently exit if tcl
+ error occurs.
+ (all loading of files): Consistently handle errorInfo.
+ (main loop): Delete useless test for $test_name == "".
+
+Wed Nov 2 08:49:06 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/udi.exp (shell_id): Delete.
+ (mondfe): Delete unneeded global's. Delete references to `shell_id'.
+ (mondfe_download): New argument `shell_id'.
+ Move verbose messages to level 2. Tighten up pattern matching on
+ text coming back from target. Don't set `timeout'. Only log
+ expect buffer contents if connection failed.
+ (exit_mondfe): Delete unneeded global's. New argument `shell_id'.
+ (exit_montip): Likewise.
+ * lib/remote.exp (telnet): Use -gl for shell prompt pattern.
+ (rlogin, rsh): Likewise.
+ (exit_remote_shell): Delete nilpotent resetting of `shell_id'.
+
+Fri Oct 28 10:38:41 1994 Rob Savoye (rob@cygnus.com)
+
+ * runtest: Make it an error if runtest.exp doesn't exist.
+
+Fri Oct 21 23:15:27 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * lib/utils.exp (prune_system_crud): Fix ld.so pattern to catch
+ multiple occurrences in a row.
+
+Fri Oct 14 17:26:38 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * runtest.exp (test_name): Delete unnecessary initialization.
+ * lib/framework.exp (clone_output): Reformat comment.
+ (reset_vars): Delete `test_name'.
+ (log_summary): Delete `tool.sum'.
+ (cleanup): Fix comment.
+ (record_test): New (internal) proc (taken from pass/fail).
+ Test `warncnt',`errcnt' before `xfail_flag'.
+ Don't incr `passcnt' prematurely.
+ (pass, fail, xpass, xfail): Call it.
+ (untested, unresolved, unsupported): Don't call xfail.
+ * lib/utils.exp (grep): Don't pass trailing ".*" to regexp.
+ (prune_system_crud): New proc.
+
+Fri Oct 7 19:19:12 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * lib/utils.exp (runtest_file_p): Add support for glob style
+ expressions.
+
+Mon Sep 26 12:03:16 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * runtest: Handle relative paths in $0.
+
+Sun Sep 25 16:51:11 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * runtest.exp: Add more docs on complexity of argument parsing.
+ Parse --host, --objdir, --srcdir, --target, and --verbose before
+ sourcing any config files. Don't let config files override --host
+ and --target. Don't call `verbose' until it's useful. Call
+ config.guess after $objdir/site.exp has been sourced.
+ Delete unused variable `match'. Reword verbose message for --name.
+ Delete existence check of `host_triplet' and `target_triplet'.
+
+Sat Sep 24 14:23:49 1994 Doug Evans (dje@cygnus.com)
+
+ * runtest.exp: Lots of whitespace cleanup. Update copyright.
+ Exit with nonzero status for illegal arguments and if we can't
+ determine the host.
+ (verbose): Add two new arguments (-n, --).
+ * lib/remote.exp: Formatting cleanup.
+ (exit_remote_shell): Add a note about `shell_id'.
+ * lib/udi.exp: Formatting cleanup.
+ (mondfe): Send message when trying to connect.
+ Watch and print more error messages coming from `mondfe'.
+ (mondfe_download): Use "verbose -n" so the pretty dots appear on
+ one line. Fix regexp in "Clear.*BSS section" message.
+
+Tue Sep 13 10:51:47 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * lib/framework.exp (log_summary): Clean up code that handles
+ `testcnt'.
+ (xfail, unsupported, untested): Don't set `exit_status',
+ these aren't errors.
+
+ * runtest.exp: Sort options in --help.
+
+Mon Sep 12 12:25:22 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * runtest.exp: Delete special handling of *.[Ccso] arguments.
+ Accept new argument: foo.exp[=arg(s)].
+ (all_runtests): New global.
+ (runtests): Records arguments for each .exp script.
+ (main test loop): Move setting of srcdir out of loop.
+ Set up `runtests' for each script.
+ * lib/utils.exp (find): Remove unnecessary "\n" in verbose message.
+ (runtest_file_p): New proc.
+
+Wed Sep 7 10:41:33 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * runtest.exp (verbose): Handle leading -'s in message.
+
+Mon Jul 18 11:16:02 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * lib/vxworks.exp: no need to use system, stty is an expect
+ builtin and can be called directly.
+
+Thu Jun 30 15:23:19 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * lib/bug.exp: replaced "rm -foreach" with "rm -f".
+
+Tue Jun 14 12:38:44 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * doc/dejagnu.texi: Fix a few typos and omissions.
+
+Tue Jun 7 13:55:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (mostlyclean, realclean): New targets.
+ * doc/Makefile.in, example/Makefile.in: Likewise.
+ * example/calc/Makefile.in, testsuite/Makefile.in: Likewise.
+
+Mon Apr 25 17:11:30 1994 Bill Cox (bill@cygnus.com)
+
+ * Makefile.in: Add FSF standard comment block.
+ * example/calc/Makefile.in: Define and use EXPECT and
+ RUNTEST variables, so 'make check' will use tools in the
+ current objdir tree if they're present.
+ * lib/remote.exp: Add rcp_download proc, to download a
+ file using remote 'cp'. This was first used for the
+ Lynx cross-host tests.
+ * testsuite/Makefile.in: Update copyright date.
+ * testsuite/runtest.all/options.exp: Update copyright date.
+
+Wed Apr 13 18:05:44 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * runtest: Pass ${1+"$@"} instead of "$@", because many shells
+ incorrectly pass an empty string when no arguments were specified.
+
+Wed Apr 13 11:46:11 1994 Bill Cox (bill@cygnus.com)
+
+ * lib/remote.exp (rcp_download): New proc for using 'rcp'
+ to download (used first for Lynx cross-testing).
+
+Tue Apr 12 13:27:15 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (TCLIBRARY): Define and use.
+
+Wed Mar 9 13:08:54 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * runtest.exp: Misc. formatting/typo cleanups.
+ Process ~/.dejagnurc and $base_dir/site.exp before command line
+ options and clarify search order of all config files.
+ Clean up verbose output for -v, -srcdir, -host, and -target options.
+
+Mon Feb 14 20:37:10 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest.exp: Re-write init file search/loading code.
+
+Tue Feb 8 19:27:07 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest.exp: Move transform from lib/utils.exp so it can be used
+ in config files.
+
+Thu Jan 20 20:05:39 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest.exp: findfile: New proc to be used in config files.
+
+Tue Jan 18 14:46:12 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest.exp: Fix so things don't bomb if whoami doesn't exist.
+
+Mon Jan 17 15:26:50 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/framework.exp (setup_xfail): Re-write so it works correctly
+ with numbers in the config string.
+
+Mon Jan 10 21:29:08 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/framework.exp: Create exp_continue if it doesn't exist.
+ * runtest.exp: Don't try to print errorInfo unless it exists.
+
+Tue Jan 4 16:01:40 1994 Rob Savoye (rob@rtl.cygnus.com)
+
+ * All files: Updated to 1.1.3. This version works with Tcl7.3 and
+ Expect5.2.
+
+Sat Jan 1 19:53:40 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/framework.exp: Fixed log_summary to cleanup all the way.
+ setup_xfail now only use canonical names, catch errors from
+ sourcing $tool_exit and $tool_version.
+ * runtest.exp: Changed the order of sourcing init files. Removed
+ all references to target_alias or host_alias. uses target and host
+ triplet only, uses config.guess to get a host type.
+
+Thu Dec 23 18:26:24 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest (debug): Add an environment variable DEJAGNULIBS to
+ point to where runtest.exp and the rest live.
+
+Wed Dec 15 20:38:49 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest.exp: Fix signal handling so only one ^C is required and
+ it actually exists after printing the summary.
+
+Fri Dec 3 20:58:27 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest.exp: Only consider a TCL_ERROR to be a sign of a problem
+ worth handling. This is when sourcing the test case.
+
+Thu Dec 2 14:16:20 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest.exp: If the verbose level is greater than 2, display
+ debugging output to the screen.
+
+Wed Dec 1 16:04:08 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest.exp: Change error handling to use the return from
+ "catch" rather than depending on errorInfo.
+
+Fri Nov 19 15:08:34 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * site.tmpl: Add LDFLAGS "-r" to vxworks targets.
+
+Mon Nov 15 19:43:28 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/debugger.exp: Add dumpvars which dumps the values of
+ variables specified by a regular expression.Add dumpvars
+ which dumps the body of procedures specified by a regular
+ expression.
+ * Makefile.in: Install site.exp as only config file.
+ * runtest.exp: look for site.tmpl in $srcdir, not site.exp in
+ $objdir.
+ * lib/framework.exp: Make istarget and isnative procs use
+ $target_alias rather than target_triplet.
+ * lib/framework.exp: Make warning and perror keep count. Have
+ pass or fail procs check, and change to unresolved.
+
+Mon Nov 15 10:20:42 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * runtest.exp: corrected a few typos in the comments. Added
+ test for getting user name from the environment first. Now
+ checks for USER and the LOGNAME. If unable to get the logname
+ from the environment, then try whoami and who am i
+
+Thu Nov 4 13:38:32 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest: Use sed rather than expr to get the execution path and
+ the runtest name cause expr doesn't seem to work portably on all
+ machines.
+
+Wed Nov 3 11:27:34 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * Makefile.in, configure.in: Install and build with new config
+ system.
+ * config/mt-*: Set default connection parameters and name
+ transformation.
+ * lib/framework.exp: Change "error" proc to "perror" so I can use
+ Tcl's builtin error handling.
+ * runtest.exp: Re-write error handling so it's now real
+ descriptive with errors and misses nothing. Add support for new
+ config file system. Up version number to 1.1.
+ * runtest: General cleanup. Add support for passing the config
+ name down to runtest.exp.
+
+Sat Oct 16 07:47:38 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * doc/runtest.1: Fix typos in font changes (\fi where \fI was meant).
+
+Wed Oct 13 11:00:55 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * runtest.exp: insert missing space
+ * lib/framework.exp: made proc verbose work as expected. Now will
+ display a message if the level is = or > than the verbose level.
+ * lib/utils.exp: replaced if $verbose>X then { send_user "foo\n" }
+ stuff with the verbose "foo" X proc call
+
+Mon Oct 11 17:11:37 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * runtest.exp: fixed stupid scoping bugs.
+
+Mon Oct 11 16:26:25 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * runtest.exp: fixed "$test_result" bug, and minor reformatting
+ changes to help make the file more readable
+
+Sat Oct 9 18:43:31 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: recognize mips*- instead of mips-
+
+Mon Sep 27 21:09:26 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/bug.exp: Add new file for procs related to "bug" boot
+ monitor.
+
+Wed Sep 22 21:01:43 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * lib/framework.exp: Added m68k-idp-* to target list.
+ * configure.in: Added m68k-idp-* to target list.
+ * config/mt-m68k-abug-aout: Fixed objobjcopy to be objcopy.
+ * config/mt-m68k-abug-coff: Fixed objobjcopy to be objcopy.
+
+Wed Sep 22 12:10:34 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * lib/framework.exp: Folded in test counting mechanism.
+
+Tue Sep 21 19:41:07 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/vxworks.exp: Added a vxworks_spawn proc to execute tasks.
+
+Mon Sep 20 21:28:23 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/vxworks.exp: Prompt user for password if the default login
+ fails.
+
+Mon Sep 13 11:30:37 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * runtest.exp: add global testcnt variable.
+ * lib/framework.exp: add testcnt mechanism. Gives a total
+ number of testcases run in summary. incremented by the
+ pass/fail/etc procs. Also added a "Tool version" string
+ in the summary.
+
+Thu Sep 9 12:37:27 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/utils.exp: Added new procs for pwd{} and absolute{}.
+ * lib/utils.exp: Removed pwd{} proc, added a download{} proc.
+
+Mon Sep 6 12:55:54 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * lib/utils.exp: fixed scoping problem of missing ""'s
+ nasty little bugger. broken since the start.
+
+Fri Sep 3 16:47:07 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * lib/framework.exp: Added support for the h8/500.
+
+Fri Sep 03 10:42:12 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * configure.in: (h8300-*-*) (h8300h-*-*) (h8500-*-*) targets added.
+
+ * config/mt-h8300hms: new file for h8300-hitachi-hms support.
+ * config/mt-h8500hms: new file for h8500-hitachi-hms support.
+ * config/mt-h8300hhms: new file for h8300h-hitachi-hms support.
+
+Tue Aug 31 16:57:12 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/utils.exp: Add a proc to kill process started within the
+ current shell session.
+
+Sun Aug 29 23:10:35 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * lib/remote.exp: wait after exiting the remote shell.
+
+Sun Aug 15 22:27:23 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * lib/framework.exp: Numeric column in summary line up and only
+ print if the sub total is greater than zero.
+
+Tue Jul 20 15:32:51 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * lib/framework.exp: Added code for initial POSIX (PCTS) support.
+
+Mon Jul 19 09:31:48 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * remote.exp: Added a supplied patch to allow specifing a port
+ to the telnet command.
+
+Mon Jul 12 17:54:58 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Remove support for command line options to use "++"
+ as a prefix. Also removed all the old code for the --diff option.
+ The --debug option can now be abbreviated to just -d.
+
+Sun Jul 11 20:49:49 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Exit after printing the version numbers.
+ * lib/utils.exp: Ignore extraneous words in the argument passed.
+
+Thu Jul 8 07:17:17 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * lib/framework.exp: Add support for the h8/300.
+
+Tue Jun 29 15:04:05 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest: Added Dje's patch so the shell stops stripping out the
+ quotes from the command line.
+
+Sun Jun 13 21:05:25 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Remove runtests option. Use any valid file name on
+ the command line instead.
+ * runtest: Add support for the Tcl debugger from the command line.
+
+Thu May 27 20:01:51 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Makefile.in: Make the release image of the testsuites from the
+ special stubs.
+
+Sun May 23 18:40:01 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Don't flag successful return codes as errors.
+ * runtest: Don't look for expect binary anymore.
+
+Tue May 11 17:31:29 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * runtest: Pass "--" to $expectbin.
+
+Fri May 7 08:19:37 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (FLAGS_TO_PASS): Added CC, CFLAGS, LDFLAGS, RUNTEST,
+ RUNTESTFLAGS.
+ * example/Makefile.in (FLAGS_TO_PASS): Was being used, but was
+ never defined.
+ * example/calc/Makefile.in: (CFLAGS): Removed -I arguments.
+ (.c.o): Use required -I arguments.
+ (PROG): Pass CFLAGS to CC.
+
+Tue May 4 22:51:06 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: load_lib exits if it can't find the file. It also
+ finds library files if srcdir = .
+
+Tue Apr 27 08:59:32 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (FLAGS_TO_PASS): Define.
+
+Fri Apr 23 13:12:27 1993 Mike Werner (mtw@deneb.cygnus.com)
+
+ * lib/framework.exp:
+ Made cosmetic changes to procedure "diff_logs".
+
+Wed Apr 21 18:05:30 1993 Rob Savoye (rob@cygnus.com)
+
+ * runtest: Looks in $rootme/../../expect and $rootme/../expect and
+ if there is one, it uses that to run runtest.exp.
+
+Wed Apr 21 12:34:10 1993 Mike Werner (mtw@deneb.cygnus.com)
+
+ * runtest.exp:
+ Changed how -diff and -mail affect the printing and
+ mailing of logs.
+ * lib/framwork.exp:
+ Changed format of the output of the diff log. Made
+ minor changes to "diff_logs" to acommodate the changes
+ to runtest.exp (above).
+
+Mon Apr 19 18:45:10 1993 Mike Werner (mtw@deneb.cygnus.com)
+
+ * runtest.exp:
+ Added the ability to specify, as an option parameter, the name
+ of the previous summary log to diff against. Added a call to
+ "close_logs" to the signal handlers. Enabled -mail option.
+ Cleaned up some comments.
+ * lib/framework.exp:
+ Added procedure "mail_file" for mailing test log summaries.
+ Removed support for automatically generating log file names with
+ embedded time/date stamps. Cleaned up "diff_logs".
+
+Sun Apr 18 19:54:17 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Fixed so signal trapping now works again. Cleaned
+ up configuration stuff and how it finds the site.exp file.
+ * Makefile.in: Remove unneeded macro definitions.
+
+Fri Apr 16 15:11:52 1993 Mike Werner (mtw@deneb.cygnus.com)
+
+ * lib/framework.exp:
+ Added the procedures "diff_logs", "open_logs", and "close_logs".
+ Changed the name of the procedure "sum" to "log_summary".
+ Changed the name of the procedure "alldone" to "cleanup".
+ "Cleanup", formerly "alldone", no longer exits; runtest
+ explicitly exits.
+ * runtest.exp:
+ Now calls "open_logs", "close_logs", and "diff_logs" to do the
+ respective goodies. We also now make explicit calls to "cleanup"
+ and exit. Enabled --diff command line option which when used
+ will cause a call to the procedure "diff_logs".
+
+Sun Apr 11 17:17:20 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Makefile.in: Removed runtest target. Cleaned up install
+ procedure.
+ * runtest.exp: No longer uses --config option.
+ * runtest: New bourne shell script to start runtest.exp.
+
+Thu Apr 8 18:12:24 1993 Mike Werner (mtw@deneb.cygnus.com)
+
+ * lib/utils.exp: the list of directories returned by getdirs now
+ contains only directories that allow read permission.
+
+Wed Apr 7 18:30:45 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Now looks for init files by ${target_os}.exp as
+ well as ${target_os}-${tool}.exp.
+ * config/mt-*: Added macros for COPY and DEMANGLE, new
+ binutils.
+
+Fri Apr 2 12:23:22 1993 Mike Werner (mtw@deneb.cygnus.com)
+
+ * lib: relocated old-dejagnu.exp to devo/gcc/testsuite/lib
+
+Mon Mar 29 14:59:23 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * framework.exp: Added tests for spectra.
+
+Thu Mar 25 14:16:54 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Fixed command line option processing. Now
+ things like CFLAGS="-v -a" should work.
+
+Thu Mar 25 12:40:50 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * lib/udi.exp (mondfe): Return -1 on failure. Don't remove *_soc
+ files.
+ (mondfe_download): Fixed invalid expect usage which could never
+ have worked.
+
+Wed Mar 24 14:11:46 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Added --target and --host for specifying the config
+ strings. The old --target is now --name.
+ * lib/framework.exp: Moved all the host/target naming stuff from
+ runtests.exp.
+ * runtest.exp: Fixed bug so CFLAGS="-v" works. I changed the way
+ the verbose pattern works in $argv.
+
+Tue Mar 23 08:48:09 1993 Fred Fish (fnf@cygnus.com)
+
+ * configure.in: Use host makefile fragment config/mh-sysv4
+ on *-*-sysv4* configurations.
+ * config/mh-sysv4: New host makefile fragment for SVR4 systems.
+
+Mon Mar 22 23:26:58 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add dvi, check and installcheck targets
+
+ * doc/Makefile.in: add defines for MAKEINFO, TEXI2DVI
+
+Sun Mar 21 17:44:11 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: New command line option --ignore. Ignore any tests
+ specified this way.
+ * lib/framework.exp: Now uses puts send_error of send_user for
+ some procs. Now warnings and errors go to stderr, and can
+ be redirected. They still go to the logs.
+
+Tue Mar 16 18:07:56 1993 Rob Savoye (rob at poseidon.cygnus.com)
+
+ * runtest.exp: Finds site.exp file with new install.
+ * Makefile.in: Installs much better.
+
+Tue Mar 9 08:17:04 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (MAKEOVERRIDES): Set to be empty.
+
+Mon Mar 8 17:40:41 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * lib/vrtx.exp: Spectra shell procedures.
+
+Mon Mar 8 19:26:41 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in, config/{mt-a29k-udi, mt-frwcom-aout, mt-i386-aout,
+ mt-i960-nindy, mt-i960-vx, mt-m68k-abug-aout, mt-m68k-abug-coff,
+ mt-m68k-aout, mt-m68k-coff, mt-m68k-vx, mt-mips, mt-sparc-aout,
+ mt-sparc-vx, mt-sparclite} (GDBFLAGS): The default is -nx, to not
+ load whatever random '.gdbinit' file might happen to be in the
+ directory where the dejagnu tests are run. If tests require
+ a specific init file, they should load them explicitly.
+
+Sun Mar 7 15:16:42 1993 Rob Savoye (rob@cygnus.com)
+
+ * runtest.exp, Makefile.in: Now sets default for objdir.
+
+Sun Feb 28 15:30:00 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Now find site.exp in a path list. Also now supports
+ using a short config file in each directory to override options.
+ * Makefile.in, configure.in: Removed link for lib directory. Added
+ doc as a subdir, runtest and site.exp now built as a dependancy,
+ rather than by configure.
+
+Thu Feb 25 11:07:30 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/mt-mips: New file for mt-idt-ecoff target.
+ * configure.in (mips-idt-ecoff): New target; uses mt-mips.
+ * runtest.exp: If mips-idt-ecoff, set target_abbrev to mips.
+ * runtest.exp: Print any error produced by ${tool_init}.
+ * lib/remote.exp (kermit): Made work.
+
+Mon Feb 22 17:11:18 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * configure.in: Removed unneccesary code from configure.in
+
+Mon Feb 22 07:54:03 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * devo/dejagnu: made modifications to framework, etc., to allow
+ it to work properly given the reorganization of deja-gnu and the
+ relocation of the testcases from deja-gnu to a "tool" subdirectory.
+
+Sun Feb 21 11:15:22 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * devo/dejagnu: Initial creation of devo/dejagnu.
+ Migrated dejagnu testcases and support files for testing software
+ tools to reside as subdirectories, currently called "testsuite",
+ within the directory of the software tool. Migrated all programs,
+ support libraries, etc. beloging to dejagnu proper from
+ devo/deja-gnu to devo/dejagnu. These files were moved "as is"
+ with no modifications. The changes to these files which will
+ allow them to configure, build, and execute properly will be made
+ in a future update.
+
+Wed Feb 17 10:51:13 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t02/whatis.exp, gdb.t03/ptype.exp: Remove expected failures
+ for mips-*-* that now work (gcc was fixed to distinguish int and
+ long in COFF debugging output).
+
+Tue Feb 16 17:31:54 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t21/demangle.exp (test_gnu_style_demangling,
+ test_cfront_style_demangling): Add tests for some cases that
+ involve const that were previously broken.
+
+Mon Feb 15 14:09:33 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t00/default.exp (attach, core-file, r, run, target core):
+ Add more error messages used by cross gdb.
+
+Fri Feb 12 11:17:05 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t21/demangle.exp: Add yet more cfront demangling tests.
+
+Thu Feb 11 12:23:53 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t21/demangle.exp: Add new demangling tests, for various
+ gnu and cfront patterns, that match recent bug fixes.
+ * configure.in (configdirs): Add gdb.t23.
+ * gdb.t23/ {Makefile.in, configure.in, in-gdbme.cc,
+ templates.exp}: New test case to testing templates. Currently
+ contains just the framework, but no tests.
+ * gdb.t21/demangle.exp (demangle): Fix proc so that demangling
+ failures don't trigger two failure reports, one erroneously
+ indicating the cause as a timeout.
+ * gdb.t21/demangle.exp (various): Print number of correct
+ demanglings when suppressing remaining tests.
+ * gdb.t21/demangle.exp (test_cfront_style_demangling):
+ New test for cfront style demangling.
+ * gdb.t21/demangle.exp (do_test): Call cfront style demangling
+ test.
+
+Wed Feb 10 18:28:40 1993 Stu Grossman (grossman at cygnus.com)
+
+ * gdb.t11/list.exp (list filename:function; wrong filename not
+ rejected): Revise expected failure profile. All systems are
+ expected to fail.
+
+Mon Feb 8 21:25:47 1993 Stu Grossman (grossman at cygnus.com)
+
+ * gdb.t00/help.exp (help set): Look for prompt on next line to
+ prevent timeout error.
+ * gdb.t11/list.exp (list filename:function; wrong filename not
+ rejected): Document expected failure for general case. Set
+ expected failure for sunos.
+
+Wed Feb 3 09:42:14 1993 Mike Stump (mrs@rtl.cygnus.com)
+
+ * g++.niklas, configure.in: Add some test cases from Niklas.
+
+Mon Feb 1 18:40:27 1993 Mike Werner (mtw@rtl.cygnus.com)
+
+ * code_quality.exp, compile.exp, execute.exp, noncompile.exp,
+ special.exp, unsorted.exp: added "unset subdir_created".
+
+Fri Jan 29 14:20:11 1993 Mike Werner (mtw@rtl.cygnus.com)
+
+ * Makefile.in (install): changed the sed command, which creates
+ $(target-alias)-runtest, to have the installed
+ $(target-alias)-runtest call $(bindir)/runtest.exp instead of
+ $(srcdir)/runtest.exp . This worked earlier but was broken by a
+ change to $(EXPECT) .
+
+Thu Jan 28 14:24:56 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (info, install-info): Deleted extraneous @'s.
+
+Thu Jan 28 08:29:57 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (CC_FOR_TARGET, CFLAGS, CXX_FOR_TARGET, CXXFLAGS,
+ CXX, GCC_FOR_TARGET, FLAGS_TO_PASS): Match definitions in
+ upper level devo/Makefile.in.
+ * config/mt-unix (EXPECT): Remove definition, it is set by
+ Makefile.in to use the latest built version.
+ * Makefile.in (CHILL_FOR_TARGET, CHILLFLAGS, CHILL_LIB): Match
+ definitions in upper level devo/Makefile.in.
+
+Wed Jan 27 21:48:15 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (clean): Test if directory exists before trying
+ to run submake in it.
+ * gdb.t00/teststrategy.exp: Add cases that work when gdb is
+ compiled with ALIGN_STACK_ON_STARTUP defined. Fix "print foo"
+ expected output to match current gdb. Fix tests for finding
+ pathname to gdb executable to use the TCL "file" command.
+ * gdb.t20/classes.exp: Change error when binfile does not
+ exist to be a simple fail instead.
+ * tcl.tests/Makefile.in (tcltest): Use CC_FOR_TARGET.
+ * tcl.tests/Makefile.in (Makefile): Add target.
+ * gdb.t30/chexp.exp: Set up expected failure for printing
+ uninitialized convenience variables.
+ * gdb.t31/chillvars.exp: Set up expected failure for references
+ to string4, which chill compiler doesn't handle yet. Add tests
+ for string repetition operator.
+ * gdb.t31/in-gdbme.ch: Comment out string4, not handled yet.
+
+Mon Jan 25 15:12:41 1993 Mike Werner (mtw@rtl.cygnus.com)
+
+ * gcc.unsorted/unsorted.exp
+ gcc.special/special.exp
+ gcc.noncompile/noncompile.exp
+ gcc.execute/execute.exp
+ gcc.compile/compile.exp
+ gcc.code_quality/code_quality.exp:
+ Modified to properly find source code for the test cases,
+ create the appropriate subdirectories to hold the compiled
+ testcases, and delete the subdirectories when finished.
+
+Thu Jan 21 18:05:54 1993 Mike Werner (mtw@rtl.cygnus.com)
+
+ * Makefile.in: cosmetic changes.
+ * gcc.code_quality/code_quality.exp: repalced a "source xxx"
+ with a "load_lib xxx".
+ * gcc.compile/compile.exp: replaced a "source xxx" with a
+ "load_lib xxx".
+
+Thu Jan 21 08:03:16 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (CC, CXX): Change to CC_FOR_TARGET, CXX_FOR_TARGET.
+ * Makefile.in (FLAGS_TO_PASS): Add AR_FOR_TARGET, CC_FOR_tARGET
+ CXX_FOR_TARGET, RANLIB_FOR_TARGET.
+ * {gdb.t00, gdb.t01, gdb.t02, gdb.t03, gdb.t04, gdb.t05, gdb.t06,
+ gdb.t07, gdb.t08, gdb.t09, gdb.t10, gdb.t11, gdb.t12, gdb.t13,
+ gdb.t15, gdb.t16, gdb.t20, gdb.t21, gdb.t22}/Makefile.in:
+ Add Makefile target, dependencies, and rules, replace CC with
+ CC_FOR_TARGET and CXX with CXX_FOR_TARGET.
+ * gdb.t03/ptype.exp: Add tests for string constants and array
+ constants.
+ * gdb.t16/printcmds.exp: Add tests for string constants and array
+ constants.
+ * Makefile.in (CHILL): Change to CHILL_FOR_TARGET.
+ * Makefile.in (FLAGS_TO_PASS): Add CHILL_FOR_TARGET.
+ * {gdb.t30, gdb.t31}/Makefile.in: Add Makefile target, dependencies,
+ and rules. Replace CHILL with CHILL_FOR_TARGET.
+ * gdb.t31/chillvars.exp: Set print address off, add tests for
+ strings.
+ * gdb.t31/in-gdbme.ch: Add some initialized string variables.
+
+Tue Jan 19 14:07:38 1993 Mike Werner (mtw@rtl.cygnus.com)
+
+ * Makefile.in: corrected anchoring error in sed script, within
+ the "install" rule, which created the the file {mach}-runtest
+
+Fri Jan 15 21:16:51 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t04/setvar.exp: Minor changes to match current syntax for
+ printing array-of-char in string form.
+ * gdb.t16/printcmds.exp: Fix one test case to match bug fix.
+ * gdb.t30/chexp.exp: Disable tests that check for control
+ sequence form of character literals, not supported in GNU Chill.
+
+Wed Jan 13 21:33:05 1993 Mike Stump (mrs@cygnus.com)
+
+ * doc/dejagnu.texi, Makefile.in: Change .../gcc to .../xgcc.
+
+Wed Jan 13 08:21:00 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (CHILLFLAGS): Add appropriate -L arg to find
+ libchill.a, if a freshly built one exists.
+ * gdb.t31/Makefile.in (LIBCHILL, LIBS): Define local defaults.
+
+ * Makefile.in (runtest): Fix to properly find freshly built
+ "expect" binary.
+
+Tue Jan 12 12:51:46 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (CPLUS): Remove macro.
+ * Makefile.in (CC, CXX, GDB, EXPECT): Use freshly build binaries
+ if available.
+ * Makefile.in (CFLAGS, CXXFLAGS, GDBFLAGS): Provide default
+ flags to go with CC, CXX, and GDB respectively.
+ * Makefile.in (FLAGS_TO_PASS): Add CXX, CXXFLAGS, LINK.
+ * Makefile.in (info, subdir_do, subdirs): Use rootme and
+ rootsrc to find tool directories, use FLAGS_TO_PASS.
+ * Makefile.in (runtest): Use new EXPECT macro.
+ * Makefile.in: Other minor macro rearrangements.
+ * config/{abug-g++.exp, aout-g++.exp, coff-g++.exp, mt-a29k-udi,
+ mt-i960-nindy, mt-i960-vx, mt-m68k-abug-aout, mt-m68k-abug-coff,
+ mt-m68k-aout, mt-m68k-coff, mt-m68k-vx, mt-unix, nind-g++.exp,
+ udi-g++.exp, unix-g++.exp, vx-g++.exp}, doc/deja-gnu.texi,
+ g++.mike/{misc2.exp, misc8.exp, misc9.exp}, g++.old-deja/tests/
+ g++.sun/g++.frag/1076585.C, gdb.t20/Makefile.in, gdb.t21/
+ Makefile.in, gdb.t22/Makefile.in, lib/mike-g++.exp:
+ Use CXX rather than CPLUS, CPLUSPLUS, or C++, use CXXFLAGS
+ rather than CFLAGS or CPLUSFLAGS or C++FLAGS.
+ * Makefile.in (CHILL): Use freshly built binaries if available.
+ * Makefile.in (CHILLFLAGS): Provide default flags for CHILL.
+ * Makefile.in (FLAGS_TO_PASS): Add CHILL, CHILLFLAGS.
+
+Mon Jan 11 18:02:48 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * expect.tests/exp-after.test, exp-before.test, log-file.test,
+ send-exp.test, spawn.test: Test case for expect tests.
+ * expect.tests/exp-test.exp: Test driver for expect tests.
+ * expect.tests/Makefile.in, configure.in: Configure
+ support.
+ * expect.tests/exp-test.c: Simple interactive program for expect
+ tests.
+ * expect.tests: New directory.
+ * config/unix-expect.exp: New tool.
+
+Fri Jan 8 16:41:51 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/udi-gdb.exp (gdb_start): don't require "UDI socket" in
+ the startup message.
+
+Wed Jan 6 08:53:08 1993 Fred Fish (fnf@cygnus.com)
+
+ * {gdb.t01, gdb.t02, gdb.t03, gdb.t04, gdb.t05, gdb.t06, gdb.t07,
+ gdb.t11, gdb.t12}/Makefile.in: Add explicit "all" target to
+ Makefiles missing it, supply explicit rules to make object files
+ from source files to subvert bug in GNU make that assumes gcc
+ style "-c -o" handling.
+ * tcl.texts/Makefile.in: Look in tcl sibling dir for library,
+ rather than picking up whatever happens to be installed.
+ * config/unix-gdb.exp (gdb_start): Temporarily increase timeout
+ by 60 seconds to accommodate heavily loaded or otherwise slow
+ systems during gdb startup. A similar fix was also installed in
+ a 14-Dec change, but mysteriously disappeared.
+ * gdb.t31/chillvars.exp: Go ahead and try to run test on non-
+ DWARF systems, as long as there is a chill executable to test.
+
+Mon Jan 4 17:19:08 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t30/chexp.exp (test_print_accept, test_print_reject):
+ Convert to varargs function.
+ * gdb.t30/chexp.exp (test_arithmetic_expressions): New tests.
+ * gdb.t31/Makefile.in (CHILL, CHILLFLAGS): Provide defaults.
+ * gdb.t31/chillvars.exp (test_UBYTE): Remove FIXME`s, fixed.
+ * gdb.t31/in-gdbme.ch (scalar_arithmetic, write_arrays,
+ booleans): Add procs for testing.
+ * lib/gdb.exp (runto): Don't expect hex format for breakpoint
+ address.
+
+Sun Jan 3 14:24:53 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t30/chexp.exp (test_float_literals_accepted): Use
+ literals in comparisons, rather than printing their values
+ directly. Avoids spurious failures due to conversion or
+ representational differences between machines types.
+
+Sat Jan 2 22:56:53 1993 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t30/chexp.exp (test_float_literals_accepted): New test.
+ * gdb.t31/in-gdbme.ch (testvars): Add floating point assigns.
+
+Thu Dec 31 08:30:08 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/help.exp: Track recent gdb changes in description
+ of "set" command for assigning expression values to variables.
+
+Wed Dec 30 13:17:36 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/gdbvars.exp: New tests for convenience variables and
+ history value list.
+ * gdb.t30/chexp.exp: Add tests for convenience variables and
+ history value list.
+
+ * config/unix-gdb.exp (gdb_exit): Put escaped quotes around
+ command to send to gdb inside a catch. Otherwise the newline
+ at the end of the quit command gets eaten.
+ * lib/gdb.exp (gdb_test): Replace bogus message about the
+ gdb process no longer existing with a error that reports the
+ real reason for the send command failing. Remove use of
+ "$command" in the expect pattern, since it may contain sequences
+ that look like regular expressions but should not be interpreted
+ as regular expressions.
+
+Tue Dec 29 22:49:56 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: define FLAGS_TO_PASS
+
+Sun Dec 27 11:52:45 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * lib/udi.exp: Fixed so that it downloads stably. Added better
+ error trapping. Works with simulator or demo board.
+ * runtest.exp: Cleaned up handling of signals during the init
+ phase.
+ * lib/old-dejagnu.exp: Fixed bug that made $CFLAGS accumulate
+ repititions of the same flags.
+ * runtest.exp: cleans up temp file better.
+ * config/udi-g++.exp: Minor bug fixes. Doesn't die it it can't
+ connect now.
+
+Sat Dec 26 19:21:14 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * config/vx-gdb.exp: Now it exits if it can't connect to the
+ target.
+ * most everything: Made *all* (whew) error and warning messages
+ use new procedures. These messages are controlled by --all rather
+ than --verbose.
+ * lib/framework.exp: Fixed clone_output so everything gets sent to
+ the correct files. Also added a procedure for standard warning and
+ error messages.
+
+Sat Dec 26 11:16:55 1992 Fred Fish (fnf@cygnus.com)
+
+ * tcl.tests/tcltest.c (Tcl_DumpActiveMemory): Remove extern
+ declaration, which is now incompatible with tcl.h.
+
+
+Tue Dec 22 22:36:42 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (subdir_do): Remove blank line after target,
+ that gives older makes indigestion.
+ * configure.in: When running "make", use environment definition
+ of MAKE if one exists, default to "make" if not in environ.
+ * gdb.t21/cplusfuncs.exp: Update regular expressions for matching
+ operators to track gdb C++ demangling fixes.
+
+Mon Dec 21 22:32:46 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t31/in-gdbme.ch (bytetable3, bytetable4): Reduce ranges
+ of array dimensions to something more managable for explicit
+ initialization. Add initializers.
+ * gdb.t31/in-gdbme.ch (inttable1, inttable2, longtable1,
+ longtable2): Fix typo, initializers were intended to be
+ sequential values for easy identification.
+ * gdb.t31/chillvars.exp: Update to track changes in in-gdbme.ch.
+
+Mon Dec 21 19:48:42 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Has new option to specify the target's
+ configuration string. Only used by runtest.
+ * g++.other/*.exp: Now use procs from mike-g+.exp.
+ * g++.mike/*.exp: Now use procs from mike-g+.exp.
+ * Makefile.in: Now has install & uninstall targets.
+ * lib/prebase, postbase.exp: Merged into lib/mike-g++.exp and made
+ into procs.
+ * runtest.exp: Traps error when trying to test a tool that does't
+ have support.
+ * lib/framework.exp: Contains all the procs from runtest.exp.
+ These are basically the guts of the testing framework.
+ * runtest.exp: Moved all procs to a library file.
+
+Sat Dec 19 16:50:46 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Upped version number to 0.8.1
+ * lib/nm-defs.exp: Support procs for nm tests.
+ * nm.all/nm.exp: Now uses a generic nm testing proc.
+ * nm.all/Makefile.in: Changes the path for the linker script so it
+ won't produce srecs.
+ * nm.all/configure.in: Copies linker script for m68k-abug and
+ edits out OUTPUT_FORMAT line.
+ * config/*-nm.exp: They only contain stubs calling the procs in
+ nm-defs.exp.
+
+Fri Dec 18 18:13:15 1992 Rob Savoye (rob@cygnus.com)
+
+ * gcc.*/*.exp: Doesn't change into the subdir.
+ * lib/c-torture.exp: Adds subdir to path for objects and binaries
+ * runtest.exp: Added tests for targetname and connectmode when
+ using a MVME m68k board.
+ * configure.in: Now tests for m68k-abug-[coff|aout].
+ * config/mt-m68k-abug: Now a mt-m68k-abug-coff and
+ mt-m68k-abug-aout version so either tool chain can be used to
+ produce the srecords.
+
+Fri Dec 18 10:26:46 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (.NOEXPORT): Add for GNU make. Don't pass defines
+ with pathnames relative to this directory to submakes.
+ * gdb.t00/{default.exp, help.exp}: Update to track latest gdb
+ changes.
+ * gdb.t30/chexp.exp: Update to track latest gdb changes.
+ * gdb.t31/{in-gdbme.ch, chillvars.exp}: Add some arrays and
+ tests for arrays, update to track latest gdb changes.
+
+Mon Dec 14 18:42:58 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/unix-gdb.exp (gdb_start): Temporarily set timeout up
+ to 60 seconds to accommodate heavily loaded or otherwise slow
+ systems during gdb startup.
+
+Mon Dec 14 12:16:27 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t11/list.exp, gdb.t16/printcmds.exp: added expected failures
+ for i960-*-*.
+ * gdb.t15/funcargs.exp: increase timeout for *-*-vxworks.
+
+Fri Dec 11 21:15:07 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t16/{in-gdbme.c, printcmds.exp}: Add some tests for
+ printing the contents of multidimensional arrays.
+
+Wed Dec 9 13:18:39 1992 Michael Werner (mtw@rtl.cygnus.com)
+
+ * tcl.test/tcl-test.exp:
+ changed the comparison that looks for the end-of-test return
+ string, "%", from the tcl interpreter, tcltest, to check for
+ "^%$" instead of just "%".
+
+Tue Dec 8 13:49:18 1992 Fred Fish (fnf@cygnus.com)
+
+ * chillvars.exp: Only run the tests if the target is an
+ SVR4 target (which presumes DWARF format). They are only
+ expected to work right now for targets that use DWARF.
+
+Tue Dec 8 13:42:45 1992 Michael Werner (mtw@rtl.cygnus.com)
+
+ * removed accidental change to config/unix-tcl.exp that
+ occurred during last check-in.
+
+Tue Dec 8 13:21:45 1992 Michael Werner (mtw@rtl.cygnus.com)
+
+ * tcl.test/configure.in
+ corrected error in "files=" line; changed "defs.h" to "defs".
+
+Sun Dec 6 22:00:06 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * config/*-nm: Fixed nm_version.
+ * configure.in: Doesn't configure tcl tests for a cross test.
+
+Sat Dec 5 14:13:15 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * doc/dejagnu.l, dejagnu.texi: Added documentation for --baud
+ option.
+ * runtest.exp: Added --baud option to spcify the baud rate for a
+ serial connection.
+
+Fri Dec 4 07:00:45 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t31/chillvars.exp: Add new tests, fix expected results
+ for some existing ones.
+
+Thu Dec 3 12:28:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t20/{classes.exp, inherit.exp, misc.exp},
+ gdb.t21/cplusfuncs.exp, gdb.t22/virtfunc.exp: Downgrade
+ missing test executables from ERROR to just FAIL.
+ * gdb.t30/chillvars.exp: Downgrade missing test executables
+ from ERROR to just FAIL. Start adding some real tests.
+ * gdb.t30/in-gdbme.ch: Start adding some initializations of
+ fundamental type variables.
+
+Wed Dec 2 11:46:04 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * runtest.exp (setup_xfail): only set xfail_prms if xfail_flag is
+ set.
+ * gdb.t11/list.exp, gdb.t12/scope.exp, gdb.t15/funcargs.exp: more
+ mips-*-* expected failures.
+
+Wed Dec 2 11:39:28 1992 Fred Fish (fnf@cygnus.com)
+
+ * lib/gdb.exp (gdb_reinitialize_dir): New utility proc.
+ * gdb.t03/ptype.exp, gdb.t06/break.exp, gdb.t07/watchpoint.exp,
+ gdb.t08/opaque.exp, gdb.t09/corefile.exp, gdb.t11/list.exp,
+ gdb.t12/scope.exp, gdb.t13/bitfields.exp, gdb.t15/funcargs.exp,
+ gdb.t16/printcmds.exp, gdb.t20/{classes.exp, inherit.exp,
+ misc.exp}, gdb.t21/{cplusfuncs.exp, demangle.exp},
+ gdb.t22/virtfunc.exp: Use new gdb_reinitialize_dir tcl proc.
+ * gdb.t20/{classes.exp, inherit.exp, misc.exp},
+ gdb.t21/{cplusfuncs.exp, demangle.exp}, gdb.t22/virtfunc.exp:
+ Suppress tests if executable not found.
+ * Makefile.in: Add CHILL and CHILLFLAGS as things to pass
+ to recursive makes.
+ * gdb.t31/{configure.in, Makefile.in, in-gdbme.ch, chillvar.exp}:
+ New directory of chill tests.
+ * config/mt-unix (CHILL, CHILLFLAGS): New defs for chill
+ compiler name and flags to pass to compiler.
+ * configure.in (configdirs): Add gdb.t31.
+ * gdb.t30/chexp.exp: Don't need to load a gdb.
+
+Mon Nov 30 20:38:00 1992 Fred Fish (fnf@cygnus.com)
+
+ * runtest.exp (setup_xfail, clear_xfail): Modify to accept
+ multiple arguments and examine each one for a valid config
+ triplet or a prms id.
+ * gdb.t03/ptype.exp: Clear xfail flag for ptype of unnamed
+ enumeration members for SVR4 systems (presumes DWARF).
+ * gdb.t11/list.exp: Set up xfail flag for tests that are
+ expected to fail on SVR4 systems (presumes DWARF).
+
+Mon Nov 30 17:32:36 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t00/default.exp (set write, show write): don't leave it at
+ set write on, because that causes debugging problems in later
+ testing on Ultrix.
+
+Mon Nov 30 17:18:32 1992 Rob Savoye (rob@cygnus.com)
+
+ * runtest.exp: Now uses find proc to recursively find all expect
+ file.
+
+Mon Nov 30 11:55:36 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t20/inherit.exp: Recognize a '.' as the g++/gdb
+ CPLUS_MARKER, rather than just '$'. This particular piece of
+ brain damage is spreading like ooze; gcc, gdb, and libiberty are
+ all infected as well.
+
+Mon Nov 30 11:23:42 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: use mt-i960-nindy, not mt-i960-nind.
+ * gdb.t02/whatis.exp, gdb.t03/ptype.exp, gdb.t08/opaque.exp,
+ gdb.t09/corefile.exp, gdb.t11/list.exp, gdb.t12/scope.exp: add
+ expected failures for mips-*-*.
+
+Sun Nov 29 23:10:43 1992 Mike Stump (mrs@rtl.cygnus.com)
+
+ * prebase.exp (not_compiler_output): Change from looking for
+ Segmentation Violation to Internal compiler error, as the compiler
+ no longer issues the former.
+
+Sun Nov 29 15:16:06 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * config:/vx-g++.exp, udi-g++.exp: Replaced with gcc init code.
+ * runtest.exp: Now executes recursively any *.exp files.
+ * lib/old-dejagnu.exp: proc old-dejagnu executes tests that are
+ supposed to.
+ * g++.old-deja/old-deja.exp: Recursively get all the C code in a
+ subdirectory tree.
+ * lib/utils.exp: New file, contains utility procs grep, find,
+ and which.
+ * runtest.exp: Applied Fred's patch for the output.
+
+Sun Nov 29 08:51:15 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t22/virtfunc.exp: Make "ptype VA" an expected failure.
+ * runtest.exp: Fix a couple of minor formatting glitches.
+ * gdb.t30/chexp.exp(test_print_reject): Add another possible
+ failure expect string.
+
+Sat Nov 28 21:09:33 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * g++.old-deja/tests: New directories for C++ code from the old
+ style DejaGnu tests.
+ * g++.old-deja/old-deja.exp: New file for running the old style
+ DejaGnu tests.
+ * lib/old-dejagnu.exp: New file. Support procs for running the
+ old style DejaGnu tests.
+
+Wed Nov 25 08:05:59 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t16/printcmds.exp: Set up expected failure for
+ "p 123DEADBEEF". Gdb thinks this is a floating point number.
+
+Mon Nov 23 12:14:43 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/mt-i960-vx: set LIBS to -lgcc, not -lg (lost when file
+ was renamed).
+ * gdb.t07/watchpoint.exp: Added expected failures for Sun3.
+
+Fri Nov 20 15:39:07 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t00/default.exp (info set): don't get fooled by the prompt
+ in the output.
+ (detach): gdb_test can not include $prompt in the expected result.
+ * gdb.t00/teststrategy.exp (backtrace): don't insist on main being
+ at level 7; any level is acceptable.
+
+Sun Nov 22 14:44:35 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * lib/remote.exp: Added proc for kermit.
+
+Fri Nov 20 11:23:26 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/unix-gdb.exp (gdb_exit): Add explicit close as
+ workaround for expect bug that slowly consumes file descriptors.
+ * gdb.t22/virtfunc.exp: When gdb dumps core, start a new one
+ for the benefit of later tests that expect a gdb to be currently
+ running. This is a kludge.
+ * configure.in (configdirs): Add gdb.t16.
+ * gdb.t16/{Makefile.in, configure.in, in-gdbme.c, printcmds.exp}:
+ New test for exhaustive printing of all ASCII characters and
+ substrings, and a few tests for printing of integral values.
+ * gdb.t30/chexp.exp: Add tests for character literals.
+
+Thu Nov 19 17:45:53 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * lib/udi.exp: New procs for udi shells.
+ * config/udi-gcc.exp: Made gcc_load
+ * config/udi-gdb.exp: Made gdb_start, gdb_load gdb_exit
+ * gdb.t00/default.exp: Lots of ugly hacks cause many default
+ actions kill the UDI connection. Lookfor for new xfails. Sigh...
+ * config/*-gdb.exp: Use which in gdb_version.
+ * lib/gcc.exp: Use which in default_gcc_version.
+ * runtest.exp: New proc which that does a path lookup.
+
+Wed Nov 18 17:08:08 1992 Michael Werner (mtw@rtl.cygnus.com)
+
+ * Updated c torture tests from the package c-torture-1.7
+ The test in: gcc.code_quality
+ gcc.compile
+ gcc.execute
+ gcc.noncompile
+ gcc.unsorted
+ were updated. Existing tests in a given directory that had
+ changed or that were not in 1.7 were moved into a subdirectory
+ called "old-tests". 1.7 had a new directory called "special",
+ the contents of which were placed in deja-gnu/gcc.special .
+ Also, deleted from a prior Changelog entry was the erroneous
+ statement of the removal of support in gcc for the recognition
+ of the ".C" extension.
+
+Wed Nov 18 13:36:43 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t30/chexp.exp: Change print tests to include explicit
+ print command so we can also include formats.
+
+Wed Nov 18 12:32:53 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: never change target_os; we need to be able to
+ check it in istarget tests.
+ * config/unix-gdb.exp (gdb_exit): the string match test was the
+ wrong way around; also, call close to try to avoid the file
+ descriptor leak in some versions of expect.
+ * teststrategy.exp: added some expected failures for Sun4 and
+ Solaris, and changed the core dump test to accept a timeout (no
+ response from gdb) if a core file was actually created.
+ * gdb.t02/whatis.exp, gdb.t03/ptype.exp, gdb.t05/expr.exp,
+ gdb.t15/funcargs.exp: added PRMS bug numbers for expected i960
+ failures.
+ * gdb.t10/crossload.exp (bfddefault): corrected error message.
+ (whole file): changed fixme handling to use setup_xfail.
+
+Tue Nov 17 09:14:11 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * runtest.exp (setup_xfail): take optional second argument which
+ is the PRMS bug number.
+ (pass, fail): use it.
+ * gdb.t00/default.exp (accept): gdb 4.7 returns a different
+ string.
+ (show): don't get fooled by the prompt in the output.
+ * gdb.t12/scope.exp: RS/6000 expects to fail print 'file'::var.
+ * gdb.t21/cplusfuncs.exp: use setup_xfail rather than FIXME.
+
+Mon Nov 16 12:38:47 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t10/Makefile.in (EXECUTABLES): Add sparc-elf.
+ * gdb.t10/README: Document sparc-elf.
+ * gdb.t10/crossload.exp: Load and test sparc-elf.
+ * gdb.t10/sparc-elf.u: New test executable.
+
+Mon Nov 16 11:31:30 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * config/unix-tcl.exp: Tcl library init module.
+ * tcl.tests: Add the tests directory from the Tcl release.
+ * tcl.tests/Makefile.in, configure.in: Support stuff.
+ * tcl.tests/tcl-test.exp: Test the Tcl library.
+
+Sun Nov 15 09:30:29 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t30/{Makefile.in, chexp.exp, configure.in}: New tests
+ for GNU-Chill.
+ * configure.in (configdirs): Add gdb.t30.
+
+Fri Nov 13 21:14:13 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * runtest.exp (pass): don't print \n\nXPASS\n\n; just XPASS:
+ suffices.
+ (setup_xfail): don't set xfail_flag unconditionally; instead set
+ it if the argument is the target so that it can be called several
+ times.
+ (clear_xfail): new function to conditionally clear xfail_flag.
+ * config/unix-gdb.exp (gdb_load): set the directory to point to
+ whereever the program is loaded from, for the benefit of symbol
+ formats which don't know that.
+ * teststrategy.exp: accept AIX error messages.
+ (print "foo"): AIX shared libraries mean gdb can't find malloc.
+ (stack trace): fails on AIX.
+ * gdb.t02/in-gdbme.c, gdb.t03/in-gdbme.c: assign to nested_su
+ field so that AIX linker doesn't strip it from object file.
+ * gdb.t03/ptype.exp (unnamed enumeration): works on RS/6000.
+ * gdb.t04/setvar.exp: don't set prms_id to garbage value.
+ * gdb.t08/opaque.exp: RS/6000 can't do xrefs.
+ * gdb.t09/corefile.exp: AIX gdb can't get name or signal from a
+ core file.
+ * gdb.t10/crossload.exp: v_signed_char on MIPS generally fails.
+ * gdb.t11/list.exp: some tests fail because gcc generates
+ incorrect debugging information.
+ * gdb.t12/in-gdbme0.c, gdb.t12/in-gdbme1.c: don't let AIX strip
+ unreferenced variables.
+
+Thu Nov 12 08:17:40 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * runtest.exp (sum): catch errors from tool_version and tool_exit,
+ to ensure that we exit as expected even if they fail.
+ * gdb.t00/default.exp, gdb.t00/help.exp: some targets, notably the
+ RS/6000, don't support "set write" and "show write".
+ * gdb.t11/list.exp (list gdbme0.c:unused, list gdbme1.c:unused):
+ mark as expected failures for i960-*-*. These should perhaps be
+ considered successes.
+
+Tue Nov 10 20:40:43 1992 Rob Savoye (rob at rtl.cygnus.com)
+
+ * lib/gcc.exp: Added $LDFLAGS to default_gcc_start so targets can
+ get their linker scripts.
+
+Mon Nov 9 10:57:44 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * lib/gcc.exp: new file; defines default_gcc_version and
+ default_gcc_start.
+ * config/*-gcc.exp: use routines in gcc.exp.
+ * gcc.execute/execute.exp: don't use c-torture, because it gives
+ us undesired PASS and FAIL reports; use gcc_start instead.
+ * gcc.execute/920501-6.c, gcc.execute/920726-1.c: don't include
+ <stdio.h> or <strings.h>, so these can be used on VxWorks.
+ * gdb.t01/run.exp: expect "run" after sending it to avoid waiting
+ for the VxWorks shell too early.
+
+Sun Nov 8 21:38:55 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: added subdir_do target, use it for info and install-info
+
+Fri Nov 6 14:10:58 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/vx-gdb.exp (gdb_load, spawn_vxgdb): increase timeouts.
+ * gdb.t00/default.exp: accept AIX error messages, and set the init
+ file name based on the target.
+ * gdb.t01/run.exp, gdb.t12/scope.exp: increase timeouts for
+ VxWorks.
+ * gdb.t06/break.exp: increase timeouts for VxWorks, and rewrite a
+ few tests to use gdb_test function.
+
+Fri Nov 6 11:34:20 1992 Michael Werner (mtw@rtl.cygnus.com)
+
+ * Moved the following ChangeLog entry from devo/ChangeLog to here:
+
+Wed Nov 4 17:57:47 1992 Michael Werner (mtw@rtl.cygnus.com)
+
+ * Makefile.in: Added stuff for building deja-gnu.
+ * ./deja-gnu/gdb.t21/ & ./deja-gnu/gdb.t22/:
+ Moved in-gdbme.C file to in-gdbme.cc to enhance portability.
+ Changed the configure.in file to reflect the filename extension
+ change.
+
+Fri Nov 6 14:00:48 1992 Ian Lance Taylor (ian@tweedledumbest.cygnus.com)
+
+ * gdb.t15/funcargs.exp: continue to call6k is an expected failure
+ for i960-*-vxworks; PRMS 1786.
+
+Thu Nov 5 18:09:23 1992 Mike Stump (mrs@rtl.cygnus.com)
+
+ * lib/prebase.exp: Remove incorrect fix. CPLUSFLAGS needs to be
+ reset on a per test case basis, as it is changed by each test
+ case. The correct way to fix this is to establish a default value
+ for the variable, and set the variable to that value.
+
+Thu Nov 5 18:04:21 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: proc unknown doesn't print the error codes if
+ they're aren't any.
+ * lib/remote.exp: New procs tip and tip_download for boards that
+ live on the end of a serial cable.
+ * config/abug-gcc.exp: Init module for MVME board.
+ * config/mt-m68k-abug: Makefile frag for m68k MVME board.
+ * configure.in: Only makes links for config files that exist.
+
+Thu Nov 5 17:40:27 1992 Fred Fish (fnf@cygnus.com)
+
+ * {gdb.t20, gdb.t21, gdb.t22}/{Makefile.in, configure.in}:
+ Convert C++ filenames from '.C' to '.cc'. Rename test files.
+
+Wed Nov 4 11:50:34 1992 Ian Lance Taylor (ian@tweedledumbest.cygnus.com)
+
+ * lib/gdb.exp (gdb_test): don't check specially for attach error,
+ since that doesn't belong in a general test.
+ * gdb.t00/default.exp: fix attach and run tests for VxWorks.
+ * gdb.t04/setvar.exp: clean up a few broken tests, eliminating
+ some false failures incorrectly marked FIXME.
+ * gdb.t12/scope.exp: do two ``next'' commands if necessary to skip
+ over the call to init.
+ * gdb.t20/classes.exp, gdb.t20/inherit.exp: make FIXME cases use
+ setup_xfail.
+
+Tue Nov 3 11:53:37 1992 Ian Lance Taylor (ian@tweedledumbest.cygnus.com)
+
+ * runtest.exp (clone_output): send strings to the user even if
+ they say FIXME.
+ * gdb.t01/in-gdbme.c (vxmain): new function for VxWorks which
+ takes an argument and calls main with it.
+ gdb.t01/run.exp: for *-*-vxworks, call vxmain to pass arguments,
+ and look for results from connected task, not gdb.
+ * gdb.t01/term.exp: don't run these tests unless native.
+ * gdb.t02/whatis.exp, gdb.t03/ptype.exp, gdb.t05/expr.exp: expect
+ the i960 to fail to print type char correctly, because gdb treats
+ char as unsigned char.
+ * gdb.t06/in-gdbme.c (vxmain): new function for VxWorks which
+ takes an argument and calls main with it.
+ gdb.t06/break.exp: adjust line numbers for previous change. For
+ target *-*-vxworks, call vxmain to pass arguments.
+ * gdb.t07/watchpoint.exp: don't check the first old value after
+ restarting the program, because on VxWorks it will not have been
+ reset.
+ * gdb.t08/opaque.exp: don't check the breakpoint number, because
+ on VxWorks gdb_load stops and restarts gdb.
+ * gdb.t10/crossload.exp: don't run these tests for i960 targets,
+ because bfd uses SELECT_VECS and these formats are unknown.
+ * gdb.t11/list.exp: changed some FIXME strings to use setup_xfail.
+
+Mon Nov 2 19:00:36 1992 Ian Lance Taylor (ian@tweedledumbest.cygnus.com)
+
+ * config/vx-gdb.exp: use the new generic communication routines in
+ lib/remote.exp.
+ lib/remote.exp (rlogin): if we get "Sorry, this system is
+ engaged", try again; it can come from VxWorks just after
+ rebooting.
+
+Sat Oct 31 20:11:12 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: procs pass & fail now use a flag set by setup_xfail
+ to determine it a test is an expected failure or an unexpected
+ success.
+ * runtest.exp: New proc setup_xfail. If called with a configure
+ pattern it sets up the next test as an expected failure or an
+ unexpected success.
+
+Sat Oct 31 16:10:14 1992 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * gdb.t10/crossload.exp: Entire file re-written to use the new
+ gdb_test command.
+
+Sat Oct 31 12:12:08 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * lib/gdb.exp: gdb_test now traps cleanly if send fails cause gdb
+ core dumped.
+ * gdb.t00/default.exp: Rewrote the first few tests to use the
+ gdb_test proc.
+ * lib/gdb.exp: Added a gdb_test proc. It takes a command and a
+ pattern and runs the gdb test.
+
+Fri Oct 30 11:46:45 1992 Fred Fish (fnf@cygnus.com)
+
+ * runtest.exp: Guard against nonexistant PWD environment var,
+ which is shell dependent.
+
+Fri Oct 30 20:23:06 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp: Changed format of log messages. $prms_id & $bug_id
+ are only printed if they are not 0. Also they now appear at the
+ end of the line in parens with a label.
+ * runtest.exp: New procs xpass & xfail for expected failures and
+ unexpected successes. Added successes to proc sum.
+ * runtest.exp: istarget & ishost with no arguments returns the
+ target and host triplet strings.
+ * runtest.exp: New proc isnative. Returns a 1 if running native,
+ a 0 if on a target.
+ * config/nind-gcc.exp, coff-gcc.ecp, aout-gcc.exp: Applied patch
+ from vx-gcc.exp so errror messages don't always go to the screen.
+
+Thu Oct 29 19:07:28 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Changed all refences to $srcdir/lib to ./lib since configure now
+ makes a link for it.
+ * config/vx-gcc.exp: gcc_load doesn't try to load a program if
+ there is no remote shell.
+ * lib/remote.exp: The network procs telnet, rlogin, rsh now do
+ three retries before exiting with an error.
+ * runtest.exp: Fixed so there are multiple ways to get the users
+ login name so it can be printed in the logs.
+ * doc/DejaGnu.l, dejagnu.texi: Removed references to $nfshost.
+ * runtest.exp: Removed the --nfshost option cause it's become
+ unnessary.
+ * configure.in: Deals with the shorter names in config. Creates an
+ abbreviation for the OS and uses that for the filename substring.
+ * config/*: All names shortened to <= 14 characters.
+ All init-$target_os-$tool.exp changed to $target_os-$tool.exp.
+ * config/mt-vxworks68, mt-vxworks960: Changed to use the
+ abbreviated triplet form like all the other stubs. Now mt-m68k-vx
+ and mt-i960-vx.
+
+Tue Oct 27 10:27:33 1992 Mike Stump (mrs@cygnus.com)
+
+ * runtest.exp: When setting base_dir don't use getenv("PWD") until
+ the code works when there is no PWD env variable.
+
+Tue Oct 27 07:37:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t00/default.exp: accept "can't create process" error for run
+ on VxWorks.
+ gdb.t08/opaque.exp: don't look for $binfile when setting
+ breakpoint.
+ gdb.t15/funcargs.exp: added -re "$prompt $" cases.
+ gdb.t20/classes.exp: accept \t as well as space after line number.
+ gdb.t22/virtfunc.exp: added expected failure for "cannot invoke
+ functions on this machine".
+ lib/gdb.exp (runto): added -re "$prompt $" cases.
+
+ * lib/gdb.exp: renamed from break.exp. Moved gdb_unload and runto
+ in from config/init-unix-gdb.exp.
+ config/init-unix-gdb.exp: removed gdb_unload and runto.
+ config/init-vxworks-gdb.exp: removed runto.
+ (gdb_start): added "set args main" so that "run" with no arguments
+ works as on Unix.
+ config/*-gdb.exp: include gdb.exp, not break.exp.
+
+ * gdb.t01/in-gdbme.c: supply static atoi for vxworks, return
+ rather than calling exit (avoids VxWorks vs. libgcc problem).
+ gdb.t07/in-gdbme.c: return rather than calling exit.
+ gdb.t08/in-gdbme0.c: return rather than calling exit.
+ gdb.t13/in-gdbme.c: return rather than calling exit.
+ * gdb.t00/default.exp: don't set height and width here.
+ config/init-unix-gdb.exp (gdb_start): set it here.
+ config/init-vxworks-gdb.exp (gdb_start): and here.
+ * config/init-vxworks-gdb.exp (runto): new function, similar to
+ init-unix-gdb.exp function.
+
+Mon Oct 26 09:16:24 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t12/scope.exp: check for $prompt when failing, not just
+ timeout.
+ * gdb.t11/list.exp: accept tab as well as space after line number.
+ * gdb.t09/corefile.exp: don't run these tests on a target system.
+ gdb.t09/Makefile.in: don't complain if can not dump core.
+ * lib/break.exp: new file, for delete_breakpoints function.
+ config/*-gdb.exp: include it.
+ * config/init-vxworks-gdb.exp (gdb_start): open the telnet
+ connection in gdb_start, not just once.
+ (telnet_init): If shell is locked, retry.
+ (gdb_load): check for $prompt; also stop and restart gdb before
+ loading each file, because vxgdb accumulates symbols and lets the
+ old ones take precendence.
+
+Sun Oct 25 11:35:49 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * config/init-vxworks-gcc.exp: Now works good, traps load errors
+ cleanly.
+ * runtest.exp, doc/dejagnu.texi: Changed all occurences of
+ $defaultmode to $connectmode.
+ * config/init-vxworks-gcc.exp, init-unix-gcc.exp: Fixed so
+ compiler output doesn't go to the screen unless $verbose>1.
+ * runtest.exp: Improved error handling in proc unknown by having
+ it dump state.
+
+Sun Oct 25 11:35:49 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest.exp, doc/dejagnu.texi: Changed all occurences of
+ $defaultmode to $connectmode.
+ * config/init-vxworks-gcc.exp, init-unix-gcc.exp: Fixed so
+ compiler output doesn't go to the screen unless $verbose>1.
+ * runtest.exp: Improved error handling in proc unknown by having
+ it dump state.
+
+Sat Oct 24 22:44:09 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * gcc.execute/execute.exp: Looks at $status after executing the
+ test code.
+ * config/init-unix-gcc.exp: Made gcc_load work and set $status.
+ * runtest.exp: Moved regex variables for decimal and hex from
+ init-unix-gdb.exp.
+
+Fri Oct 23 12:03:47 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * config/mt-m68k-aout, mt-m68k-coff, mt-i960-nindy, mt-a29k-udi:
+ New makefile stubs.
+ * config/init-nindy-gdb.exp, init-nindy-gdb.exp, init-nindy-gdb.exp:
+ New init modules for nindy tests.
+ * configure.in: Added aout, coff, udi targets.
+ * config/init-aout-gdb.exp, init-coff-gdb.exp, init-udi-gdb.exp:
+ New init modules for gdb tests.
+ * config/init-aout-gcc.exp, init-coff-gcc.exp, init-udi-gcc.exp:
+ New init modules for gcc tests.
+ * config/init-aout-nm.exp, init-coff-nm.exp, init-udi-nm.exp: New
+ init modules for nm tests.
+ * lib/c-torture.exp: Fixed so warning messages are still a PASS.
+ * runtest.exp: Fixed bug so --connectmode now works.
+
+Fri Oct 23 11:56:02 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t06/in-gdbme.c: added definition of atoi when using VxWorks.
+ gdb.t06/break.exp: adjusted line numbers for above change.
+
+Thu Oct 22 21:39:03 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Makefile.in: Added to site target so the value of LIBS goes into
+ site.exp.
+
+Thu Oct 22 12:16:03 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * gdb.t00/help.exp: VxWorks support:
+ help i, help info: info sharedlibrary line is optional
+ help source: accept .vxgdbinit as well as .gdbinit
+ * gdb.t00/default.exp: VxWorks support:
+ add-symbol-file, show prompt: use $prompt, not (gdb)
+ i, info: info sharedlibrary line is optional
+ load, r, run, x: accept vxgdb responses as legitimate
+ * config/init-vxworks-gdb: send a single \n at end, because
+ otherwise the multiple prompts confuse the expect scripts.
+
+Wed Oct 21 16:06:33 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in, */Makefile.in: use new variable $(LIBS) when
+ linking.
+ config/mt-vxworks68, config/mt-vxworks960: define LIBS as -lgcc.
+ * configure.in: add irix* to list of unix targets.
+
+Tue Oct 20 12:31:38 1992 Mike Stump (mrs@rtl.cygnus.com)
+
+ * Makefile.in (subdirs): Fixed so that make works, even when whole
+ subdirectories of tests are removed. This way, subsets of the
+ whole set of test can be distributed.
+
+Mon Oct 19 10:59:19 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * gcc.execute/execute.exp: Runs all the test from the c-torture test's
+ execute directory.
+ * gcc.execute: New directory
+ * gcc.code_quality/code_quality.exp: Runs all the test from the c-torture test's
+ code_quality directory.
+ * gcc.code_quality: New directory
+ * gcc.noncompile/noncompile.exp: Runs all the test from the c-torture test's
+ noncompile directory.
+ * gcc.noncompile: New directory
+ * gdb.*/*.exp: Removed all references to $det_file.
+ * nm.all/nm.exp: Removed all references to $det_file.
+ * g++.other/g++-03.exp, g++-04.exp: Source prebase.exp and
+ postbase.exp from lib directory.
+ * g++.mike/misc1.exp, misc2.exp, misc3.exp, misc4.exp, misc5.exp,
+ misc6.exp, p646.exp, p710.exp: Source prebase.exp and postbase.exp
+ from lib directory.
+ * prebase.exp, postbase.exp: Moved into lib directory.
+
+Sun Oct 18 15:46:07 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * lib/c-torture.exp: New support procs for running tests from the
+ C torture test.
+ * gcc.unsorted/unsorted.exp: Runs all the test from the c-torture test's
+ unsorted directory.
+ * gcc.unsorted: New directory
+ * lib: New directory for Tcl procs used by tests.
+
+Sun Oct 18 00:39:59 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t11/list.exp: Revise to install FIXME cases for things
+ that are known to fail when used with DWARF.
+ * gdb.t07/watchpoints.exp: Rewrite to avoid cascading of errors.
+
+Sat Oct 17 10:54:42 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/teststrategy.exp: Fix single step tests to succeed
+ if the source for the gdb being tested is no longer available
+ for the gdb doing the testing.
+
+Fri Oct 16 17:25:31 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * g++.mike/misc1.C, misc4.C misc5.C p646.C: Changed all occurences
+ of 'i' as a variable, cause it screws up the vxworks 'i' shell
+ command.
+
+Fri Oct 16 15:51:10 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/default.exp: Set height to zero. Fix target cmds
+ to accept either "child" or "procfs" depending upon whether
+ gdb uses /proc.
+ * gdb.t00/help.exp: Accept either "child" or "procfs" for
+ target commands, depending upon gdb configuration for /proc.
+ * gdb.t00/teststrategy.exp: Make disassembly output more
+ portable. Make test for gdb core dump more portable.
+ * gdb.t07/watchpoint.exp: Test only for pattern at line
+ for watchpoint hit, ignore break addr and linenumber.
+ * gdb.t09/corefile.exp: Minor fixes for system dependencies.
+
+Wed Oct 14 13:11:51 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (configdirs): Add gdb.t22
+ * gdb.t22/{Makefile.in, configure.in, in-gdbme.C, virtfunc.exp}:
+ New tests for calling C++ virtual functions.
+
+Wed Oct 14 00:30:07 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (configdirs): Add gdb.t21
+ * config/init-unix-gdb.exp (delete_breakpoints): Minor cleanup.
+ * config/init-unix-gdb.exp (runto): New proc.
+ * gdb.t00/teststrategy.exp (test_with_self): Preserve the
+ original timeout and restore when done. Extend the timeout
+ for loading gdb into itself to 10 minutes (old limit of 5 minutes
+ was hit on a SPARCstation under moderate load).
+ * gdb.t01/term.exp: Fix run command in "info terminal" test.
+ * gdb.t06/break.exp: Fix linenumber in "run 2" output.
+ * gdb.t12/scope.exp: Remove "runto" proc, moved to init file.
+ * gdb.t20/inherit.exp: Remove "runto" proc, moved to init file.
+ * gdb.t20/classes.exp: Remove "runto" proc, moved to init file.
+ Also remove some junk leftover from gdbtest case conversion.
+ * gdb.t21/{Makefile.in, configure.in, in-gdbme.C, cplusfuncs.exp,
+ demangle.exp}: New test case for demangling and C++ function
+ lookups.
+
+Mon Oct 12 09:10:22 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t00/default.exp: Add expect strings for setting height and
+ width commands. Add expect string for add-symbol-file.
+ * gdb.t00/teststrategy.exp: Add proc to convert current gdb
+ pathname to fully qualified pathname for the copy command.
+ Reorganize so that the test can be gracefully skipped if this
+ fails. Increase timeout to load gdb to 5 minutes for systems
+ where loading is done over the network and/or full symtabs are
+ required.
+ * gdb.t20/{Makefile.in, configure.in, in-gdbme.C, classes.exp,
+ inherit.exp, misc.exp}: New tests for C++.
+
+Sat Oct 10 18:23:20 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest: New makefile created bourne shell to load runtest.exp
+ into expect. Needed for machine that don't grok #!/bin/expect kind
+ of things.
+ * config/mt-vxworks960: Uses new p3 naming convention. Also
+ expects to find all the binaries in your path.
+ * gdb.t13/bitfields.exp: Added a line after every test to dump the
+ output to the detail file.
+ * gdb.t15/funcargs.exp: Added a line after every test to dump the output to the detail file.
+ * configure.in: Do a "make runtest" for post target.
+ * Makefile.in: Has new target for making runtest. Runtest is a
+ bourne shell script that start $srcdir/runtest.exp.
+ * runtest.exp: made the printing of the summary counts a proc so a
+ ^C or SIGQUIT will print the summary, then exit.
+ * runtest: Renamed to runtest.exp.
+
+Fri Oct 9 07:15:04 1992 Fred Fish (fnf@cygnus.com)
+
+ * gdb.t11/configure.in (srctrigger): Change to list.exp.
+
+Fri Oct 9 00:16:02 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in: Add gdb.t11.
+ * runtest: Add new variable efailcnt for expected failures.
+ Treat expected failures as passes, but count them separately
+ and report summary.
+ * config/init-unix-gdb.exp (delete_breakpoints): Add proc.
+ * gdb.t03/ptype.exp: Add expected failure for enums.
+ * gdb.t04/setvar.exp: Make FIXME's consistent with other tests.
+ * gdb.t06/break.exp: Add new test for next over recursive calls.
+ * gdb.t11/{Makefile.in, configure.in, in-gdbme0.c, in-gdbme0.h,
+ in-gdbme1.c, list.exp}: New test for list command.
+ * gdb.t15/in-gdbme.c (test_struct_args): Remove aggregate initial-
+ ization.
+
+Tue Oct 6 19:25:00 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/init-unix-gdb.exp: Don't spawn gdb with a null argument
+ when GDBFLAGS is empty.
+ * gdb.t00/default.exp: Set width to 0 (unlimited).
+ * gdb.t00/default.exp: Add expect strings for "attach", "run",
+ "source", and "x", that match current gdb.
+ * gdb.t00/help.exp: Fix expect string for "help breakpoints".
+ * gdb.t00/teststrategy.exp: Fix "run" send string and expected
+ output. Fix expected output for control-C.
+ * gdb.t06/break.exp: Restart gdb to avoid leftovers from other
+ tests. Adjust line numbers to account for changes in test source.
+
+Tue Oct 6 11:08:26 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (configdirs): Add gdb.t13 gdb.t15.
+ * gdb.t12/in-gdbme0.c: Add code for checking auto variables and
+ local scopes.
+ * gdb.t12/scope.exp: Add tests for auto variables and local scopes.
+ * gdb.t13/{Makefile.in, configure.in, in-gdbme.c, bitfields.exp}:
+ New test for bitfields.
+ * gdb.t15/{Makefile.in, configure.in, in-gdbme.c, funcargs.exp}:
+ New test for actual args passed to functions.
+
+Fri Oct 2 15:42:10 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Makefile.in: Added support for srcdir going to site.exp.
+
+Thu Oct 1 21:26:35 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * teststrategy.exp: Changed the test for target vs host to using
+ $target_alias & $host_alias instead of $target_os & $host_os.
+ * corefile.exp: Added line to dump output of tests to detail
+ log.
+ * scope.exp: Added line to dump output of tests to detail
+ log.
+ * opaque.exp: Added line to dump output of tests to detail
+ log.
+ * crossload.exp: Added line to dump output of tests to detail
+ log.
+ * watchpoint.exp: Added line to dump output of tests to detail
+ log.
+
+Thu Oct 1 21:05:28 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest: Changed the test for target vs host to using
+ $target_alias & $host_alias instead of $target_aos & $host_os.
+
+Sep 30 08:45:00 1992 Fred Fish (fnf@fishpond.cygnus.com)
+
+ * configure.in (configdirs): Add gdb.t07, gdb.t08, gdb.t09
+ gdb.t10, gdb.t12.
+ * runtest: Fix some misspellings in trap commands.
+ * runtest (proc unknown): Change arg to args.
+ * runtest (clone_output, pass, fail): Remove leading tabs from result
+ lines that waste space that can be used for more meaningful
+ comments.
+ * runtest: Remove extraneous 12 newlines at end of file.
+ * config/init-unix-gdb.exp: Add convenience abbreviations for
+ hex and decimal number strings.
+ * config/init-unix-gdb.exp: Add gdb_unload proc.
+ * gdb.t06/break.exp: Replace hardcoded directory with $subdir.
+ * gdb.t07/{Makefile.in, configure.in, in-gdbme.c, watchpoint.exp}:
+ New tests for watchpoints.
+ * gdb.t08/{Makefile.in, configure.in, in-gdbme0.c, in-gdbme1.c,
+ opaque.exp}: New tests for opaque structs.
+ * gdb.t09/{Makefile.in, configure.in, in-gdbme.c, corefile.exp}:
+ New tests for core file handling.
+ * gdb.t10/{Makefile.in, configure.in, README, in-gdbme.c,
+ crossload.exp, i486-elf.u, i860-elf.u, m68k-aout.u, m68k-aout2.u,
+ m68k-elf.u, mips-ecoff.u, sparc-aout.u}: New files for non-native
+ executable handling tests.
+ * gdb.t12/{Makefile.in, configure.in, in-gdbme0.c, in-gdbme1.c,
+ scope.exp}: New tests for handling scope specifications.
+
+Sun Sep 20 14:18:19 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * configure.in: Better support for multiple platforms. Configures
+ for most unix variants and targets.
+ * DejaGnu.l, dejagnu.texi: Updated with new command line option.
+ * runtest: Added option to not reboot the target evry time.
+
+Thu Sep 10 17:15:37 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest: Check for config variable targetname and nfshost after
+ cmd options rather than before.
+
+Mon Sep 7 21:06:23 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * config/mt-m68k-coff: Created for m68k based bare board.
+
+Sun Sep 6 16:48:29 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * postbase.exp: add $srcdir for g++_start invocation from
+ different directory tree.
+ * postbase.exp: made output other than pass/fail go only to
+ screen only if $verbose > 1.
+
+Wed Sep 2 23:29:14 1992 Rob Savoye (rob at rtl.cygnus.com)
+
+ * Minor bug fixes. Now works with local config file.
+
+Sun Aug 16 23:00:40 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * dejagnu.texi: updated some more.
+ * configure.in: added nm support.
+ * Makefile.in: added nm.all to subdirs list.
+ * config/init-sunos-nm.exp: new init module for nm tests.
+ * nm.all/in-nmtest.c: new test case code for nm.
+ * nm.all/nm.exp: new test cases for nm.
+ * nm.all/Makefile.in: new makefile fragment
+ for nm tests.
+ * nm.all/configure.in: new config file file for nm tests.
+
+Sat Aug 15 16:30:39 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * All test cases: changed how the tool is invoked. Now use the
+ _start function.
+ * configure.in: added g++ init module.
+ * init-*-g++.exp: Created new global called $exec_output, to hold
+ the output of an executable produce by g++.
+ * init-sunos-g++.exp: Added stubs to target dependant routines.
+ * g++-init.exp: renamed to config/init-sunos-g++.exp.
+ * Features.txt: moved to doc directory.
+
+Sun Aug 9 22:49:21 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Added self-defined makefile style arguments.
+ * Added most of the makefile variables for tools to site.exp.
+ * Merged *-gdb-exit.exp into the config/init-*-gdb.exp and made it
+ a function call instead.
+
+Sat Aug 8 18:47:40 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * runtest: Now lets all site.exp set all configuration variables.
+ Command line options overrule the config file's.
+ * runtest: Rearranged all command line options. Made most of them
+ use a --fullname syntax.
+ * runtest: Now --verbose prints only the tests that failed. Added
+ option --all that prints tests that passed too.
+
+Fri Aug 7 21:55:48 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * init-vxworks-gdb.exp: Now uses config file.
+ * Makefile.in: Now has a target to make a config file.
+ * site.exp: Created by make/configure. Holds init values for
+ init module.
+ * configure.in: Now configures init modules for tool.
+ * runtest: Now uses init setup by configure.
+
+Wed Aug 5 23:04:47 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * all files: Changed the prompt pattern to a variable $prompt that
+ is set in the init module.
+
+Thu Jul 16 11:12:44 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Changed the framework executable from DejaGnu to runtest.
+
+Sun Jul 12 16:08:04 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Changed command line options so cc, gdb, etc... are specified
+ like makefiles. ie: CC=gcc CFLAGS="-v -r"
+ * Changed several command line option names.
+
+Fri Jul 10 11:28:00 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Added support to gdb_load in gdb-init.exp for loading a program
+ if another one is already loaded. Also now deals with reloading if
+ still debugging previous program.
+ * Added multiple levels of verbose. Verbose gets incremented
+ depending on how many times it appears on the command line.
+ * Added more subdirectories for gdb tests.
+ * Added tests for testing "run" and "terminal" commands.
+ * Added support to gdb_load() so it can load a file to replace the
+ previous one.
+
+Tue Jun 30 22:22:00 1992 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * DejaGnu: Added changes to main loop adding support for init and
+ exit modules. Moved *_version stuff to init modules.
+ * DejaGnu.l: Added new command line option for targets. Added lots
+ on how to write a test.
+ * Added section on init and exit modules. Added keyword use by
+ DejaGnu.
+ * vxworks-gdb-init.exp: Expect script that logs in to vxworks board,
+ starts GDB, and loads a file.
+ * gdb-init.exp: New init module for gdb native. Was gdb-01.exp.
+ * gdb-exit.exp: New exit module for GDB native.
+ * features.txt: List of features and goals. Based on testing meeting
+ notes.
+ * g++-init.exp: New module for G++ initialization.
+ * Gave gdb.all tests intelligent names instead of numbers.
+ * default.exp: Was xdefault.exp. Removed spawn commnd. Added prompt
+ for test failure.
+ * help.exp: Removed process spawning part. Added prompt match for test
+ failure.
+ * echo.exp: Was gdb-02.exp.
+
+Thu May 21 17:20:23 1992 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * Hacking in better detailed reports.
diff --git a/dejagnu/INSTALL b/dejagnu/INSTALL
new file mode 100644
index 00000000000..50dbe439d09
--- /dev/null
+++ b/dejagnu/INSTALL
@@ -0,0 +1,183 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ 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, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ 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 at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' 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. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. 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.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. 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.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+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 must use a version of `make' that
+supports the `VPATH' variable, such as 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 `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have 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.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' 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.
+
+ 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'.
+
+Optional Features
+=================
+
+ 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.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+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 host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+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.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--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.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/dejagnu/Makefile.am b/dejagnu/Makefile.am
new file mode 100644
index 00000000000..d68185fcbda
--- /dev/null
+++ b/dejagnu/Makefile.am
@@ -0,0 +1,50 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+SUBDIRS = doc testsuite
+
+# driver script goes in /usr/local/bin
+bin_SCRIPTS = runtest
+
+# auxiliary scripts go in /usr/local/share/dejagnu
+pkgdata_SCRIPTS = config.guess runtest.exp
+
+# Below, host-independent data files that need to get installed.
+# We do it this way so we can use globbing.
+
+lib_dest = $(DESTDIR)$(pkgdatadir)
+lib_files = $(srcdir)/*.c $(srcdir)/lib/*.exp
+
+baseboards_dest = $(DESTDIR)$(pkgdatadir)/baseboards
+baseboards_files = $(srcdir)/baseboards/README $(srcdir)/baseboards/*.exp
+
+config_dest = $(DESTDIR)$(pkgdatadir)/config
+config_files = $(srcdir)/config/README $(srcdir)/config/*.exp
+
+install-data-local:
+ $(mkinstalldirs) $(lib_dest)
+ for f in $(lib_files); do \
+ test ! -f "$$f" || $(INSTALL_DATA) $$f $(lib_dest); \
+ done
+ #
+ $(mkinstalldirs) $(baseboards_dest)
+ for f in $(baseboards_files); do \
+ test ! -f "$$f" || $(INSTALL_DATA) $$f $(baseboards_dest); \
+ done
+ #
+ $(mkinstalldirs) $(config_dest)
+ for f in $(config_files); do \
+ test ! -f "$$f" || $(INSTALL_DATA) $$f $(config_dest); \
+ done
+
+uninstall-local:
+ for f in $(lib_files); do \
+ test ! -f "$$f" || rm -f $(lib_dest)/`basename "$$f"`; \
+ done
+ for f in $(config_files); do \
+ test ! -f "$$f" || rm -f $(config_dest)/`basename "$$f"`; \
+ done
+ for f in $(baseboards_files); do \
+ test ! -f "$$f" || rm -f $(baseboards_dest)/`basename "$$f"`; \
+ done
diff --git a/dejagnu/Makefile.in b/dejagnu/Makefile.in
new file mode 100644
index 00000000000..85306fa6349
--- /dev/null
+++ b/dejagnu/Makefile.in
@@ -0,0 +1,412 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 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.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+BOARDS = @BOARDS@
+CC = @CC@
+CONFIG = @CONFIG@
+EXEEXT = @EXEEXT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+VERSION = 19991108@VERSION@
+
+AUTOMAKE_OPTIONS = cygnus
+
+SUBDIRS = doc testsuite
+
+# driver script goes in /usr/local/bin
+bin_SCRIPTS = runtest
+
+# auxiliary scripts go in /usr/local/share/dejagnu
+pkgdata_SCRIPTS = config.guess runtest.exp
+
+# Below, host-independent data files that need to get installed.
+# We do it this way so we can use globbing.
+
+lib_dest = $(DESTDIR)$(pkgdatadir)
+lib_files = $(srcdir)/*.c $(srcdir)/lib/*.exp
+
+baseboards_dest = $(DESTDIR)$(pkgdatadir)/baseboards
+baseboards_files = $(srcdir)/baseboards/README $(srcdir)/baseboards/*.exp
+
+config_dest = $(DESTDIR)$(pkgdatadir)/config
+config_files = $(srcdir)/config/README $(srcdir)/config/*.exp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_CLEAN_FILES =
+SCRIPTS = $(bin_SCRIPTS) $(pkgdata_SCRIPTS)
+
+DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
+Makefile.in NEWS TODO aclocal.m4 config.guess configure configure.in \
+install-sh mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ else :; fi; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_SCRIPTS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \
+ done
+
+install-pkgdataSCRIPTS: $(pkgdata_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ @list='$(pkgdata_SCRIPTS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(pkgdatadir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $$p $(DESTDIR)$(pkgdatadir)/`echo $$p|sed '$(transform)'`; \
+ else if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/`echo $$p|sed '$(transform)'`; \
+ else :; fi; fi; \
+ done
+
+uninstall-pkgdataSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ list='$(pkgdata_SCRIPTS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(pkgdatadir)/`echo $$p|sed '$(transform)'`; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(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
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --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) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am:
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-info-am:
+install-info: install-info-recursive
+install-exec-am: install-binSCRIPTS
+install-exec: install-exec-recursive
+
+install-data-am: install-pkgdataSCRIPTS install-data-local
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-binSCRIPTS uninstall-pkgdataSCRIPTS \
+ uninstall-local
+uninstall: uninstall-recursive
+all-am: Makefile $(SCRIPTS)
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(pkgdatadir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: uninstall-binSCRIPTS install-binSCRIPTS uninstall-pkgdataSCRIPTS \
+install-pkgdataSCRIPTS install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-info-am \
+install-info install-exec-am install-exec install-data-local \
+install-data-am install-data install-am install uninstall-local \
+uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+install-data-local:
+ $(mkinstalldirs) $(lib_dest)
+ for f in $(lib_files); do \
+ test ! -f "$$f" || $(INSTALL_DATA) $$f $(lib_dest); \
+ done
+ #
+ $(mkinstalldirs) $(baseboards_dest)
+ for f in $(baseboards_files); do \
+ test ! -f "$$f" || $(INSTALL_DATA) $$f $(baseboards_dest); \
+ done
+ #
+ $(mkinstalldirs) $(config_dest)
+ for f in $(config_files); do \
+ test ! -f "$$f" || $(INSTALL_DATA) $$f $(config_dest); \
+ done
+
+uninstall-local:
+ for f in $(lib_files); do \
+ test ! -f "$$f" || rm -f $(lib_dest)/`basename "$$f"`; \
+ done
+ for f in $(config_files); do \
+ test ! -f "$$f" || rm -f $(config_dest)/`basename "$$f"`; \
+ done
+ for f in $(baseboards_files); do \
+ test ! -f "$$f" || rm -f $(baseboards_dest)/`basename "$$f"`; \
+ done
+
+# 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/dejagnu/NEWS b/dejagnu/NEWS
new file mode 100644
index 00000000000..b3caa6c4357
--- /dev/null
+++ b/dejagnu/NEWS
@@ -0,0 +1,3 @@
+DejaGnu is now back under active maintainance. The initial work has been
+rewriting the manual to bring it up to date, and switching to SGML. NT
+support has also been added, and DejaGnu now uses automake.
diff --git a/dejagnu/README b/dejagnu/README
new file mode 100644
index 00000000000..0e22eab5e2d
--- /dev/null
+++ b/dejagnu/README
@@ -0,0 +1,283 @@
+ DejaGnu is a framework for testing other programs. Its purpose is to
+provide a single front end for all tests. Beyond this, DejaGnu offers
+several advantages for testing:
+
+ - The flexibility and consistency of the DejaGnu framework
+ make it easy to write tests for any program.
+
+ - DejaGnu provides a layer of abstraction which makes all
+ tests (if correctly written) portable to any host or target
+ where a program must be tested. For instance, a test for
+ GDB can run (from any Unix based host) on any target
+ architecture supported by DejaGnu. Currently DejaGnu runs
+ tests on several single board computers, whose operating
+ software ranges from just a boot monitor to a full-fledged,
+ Unix-like realtime OS.
+
+ - DejaGnu is written in expect, which in turn uses Tcl
+ (Tool command language). The framework comprises two parts:
+ the testing framework and the testsuites themselves. Tests
+ are usually written in expect using Tcl.
+
+ Bugs can be reported to bug-dejagnu@prep.ai.mit.edu.
+
+ How To Configure and Build
+
+ To build DejaGnu, run the ``configure'' script here, e.g.:
+
+ ./configure MYHOSTTYPE
+
+followed by running ``make''. (MYHOSTTYPE is a name for your host computer,
+for instance "sun4". You can use the script ``config.sub'' to test whether
+a name is recognized; if it is, config.sub translates it to a triplet
+specifying CPU, vendor, and OS.) This is used when you plan to
+configure and build in the source tree.
+
+ If you use a separate tree for object files, (the recommended way),
+then the --srcdir option must also be specified. This would also
+require that the configure script be run from the top level directory.
+
+ PATH/configure MYHOSTYPE --srcdir PATH/dejagnu
+
+where PATH is is the directory that the contains the sources.
+
+ To configure it so it gets installed somewhere other than the
+default of /usr/local, use the --prefix option.
+
+ configure MYHOSTYPE --prefix [PATH]
+
+where PATH is the prefix used to install the programs.
+
+ The configure testing and building will use the native compiler "cc"
+on your host machine. To change which compiler gets used (like gcc)
+set a the variable "CC" in your environment to point to it.
+
+ For csh users: "setenv CC gcc"
+ For bourne shell users: "CC=gcc;export CC"
+
+ Then when you compile, use "make CC=$CC".
+
+See etc/cfg-paper.texi, etc/configure.texi, and/or the README files in
+various subdirectories, for more details.
+
+ As DejaGnu is a Tcl program, there is nothing to build. However, the
+documentation is not built by default. Use these targets:
+"make info" - Convert the texinfo document to something that can
+ be used the GNU info program or info mode in emacs.
+"make dvi" - Convert the texinfo document to something that can
+ be printed. This produces dvi output.
+"make doc" - This builds both.
+"make ps" - This converts the dvi file into postscript. This
+ requires a copy of dvips.
+"make install" - This installs DejaGnu based on the --prefix option
+ when configuring. Otherwise it defaults to
+ /usr/local. See the DejaGnu manual for more
+ information on installation.
+
+ Changes from 1.1.1
+ 1. Works with (included in release) Tcl 7.3 and Expect 5.6.
+ 2. Much better error trapping and handling, including the
+ execution of sub scripts.
+ 3. Re-worked configuration subsystem.
+ 4. Default handling for testing unknown targets.
+ 5. New testsuite for expect and runtest.
+ 6. More debugging procedures.
+
+ Changes from 1.0
+
+ 1. DejaGnu now conforms to POSIX 1003.3, a standard for
+ testing frameworks.
+ 2. A Tcl debugger written by Don Libes has been added.
+ 3. Lots of bug fixes.
+
+ Changes from 0.9
+
+ 1. DejaGnu now installs itself like other utilities.
+ 2. 700 G++ tests are included.
+ 3. The bugs in the GCC tests have been fixed.
+ 4. Testsuites are released separately.
+ 5. Testsuite sources now reside with the within each tool's
+ source tree.
+
+-------------------------------------------------------------------
+Here's is a posting on the Free OS testing project. (FROST)
+-------------------------------------------------------------------
+If you have built up your own tests for system calls, library
+routines, networking protocols, or common utilities, this posting
+offers you an opportunity to put them to good use. You can do a good
+deed for the Linux community, the Berkeley UNIX community, and the
+wider world of free software users.
+
+Also, if you would like to learn some good test tools and strategies,
+and devote some time on a volunteer basis to writing tests -- perhaps
+a couple of weeks full-time, or a couple hours per week over a period
+of several months -- then here is a project you should get involved
+in.
+
+I am helping to coordinate a test effort for Linux. In the following
+four sections of this message I will describe the goals, the process,
+the people trying to do it, and what you can do to help.
+
+Goals
+
+ Linux and BSD share a number of libraries and utilities, both
+ because BSD software was ported to Linux, and because several free
+ software (GNU) utilities have been ported to both operating
+ systems.
+
+ Linux shows startling differences and failures as you move from one
+ set of hardware to another. People who hope to base their own
+ commercial products on Linux would like to see proof that it is
+ robust, portable, and standard-conforming. The problem is that
+ cross-platform testing is very hard to do, and few decent test
+ suites exist either for free software or for UNIX. (Look at all the
+ differences you find among systems that are SVID-conforming,
+ particularly at higher levels such as the utilities.)
+
+ Therefore, a number of us who are interested n Linux have decided to
+ enter the modern age of formal, automated software testing -- but in
+ a manner that is proper for the free software community.
+
+ Using DejaGnu, a test platform developed by Cygnus Support and
+ placed under the GPL, we want to collect the best tests we can from
+ people everywhere, and integrate them into suites that any user can
+ download, run, and interpret with a few commands. DejaGnu already
+ runs under BSD, and Cygnus is porting it to Linux.
+
+ Our goal is to test as many parts of the system as possible,
+ including system calls (particularly for POSIX 1003.1 compliance),
+ libraries in the official distribution, networking protocols,
+ and utilities. We need help with
+
+ 1) integrating good tests donated by the community (and probably
+ written in a variety of programming languages and command
+ shells) into the DejaGnu framework, and
+
+ 2) writing new tests for major functional areas for which no
+ adequate tests exist.
+
+ The tests we use will be placed under the GPL and distributed by
+ Cygnus Support along with DejaGnu. H. J. Lu, who maintains the C
+ library for Linux, has offered to run the POSIX 1003.1 tests and as
+ many others as he can.
+
+Process
+
+ First let me summarize the advantages of using DejaGnu, a free
+ software product that will be the umbrella for all the tests, and
+ then explain how we plan to conduct this project.
+
+ Cygnus Support released DejaGnu to the public on January 3, along
+ with several test suites for GNU language tools. The product is
+ designed for portability and easy cross-platform development and
+ execution. It works more uniformly than typical tests using the
+ UNIX shell, and also supports interactive testing better than most
+ test platforms -- for instance, Cygnus has written over 1300 unit
+ tests for the gdb debugger using it.
+
+ The implementation of DejaGnu is based on tcl and expect, two simple
+ existing languages for writing commands. You can develop new tests
+ in two major ways: by placing keyword-based comments in C source
+ code, or by writing tests in tcl.
+
+ While Cygnus is still increasing their body of tests for language
+ tools, they are also turning their resources toward the libraries
+ and GNU utilities. While most of the tests are written at Cygnus,
+ they have reached out to communities of testers and are now porting
+ substantial sets of donated tests.
+
+ We are hoping to broaden this successful use of collaboration across
+ user communities. We hope that suites of useful tests are sitting
+ in desk drawers out there. We also hope to gather and mobilize
+ people who appreciate the value of formal tests in legitimizing free
+ software, and would like to help write them.
+
+ I am not an employee of Cygnus, but have volunteered to talk to
+ interested people and do an initial classification of tests, just to
+ offload some of this routine work from them. I will discuss all
+ offers with Cygnus staff to find out what is most needed and decide
+ which tests to incorporate into DejaGnu. There are several criteria
+ for choosing tests, including the degree to which an area is
+ covered, and its importance in the overall stability of the
+ operating system. Some tests may have to be rejected just because
+ they are hard to fit into the DejaGnu model.
+
+People
+
+ Now you can find out why each of us got involved with this project.
+
+ Cygnus writes and distributes free software, selling support as a
+ means to make money. The company is not directly in the business of
+ supporting operating systems or common UNIX utilities, so this kind
+ of testing is tangential to their main goals. But they may want to
+ support those things in the future. In any case, they would like to
+ see Linux do well, and this big test project will be a good
+ promotion for DejaGnu.
+ H. K. Lu, as a volunteer for Linux, has been using his own system to
+ implement, port, maintain, and ensure ANSI and POSIX compliance for
+ the C library (mostly the GNU C library along with the iostream
+ class from the g++ library). He is looking for ways to validate the
+ work that he and many other contributors have put in.
+
+ As an editor at a publisher of computer books, my relationship to
+ Linux and BSD is even more distant than that of Cygnus. But we are
+ thinking about putting out books about Linux, from either the Linux
+ Documentation Project or independent authors, and would like to make
+ sure Linux is stable enough to be documented. The testing of
+ utilities is particularly important to me, because it can provide
+ quality assurance for our books, including the BSD version of UNIX
+ in a Nutshell.
+
+What you can do
+
+ We ask people who have written tests in the areas I have described
+ to donate them to this project and see them benefit the public.
+ Don't just send me stuff -- write or call to discuss what you've got
+ in general. You also have to assign the tests to the Free Software
+ Foundation (a simple matter, so long as you are the owner of the
+ tests) so that they can be distributed under the GPL.
+
+ Also, please don't starting flaming about the GPL. Either join our
+ project and donate your tests, or don't. Personally, I do not take
+ a side in this war.
+
+ People who are interested in testing as a discipline, and have some
+ time to donate, are invited to contact me to help write tests. Tell
+ me:
+
+ Your knowledge of computer languages and tools
+
+ Previous software test efforts you have engaged in, if any
+
+ How much time you can devote
+
+ What functional areas you think are important and have a
+ particular interest in
+
+ Cygnus staff will tell volunteers which areas need testing, and
+ offer guidance while you learn and apply DejaGnu. The most
+ important trait for the project is rigorous thinking along the lines
+ of software quality (so the best preparation is to have done some
+ formal testing before). You do not need to know any particular
+ language or tool; you can learn tcl or other aspects of DejaGnu
+ fairly quickly.
+
+ Contact information for me is in my signature. I am at the phone
+ number during traditional U.S. business hours. So send mail any
+ time, or try calling from Monday through Friday, 9:00 AM to 5:00 PM,
+ Eastern Daylight Saving Time (four hours later than Greenwich Mean
+ Time).
+
+ Feel free to distribute and repost this message elsewhere, in its
+ entirety.
+
+----------------------------------------------------------------------
+Andy Oram O'Reilly & Associates, Inc. andyo@ora.com
+ 90 Sherman Street, Cambridge, MA 02140 (617) 354-5800
+ fax (617) 661-1116
+----------------------------------------------------------------------
+
+There is a new listserv based mailing list for the FROST project. To
+subscribe, send email to "listserv@cygnus.com" and the body should
+contain "SUBSCRIBE FROST <your name>". Messages sent to
+frost@cygnus.com go to the mailing list. \ No newline at end of file
diff --git a/dejagnu/TODO b/dejagnu/TODO
new file mode 100644
index 00000000000..2f77cd5bba8
--- /dev/null
+++ b/dejagnu/TODO
@@ -0,0 +1,8 @@
+ Thu Mar 16 17:34:33 MST 1995
+
+. Add more support for target boards and realtime OS's.
+. Use the new expect terminal support for an "escape codes" API.
+. Use expectk and write a GUI testing API, complete with
+ record/playback.
+. Add a "testing methodologies" section to the manual.
+
diff --git a/dejagnu/aclocal.m4 b/dejagnu/aclocal.m4
new file mode 100644
index 00000000000..f5379a5be03
--- /dev/null
+++ b/dejagnu/aclocal.m4
@@ -0,0 +1,137 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Do all the work for Automake. 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.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# 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 (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $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
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
diff --git a/dejagnu/baseboards/README b/dejagnu/baseboards/README
new file mode 100644
index 00000000000..590bc43fee5
--- /dev/null
+++ b/dejagnu/baseboards/README
@@ -0,0 +1,15 @@
+The files in this directory are used to describe the basic
+configuration of a board. (Note that we use "board" in its loosest
+sense, referring to either a target or host). The structure of these
+files is very similar, and I would suggest that you follow this when
+writing a new one.
+
+Two files need to be created for a given board; the appropriate file
+in this directory, and one in devo/dejagnu/config. The one in here is
+used to set up entries in the data array describing the board, while
+the one in devo/dejagnu/config is used to describe the actions used to
+actually communicate with the board.
+
+A third file (the site-specific machine file) can be used to describe
+any site-specific functionality, such as port numbers, serial devices,
+etc.
diff --git a/dejagnu/baseboards/a29k-udi.exp b/dejagnu/baseboards/a29k-udi.exp
new file mode 100644
index 00000000000..3b4c5069af1
--- /dev/null
+++ b/dejagnu/baseboards/a29k-udi.exp
@@ -0,0 +1,23 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {a29k-amd-udi};
+
+# Load the generic configuration for this board.
+load_generic_config "udi";
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]";
+# The basic set of flags needed to build "hello world" for this
+# board. This target uses libgloss and newlib.
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# We don't need a linker script.
+set_board_info ldscript "";
+
+# mondfe can't return exit statuses, so gcc (ctorture et al) needs to
+# do what it can to get them.
+set_board_info needs_status_wrapper 1;
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 16384
diff --git a/dejagnu/baseboards/arc-sim.exp b/dejagnu/baseboards/arc-sim.exp
new file mode 100644
index 00000000000..4bb9d4a19cf
--- /dev/null
+++ b/dejagnu/baseboards/arc-sim.exp
@@ -0,0 +1,37 @@
+# There is currently no ARC simulator. This exists so gcc compile.exp testing
+# works.
+
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {arc-elf}
+
+# Load the generic configuration for this board. This will define a basic set
+# of routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# "arc" is the name of the sim subdir in devo/sim.
+setup_sim arc
+
+# No multilib options needed by default.
+process_multilib_options ""
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# No linker script needed.
+set_board_info ldscript "";
+
+# The simulator doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+# Doesn't pass arguments or signals, can't return results, and doesn't
+# do inferiorio.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
diff --git a/dejagnu/baseboards/arm-ice.exp b/dejagnu/baseboards/arm-ice.exp
new file mode 100644
index 00000000000..8e03737d0c9
--- /dev/null
+++ b/dejagnu/baseboards/arm-ice.exp
@@ -0,0 +1,48 @@
+# Load the generic configuration for this board. This will define a basic
+# set of routines used to communicate with the board.
+load_generic_config "arm-ice"
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+if { [board_info $board obj_format] == "pe" } {
+ set additional_options "-Wl,-oformat,pe-arm-little,--image-base,0"
+} else {
+ set additional_options ""
+}
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+# The basic set of flags needed to build "hello world" for this
+# board. This board uses libgloss and newlib.
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags] $additional_options"
+# This board doesn't use a linker script.
+set_board_info ldscript "";
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 16384
+
+# We use "target rdi" to talk to the board.
+set_board_info gdb_protocol "rdi"
+
+# No support for signals.
+set_board_info gdb,nosignals 1
+
+# Make this variable go away, we don't need it.
+unset additional_options;
+
+# Can't call functions from GDB.
+set_board_info gdb,cannot_call_functions 1
+
+# Or do I/O.
+set_board_info gdb,noinferiorio 1
+
+# Or have signals.
+set_board_info gdb,nosignals 1
+
+# Exit statuses are invalid.
+set_board_info exit_statuses_bad 1
diff --git a/dejagnu/baseboards/arm-sim.exp b/dejagnu/baseboards/arm-sim.exp
new file mode 100644
index 00000000000..9e96c1b2ed7
--- /dev/null
+++ b/dejagnu/baseboards/arm-sim.exp
@@ -0,0 +1,52 @@
+# Load the generic configuration for this board. This will define a basic
+# set of routines used to communicate with the board.
+load_generic_config "sim"
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+if { [board_info $board obj_format] == "pe" } {
+ set additional_options "-Wl,-oformat,pe-arm-little,--image-base,0"
+# set_board_info uses_underscores 1
+} else {
+
+# if [istarget "*-*-coff"] {
+# set_board_info uses_underscores 1
+# }
+
+ set additional_options ""
+}
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# The name of the directory in the build tree where the simulator lives.
+setup_sim arm;
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+# The basic set of flags needed to build "hello world" for this
+# board. This board uses libgloss and newlib.
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags] $additional_options"
+
+# This board doesn't use a linker script.
+set_board_info ldscript "";
+
+# The simulator doesn't return exit statuses and we need to indicate this.
+set_board_info needs_status_wrapper 1
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 16384
+
+# No support for signals.
+set_board_info gdb,nosignals 1
+
+# More time is needed to compile PlumHall tests
+set_board_info gcc,timeout 800
+
+# Make this variable go away, we don't need it.
+unset additional_options;
diff --git a/dejagnu/baseboards/basic-sim.exp b/dejagnu/baseboards/basic-sim.exp
new file mode 100644
index 00000000000..3fa7c4dc2c8
--- /dev/null
+++ b/dejagnu/baseboards/basic-sim.exp
@@ -0,0 +1,51 @@
+# find_sim -- find a usable simulator
+# This proc is local to this file and is used to locate a simulator to use.
+# First we see if SIM=foo was specified on the command line.
+# Otherwise we search the build tree, then $PATH.
+
+proc find_sim { target_alias sim_dir sim_name } {
+ global tool_root_dir;
+ global SIM
+
+ if [info exists SIM] {
+ return $SIM
+ }
+
+ if [is_remote host] {
+ if ![board_info host exists no_transform_name] {
+ return ${target_alias}-${sim_name};
+ } else {
+ return ${sim_name};
+ }
+ }
+
+ # We have to search because tool_root_dir may actually point to that blasted
+ # "target" subdirectory.
+ set try [lookfor_file ${tool_root_dir} sim/${sim_dir}/${sim_name}];
+ if { $try != "" } {
+ return $try;
+ }
+ return ${target_alias}-${sim_name};
+}
+
+proc setup_sim { subdir_name } {
+ global target_alias;
+ global tool_root_dir;
+ global board;
+
+ if [info exists target_alias] {
+ set tmp $target_alias;
+ } else {
+ if [board_info $board exists target_install] {
+ set tmp [lindex [board_info $board target_install] 0];
+ }
+ }
+
+ if ![board_info $board exists sim] {
+ set_board_info sim [find_sim $tmp $subdir_name run];
+ }
+
+ verbose "Using simulator [board_info $board sim]\n"
+}
+
+set_board_info is_simulator 1;
diff --git a/dejagnu/baseboards/cf.exp b/dejagnu/baseboards/cf.exp
new file mode 100644
index 00000000000..f4d73c3e5fb
--- /dev/null
+++ b/dejagnu/baseboards/cf.exp
@@ -0,0 +1,73 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {m68k-elf};
+
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "cfdbug";
+
+# Need -m5200 by default.
+process_multilib_options "-m5200"
+
+# The compiler used to build for this board. Note that this has nothing to do
+# with what compiler is tested when testing gcc.
+set_board_info compiler "[find_gcc]"
+
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+
+# Nasty hack.
+if { [board_info $board obj_format] == "a.out" } {
+ # Need to pass the start address to objcopy.
+ set_board_info use_vma_offset 1;
+ # Wrapping has to be specially done for m68k-aout, for whatever reason.
+ set_board_info wrap_m68k_aout 1;
+
+ set extra_m68k_ld_flags "-N"
+
+ # We need to tell GDB to load at the correct offset.
+ set_board_info gdb_load_offset [board_info $board hex_startaddr];
+} else {
+ set extra_m68k_ld_flags ""
+}
+
+set_board_info ldflags "$extra_m68k_ld_flags [libgloss_link_flags] [newlib_link_flags]"
+unset extra_m68k_ld_flags
+
+
+# If no output format is specified, use objcopy.
+if ![board_info $board exists output_format] {
+ set tempfil [lookfor_file $tool_root_dir binutils/objcopy];
+ if { $tempfil != "" } {
+ set_board_info objcopy $tempfil
+ } else {
+ set_board_info objcopy [transform objcopy]
+ }
+ unset tempfil
+}
+
+# SBC5204 linker script.
+set_board_info ldscript "-Wl,-Tsbc5204.ld";
+# The idt interface can't return exit statuses, so gcc (ctorture et
+# al) needs to do what it can to get them.
+set_board_info needs_status_wrapper 1;
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can be.
+# The board has 192K of RAM. We will set stack size to one third of that.
+set_board_info gcc,stack_size 65536
+
+# GDB needs to use "target dbug" to talk to the board.
+set_board_info gdb_protocol "dbug";
+
+# Can't pass arguments to the program under test.
+set_board_info noargs 1
+
+# Nor can it do I/O in GDB.
+set_board_info gdb,noinferiorio 1
+
+# It has no signals.
+set_board_info gdb,nosignals 1
+
+# It can't return results when debugging with GDB.
+set_board_info gdb,noresults 1
+
+# Pseudo-random guess.
+set_board_info sys_speed_value 200;
diff --git a/dejagnu/baseboards/cygmon.exp b/dejagnu/baseboards/cygmon.exp
new file mode 100644
index 00000000000..6ee4458c230
--- /dev/null
+++ b/dejagnu/baseboards/cygmon.exp
@@ -0,0 +1,31 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sparc-elf sparc64-elf}
+
+# Load the generic configuration for this board. This will define a
+# set of generic routines used by the tool to communicate with the
+# board.
+load_generic_config "cygmon";
+
+# It needs no multilib flags by default.
+process_multilib_options ""
+
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "-nostdlib [libgloss_link_flags] [newlib_link_flags] [board_info $board addl_link_flags]";
+
+# CygMON linker script.
+set_board_info ldscript "-Tcygmon.ld"
+
+# Standard remote protocol.
+set_board_info gdb_protocol "remote";
+# We can't do input in GDB (yet! HA!). It *will* do output, hurrah.
+set_board_info gdb,noinferiorio 1;
+# Or pass arguments.
+set_board_info noargs 1;
+# Or do signals.
+set_board_info gdb,nosignals 1;
+
+set_board_info shell_prompt "cygmon>"
+
+
+set_board_info use_gdb_stub 1;
diff --git a/dejagnu/baseboards/cygwin.exp b/dejagnu/baseboards/cygwin.exp
new file mode 100644
index 00000000000..80d44076b99
--- /dev/null
+++ b/dejagnu/baseboards/cygwin.exp
@@ -0,0 +1,12 @@
+# The canonical unix board description.
+load_generic_config "unix";
+
+process_multilib_options "";
+
+set_board_info compiler "[find_gcc]";
+
+set_board_info bmk,use_alarm 1;
+
+set_board_info gdb,noinferiorio 1;
+
+send_user "configuring for cygwin testing\n";
diff --git a/dejagnu/baseboards/d10v-sim.exp b/dejagnu/baseboards/d10v-sim.exp
new file mode 100644
index 00000000000..f744cdc48da
--- /dev/null
+++ b/dejagnu/baseboards/d10v-sim.exp
@@ -0,0 +1,48 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {d10v-elf}
+
+# Load the generic configuration for this board. This will define any
+# routines needed to communicate with the board.
+load_generic_config "sim";
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# The name of the simulator directory is "d10v".
+setup_sim d10v
+
+# No multilib options needed by default.
+process_multilib_options "";
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info cflags "[newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# No linker script needed.
+set_board_info ldscript "";
+
+# Can't pass arguments to programs on this target..
+set_board_info noargs 1
+# And there's no support for signals.
+set_board_info gdb,nosignals 1
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 5000
+
+# Used by a few gcc.c-torture testcases when trampolines are used.
+set_board_info gcc,no_trampolines 1
+
+# Used by a few gcc.c-torture testcases when labels as values are used.
+set_board_info gcc,no_label_values 1
+
+# Torture test gcc.c-torture/execute/920501-6.c takes > 5 minutes on a
+# 90 Mhz Pentium, so up the time limit.
+set board_info($board,sim_time_limit) 600
+
+# sizeof int != sizeof long.
+set_board_info gdb,short_int 1
diff --git a/dejagnu/baseboards/d10v.exp b/dejagnu/baseboards/d10v.exp
new file mode 100644
index 00000000000..3e46e1117ce
--- /dev/null
+++ b/dejagnu/baseboards/d10v.exp
@@ -0,0 +1,56 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {d10v-elf}
+
+# Load the generic configuration for this board. This will define a base set
+# of routines needed by the tool to communicate with the board.
+load_generic_config "d10v"
+
+# No multilib options are needed by default for this board.
+process_multilib_options "";
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]";
+# No linker script needed.
+set_board_info ldscript "";
+
+# The board can't really return exit statuses and we need to indicate this;
+# however, the standard GCC wrapper won't work with this target because
+# it can't do I/O.
+#set_board_info needs_status_wrapper 1
+
+# It uses the remote stub protocol to talk to the board.
+set_board_info gdb_protocol "remote"
+set_board_info use_gdb_stub 1
+
+# Both the EVA and TS3 boards currently deal badly with X packets.
+set_board_info disable_x_packet 1
+
+# Both the EVA and TS3 boards currently deal badly with Z packets.
+set_board_info disable_z_packet 1
+
+# Used by gdb-comm.
+set_board_info gdb_run_command "jump *_start";
+set_board_info gdb,start_symbol "_start";
+
+# Can't pass arguments to programs on this target.
+set_board_info noargs 1
+# And there's no support for signals.
+set_board_info gdb,nosignals 1
+# And it can't do I/O.
+set_board_info gdb,noinferiorio 1
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 5000
+
+# Used by a few gcc.c-torture testcases when trampolines are used.
+set_board_info gcc,no_trampolines 1
+
+# Used by a few gcc.c-torture testcases when labels as values are used.
+set_board_info gcc,no_label_values 1
+
+# sizeof int != sizeof long.
+set_board_info gdb,short_int 1
diff --git a/dejagnu/baseboards/d30v-sim.exp b/dejagnu/baseboards/d30v-sim.exp
new file mode 100644
index 00000000000..c7951657914
--- /dev/null
+++ b/dejagnu/baseboards/d30v-sim.exp
@@ -0,0 +1,33 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {d30v-elf}
+
+# Load the generic configuration for this board. This will define any
+# routines needed to communicate with the board.
+load_generic_config "sim";
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# The name of the simulator directory is "d30v".
+setup_sim d30v
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+# Pass -C to the assembler to suppress the warning about symbols being the same name as registers
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags] -Wa,-C"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags] -mextmem -Wl,--defsym,__stack=0x80800000"
+# No linker script needed.
+set_board_info ldscript "";
+
+# Can't pass arguments to programs on this target..
+set_board_info noargs 1
+# And there's no support for signals.
+set_board_info gdb,nosignals 1
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 5000
diff --git a/dejagnu/baseboards/danlite-elf.exp b/dejagnu/baseboards/danlite-elf.exp
new file mode 100644
index 00000000000..e22db2f7850
--- /dev/null
+++ b/dejagnu/baseboards/danlite-elf.exp
@@ -0,0 +1,42 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sparc86x-elf}
+
+# Load the generic configuration for this board. This will define a
+# set of generic routines used by the tool to communicate with the
+# board.
+load_generic_config "slite";
+
+# It needs no multilib flags by default.
+process_multilib_options ""
+
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+
+set_board_info ldflags "-nostartfiles [libgloss_link_flags] [newlib_link_flags]";
+
+# DANlite (sparc86x) linker script.
+set_board_info ldscript "-Tsparc86x.ld";
+
+# The address at which the stub needs to be linked.
+# set_board_info gdb_stub_offset "0x40000000";
+
+# The board doesn't return exit statuses and we need to indicate this.
+# However, the standard GCC wrapper won't work with this target because
+# it doesn't return stuff from printf ().
+set_board_info needs_status_wrapper 1;
+
+# We use a GDB stub to talk to the board.
+set_board_info use_gdb_stub 1;
+# For GDB, we need to use a real stub (not the separate loader scheme
+# we use for Sparclet).
+set_board_info gdb_stub "";
+# And the protocol is "sparclite".
+set_board_info gdb_protocol "sparclite";
+# No mathlib.
+set_board_info mathlib "";
+# We can't do I/O in GDB.
+set_board_info gdb,noinferiorio 1;
+# Or pass arguments.
+set_board_info noargs 1;
+# Or do signals.
+set_board_info gdb,nosignals 1;
diff --git a/dejagnu/baseboards/dos.exp b/dejagnu/baseboards/dos.exp
new file mode 100644
index 00000000000..8702a031a71
--- /dev/null
+++ b/dejagnu/baseboards/dos.exp
@@ -0,0 +1,25 @@
+# This is a list of the installed tools for this board. Of course,
+# we apparently don't create a compiler for this board, but...
+set_board_info target_install {i386-cygwin32}
+
+# Load the generic configuration for the board. This will define any routines
+# needed by the tool to communicate with the board.
+
+load_generic_config "dos";
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]";
+# The basic set of flags needed to build "hello world" for this
+# board. This target uses libgloss, libio and winsup.
+set_board_info cflags "[newlib_include_flags] [libio_include_flags] [winsup_include_flags]";
+set_board_info ldflags "[newlib_link_flags] [libio_link_flags] [winsup_link_flags]"
+# We don't need a link script.
+set_board_info ldscript "";
+
+# mondfe can't return exit statuses, so gcc (ctorture et al) needs to
+# do what it can to get them.
+set_board_info needs_status_wrapper 1;
+
+set_board_info gdb_opts "--command gdbinit"
+set_board_info gdb,nointerrupts 1
diff --git a/dejagnu/baseboards/fr30-cygmon.exp b/dejagnu/baseboards/fr30-cygmon.exp
new file mode 100644
index 00000000000..b18fa595289
--- /dev/null
+++ b/dejagnu/baseboards/fr30-cygmon.exp
@@ -0,0 +1,31 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {fr30-elf}
+
+# Load the generic configuration for this board. This will define a
+# set of generic routines used by the tool to communicate with the
+# board.
+load_generic_config "cygmon";
+
+# It needs no multilib flags by default.
+process_multilib_options ""
+
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags] [board_info $board addl_link_flags]";
+
+# CygMON linker script.
+set_board_info ldscript "-specs=eval1.specs"
+
+# Standard remote protocol.
+set_board_info gdb_protocol "remote";
+# We can't do input in GDB (yet! HA!). It *will* do output, hurrah.
+set_board_info gdb,noinferiorio 1;
+# Or pass arguments.
+set_board_info gdb,noargs 1;
+set_board_info noargs 1;
+# Or do signals.
+set_board_info gdb,nosignals 1;
+
+set_board_info shell_prompt "cygmon>"
+
+set_board_info use_gdb_stub 1;
diff --git a/dejagnu/baseboards/fr30-elf.exp b/dejagnu/baseboards/fr30-elf.exp
new file mode 100644
index 00000000000..3c8f514ce08
--- /dev/null
+++ b/dejagnu/baseboards/fr30-elf.exp
@@ -0,0 +1,40 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {fr30-elf}
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+# Load the generic configuration for this board. This will define a basic set
+# of routines needed by the tool to communicate with the board.
+if { $is_gdb_remote } {
+ load_generic_config "fr30-stub"
+} else {
+ load_generic_config "fr30"
+}
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+set_board_info ldscript "-Wl,-Teva.ld"
+set_board_info gdb,start_symbol "_start"
+
+set_board_info needs_status_wrapper 1
+
+# The GDB protocol used for this target.
+if { ! $is_gdb_remote } {
+ set_board_info gdb_protocol "fr30"
+} else {
+ set_board_info gdb_protocol "fr30"
+ set_board_info use_gdb_stub 1
+ set_board_info gdb_stub_ldscript "-Wl,-Teva-stub.ld"
+}
+
+# Doesn't pass arguments or signals, can't return results, and doesn't
+# do inferiorio.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
diff --git a/dejagnu/baseboards/fr30-sim.exp b/dejagnu/baseboards/fr30-sim.exp
new file mode 100644
index 00000000000..73fad4cec71
--- /dev/null
+++ b/dejagnu/baseboards/fr30-sim.exp
@@ -0,0 +1,34 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {fr30-elf}
+
+# Load the generic configuration for this board. This will define a basic set
+# of routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# "fr30" is the name of the sim subdir in devo/sim.
+setup_sim fr30
+
+# No multilib options needed by default.
+process_multilib_options ""
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# No linker script needed.
+set_board_info ldscript "";
+
+# The simulator doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+# Doesn't pass arguments or signals, can't return results, and doesn't
+# do inferiorio.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
diff --git a/dejagnu/baseboards/h8300-sim.exp b/dejagnu/baseboards/h8300-sim.exp
new file mode 100644
index 00000000000..39415dfd09d
--- /dev/null
+++ b/dejagnu/baseboards/h8300-sim.exp
@@ -0,0 +1,44 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {h8300-hms}
+
+# Load the tool-specific configuration for this board, as well as the
+# generic configuration. This will define any routines needed by the
+# tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# The name of the simulator is "h8300" (as in h8300-hms-run).
+setup_sim h8300
+
+# No multilib options are used by default.
+process_multilib_options ""
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+# We only support newlib on this target.
+set_board_info cflags "[newlib_include_flags]"
+set_board_info ldflags "[newlib_link_flags]"
+# The simulator doesn't return exit statuses and we need to indicate this.
+set_board_info needs_status_wrapper 1
+
+# There's no support for argument-passing.
+set_board_info noargs 1
+# Nor does it have real signals.
+set_board_info gdb,nosignals 1
+# And it can't do I/O.
+set_board_info gdb,noinferiorio 1
+# Nor can it return results.
+set_board_info gdb,noresults 1
+
+# Limit the stack size to something real tiny.
+set_board_info gcc,stack_size 4096
+
+# There's no long long support on this target
+set_board_info no_long_long 1
+
+# sizeof int != sizeof long.
+set_board_info gdb,short_int 1
diff --git a/dejagnu/baseboards/h8300.exp b/dejagnu/baseboards/h8300.exp
new file mode 100644
index 00000000000..f42dbb04ba0
--- /dev/null
+++ b/dejagnu/baseboards/h8300.exp
@@ -0,0 +1,68 @@
+# Load the tool-specific configuration for this board, as well as the
+# generic configuration. This will define any routines needed by the
+# tool to communicate with the board.
+load_generic_config "h8300"
+
+# Don't use anything by default.
+process_multilib_options ""
+
+# The default compiler for this target.
+set_board_info compiler "[find_gcc]"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info cflags "[newlib_include_flags]"
+set_board_info ldflags "[newlib_link_flags]"
+
+# The GDB protocol used with this board.
+set_board_info gdb_protocol "remote"
+# It's running a GDB stub in ROM.
+set_board_info use_gdb_stub 1;
+
+# There's no support for argument-passing.
+set_board_info noargs 1
+# Nor does it have real signals.
+set_board_info gdb,nosignals 1
+# And it can't do I/O.
+set_board_info gdb,noinferiorio 1
+# Nor can it return results.
+set_board_info gdb,noresults 1
+
+# Limit the stack size to something real tiny.
+set_board_info gcc,stack_size 4096
+
+# The board can get wedged in amusing and interesting ways.
+set_board_info unreliable 1
+
+# There's no long long support on this target
+set_board_info no_long_long 1
+
+# sizeof int != sizeof long.
+set_board_info gdb,short_int 1
+
+# Pick the right linker script if -mh/-ms is specified.
+
+set linker_script "h8300.ld"
+
+foreach x $board_variant_list {
+ regsub -all "^\[ \t\]*" "$x" "" x;
+ regsub -all "\[ \t\]*$" "$x" "" x;
+
+ case $x in {
+ { h -mh } {
+ set linker_script "h8300h.ld"
+ }
+ { s -ms } {
+ set linker_script "h8300s.ld"
+ }
+ }
+}
+
+# Whee, magic linker scripts hidden away.
+#
+# This one's dependent on the multilib options in use, sadly. And we
+# *need* a linker script. Really. Otherwise the code gets linked at
+# the wrong address and it won't run on the board.
+set_board_info ldscript "-Wl,-T${prefix_dir}/h8300-hms/${linker_script}"
+
+unset linker_script
diff --git a/dejagnu/baseboards/i386-bozo.exp b/dejagnu/baseboards/i386-bozo.exp
new file mode 100644
index 00000000000..1dbfae0fa76
--- /dev/null
+++ b/dejagnu/baseboards/i386-bozo.exp
@@ -0,0 +1,51 @@
+# Load the tool-specific configuration for this board, as well as the
+# generic configuration. This will define any routines needed by the
+# tool to communicate with the board.
+load_generic_config "i386-bozo"
+
+# Use no multilib options by default.
+process_multilib_options ""
+
+# Default to COFF.
+set add_flags "";
+if { [board_info $board obj_format] == "a.out" } {
+ set_board_info support_libs "${prefix_dir}/i386-aout/"
+ set_board_info gdb_load_offset "0x41000000";
+ set_board_info gdb_sect_offset "0x41000000";
+ set add_flags "-N ";
+} elseif { [board_info $board obj_format] == "elf" } {
+ set_board_info support_libs "${prefix_dir}/i386-elf/"
+} else {
+ set_board_info support_libs "${prefix_dir}/i386-coff/"
+}
+
+# The default compiler for this target.
+set_board_info compiler "[find_gcc]"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info cflags "[newlib_include_flags]"
+set_board_info ldflags "${add_flags}[newlib_link_flags] -B[board_info $board support_libs]"
+# Whee, magic linker scripts hidden away.
+set_board_info ldscript "-Tbozo.ld"
+
+# The GDB protocol used with this board.
+set_board_info gdb_protocol "remote"
+# It's running a GDB stub in ROM.
+set_board_info use_gdb_stub 1;
+
+# There's no support for argument-passing.
+set_board_info noargs 1
+# Can't do input.
+set_board_info gdb,noinferiorio 1
+# Nor does it have real signals.
+set_board_info gdb,nosignals 1
+
+# Limit the stack size.
+set_board_info gcc,stack_size 16384
+
+# Status wrapper will work, although exit statuses are reliable.
+set_board_info needs_status_wrapper 1
+
+# This is the start symbol in crt0.o.
+set_board_info gdb,start_symbol "_start";
diff --git a/dejagnu/baseboards/i960-cyclone.exp b/dejagnu/baseboards/i960-cyclone.exp
new file mode 100644
index 00000000000..6ce5ce70220
--- /dev/null
+++ b/dejagnu/baseboards/i960-cyclone.exp
@@ -0,0 +1,47 @@
+# Danger, Will Robinson! Settings in this file do not override
+# previous settings for the board being defined.
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "i960"
+
+# No multilib options needed by default.
+process_multilib_options ""
+
+# We want to strip executables before downloading them via xmodem.
+if ![board_info $board exists strip] {
+ set tempfil [lookfor_file $tool_root_dir binutils/strip];
+ if { $tempfil != "" } {
+ set_board_info strip $tempfil
+ } else {
+ set_board_info strip [transform strip]
+ }
+ unset tempfil
+}
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info start_addr 0xa0008000
+set_board_info ldflags "-Wl,-Ttext,[board_info $board start_addr] [libgloss_link_flags] [newlib_link_flags] -B${prefix_dir}/i960-coff/"
+# IDT linker script.
+set_board_info ldscript "-Wl,-T${prefix_dir}/i960-coff/i960.ld"
+
+# GDB doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+
+# The GDB protocol used with this board.
+set_board_info gdb_protocol "mon960"
+
+# Can't pass arguments to the program.
+set_board_info noargs 1
+
+# No support for signals.
+set_board_info gdb,nosignals 1
+
+set_board_info gdb_prompt "\\(gdb960\\)"
+
+# The board tends to be unreliable.
+set_board_info unreliable 1
diff --git a/dejagnu/baseboards/i960-sim.exp b/dejagnu/baseboards/i960-sim.exp
new file mode 100644
index 00000000000..98ca8de63a4
--- /dev/null
+++ b/dejagnu/baseboards/i960-sim.exp
@@ -0,0 +1,28 @@
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "sim";
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim";
+
+# This tells it which directory to look in for the simulator.
+setup_sim i960;
+
+# No multilib flags are set by default.
+# Set -msoft-float, because the simulator doesn't have FP support yet.
+process_multilib_options "-msoft-float";
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]";
+
+set_board_info cflags "-mka [libgloss_include_flags] [newlib_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]";
+
+# Use mon960.
+set_board_info ldscript "-Wl,-Tmon960.ld";
+
+# And, it can't do arguments, and doesn't have real signals.
+# ??? Unknown if this is right.
+set_board_info noargs 1;
+set_board_info gdb,nosignals 1;
diff --git a/dejagnu/baseboards/jmr3904-sim.exp b/dejagnu/baseboards/jmr3904-sim.exp
new file mode 100644
index 00000000000..244e2b5d688
--- /dev/null
+++ b/dejagnu/baseboards/jmr3904-sim.exp
@@ -0,0 +1,14 @@
+# And we use the jmr3904 linker script.
+set_board_info ldscript "-Tjmr3904app.ld"
+
+# Pass --board=jmr3904 to the standalone simulator
+set_board_info sim,options "--board=jmr3904"
+set_board_info gdb,target_sim_options "--board=jmr3904"
+
+# Pass -G 0 when testing libjava
+set_board_info libjava,options "-G 0"
+
+set_board_info gcc,stack_size "8192"
+
+# Otherwise we're the same as the standard MIPS simulator.
+load_base_board_description "mips-sim";
diff --git a/dejagnu/baseboards/m32r-elf.exp b/dejagnu/baseboards/m32r-elf.exp
new file mode 100644
index 00000000000..ab402ae5ded
--- /dev/null
+++ b/dejagnu/baseboards/m32r-elf.exp
@@ -0,0 +1,40 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {m32r-elf}
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+# Load the generic configuration for this board. This will define a basic set
+# of routines needed by the tool to communicate with the board.
+if { $is_gdb_remote } {
+ load_generic_config "m32r-stub"
+} else {
+ load_generic_config "m32r"
+}
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+set_board_info ldscript "-Wl,-Teva.ld"
+set_board_info gdb,start_symbol "_start"
+
+set_board_info needs_status_wrapper 1
+
+# The GDB protocol used for this target.
+if { ! $is_gdb_remote } {
+ set_board_info gdb_protocol "m32r"
+} else {
+ set_board_info gdb_protocol "m32r"
+ set_board_info use_gdb_stub 1
+ set_board_info gdb_stub_ldscript "-Wl,-Teva-stub.ld"
+}
+
+# Doesn't pass arguments or signals, can't return results, and doesn't
+# do inferiorio.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
diff --git a/dejagnu/baseboards/m32r-sim.exp b/dejagnu/baseboards/m32r-sim.exp
new file mode 100644
index 00000000000..eaa7145bd54
--- /dev/null
+++ b/dejagnu/baseboards/m32r-sim.exp
@@ -0,0 +1,34 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {m32r-elf}
+
+# Load the generic configuration for this board. This will define a basic set
+# of routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# "m32r" is the name of the sim subdir in devo/sim.
+setup_sim m32r
+
+# No multilib options needed by default.
+process_multilib_options ""
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# No linker script needed.
+set_board_info ldscript "";
+
+# The simulator doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+# Doesn't pass arguments or signals, can't return results, and doesn't
+# do inferiorio.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
diff --git a/dejagnu/baseboards/m68k-emc.exp b/dejagnu/baseboards/m68k-emc.exp
new file mode 100644
index 00000000000..7b576496f4f
--- /dev/null
+++ b/dejagnu/baseboards/m68k-emc.exp
@@ -0,0 +1,35 @@
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "m68k-emc";
+
+# No multilib options by default.
+process_multilib_options ""
+
+# The compiler used to build for this board. Note that this has nothing to do
+# with what compiler is tested when testing gcc.
+set_board_info compiler "[find_gcc]"
+
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+
+set_board_info ldflags "-nostdlib [libgloss_link_flags] [newlib_link_flags]"
+
+# No linker script.
+set_board_info ldscript "";
+# The idt interface can't return exit statuses, so gcc (ctorture et
+# al) needs to do what it can to get them.
+set_board_info needs_status_wrapper 1;
+
+# GDB needs to use "target remote" to talk to the board.
+set_board_info gdb_protocol "remote";
+
+# Can't pass arguments to the program under test.
+set_board_info noargs 1
+
+# Nor can it do I/O in GDB.
+set_board_info gdb,noinferiorio 1
+
+# It has no signals.
+set_board_info gdb,nosignals 1
+
+# It can't return results when debugging with GDB.
+set_board_info gdb,noresults 1
diff --git a/dejagnu/baseboards/mcore-elf.exp b/dejagnu/baseboards/mcore-elf.exp
new file mode 100644
index 00000000000..a50df98a038
--- /dev/null
+++ b/dejagnu/baseboards/mcore-elf.exp
@@ -0,0 +1,35 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mcore-elf}
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+# Load the generic configuration for this board. This will define a basic set
+# of routines needed by the tool to communicate with the board.
+load_generic_config "mcore"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "-specs=cmb.specs [libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+set_board_info ldscript ""
+set_board_info gdb,start_symbol "_start"
+
+#set_board_info needs_status_wrapper 1
+
+# The GDB protocol used for this target.
+set_board_info gdb_protocol "picobug"
+set_board_info use_gdb_stub 1
+
+# Doesn't pass arguments or signals, can't return results, and doesn't
+# do inferiorio. It can't handle FP, either.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
+set_board_info gdb,skip_float_tests 1
+
+# Increase the timeout
+set timeout 60
diff --git a/dejagnu/baseboards/mcore-moto-sim.exp b/dejagnu/baseboards/mcore-moto-sim.exp
new file mode 100644
index 00000000000..a362f4fffdb
--- /dev/null
+++ b/dejagnu/baseboards/mcore-moto-sim.exp
@@ -0,0 +1,125 @@
+# This is a HACKED version of mcore-sim.exp that is intended to
+# support running tests on Motorola's proprietry MCore simulator.
+
+# It is quite likely that thia file will need to be modified in
+# order for you to use Motorola's simulator.
+
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mcore-elf, mcore-pe}
+
+# Do general config stuff but do not load anything. "jim" was
+# chosen because it does not exist.
+load_generic_config "jim"
+
+process_multilib_options ""
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+
+# No linker script needed.
+set_board_info ldscript "";
+
+# The simulator doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+
+# Doesn't pass arguments or signals, can't return results, and doesn't
+# do inferiorio.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
+
+# Rather than include the normal simulator support files,
+# their functions are reproduced (and modified) here.
+# --------------------------------------------------------------
+proc sim_spawn { dest cmdline args } {
+
+ # Choose whoch simulator to run
+ ## XXX - fixme - this should be automatic based on the
+ ## multilib option.
+ ## XXX - fixme - this should not be hardcoded.
+ set sim "/home/nickc/bin/linux/sim-be"
+# set sim "/home/nickc/bin/linux/sim-le"
+
+ set simflags "-m abi"
+
+ # Create a script to run the program
+ set handle [open doit w]
+ puts $handle "load $cmdline"
+ puts $handle "reset"
+ puts $handle "g 28"
+ puts $handle "quit"
+ close $handle
+
+ return [eval remote_spawn host \{ $sim $simflags "-sdoit" \} $args];
+}
+
+proc sim_wait { dest timeout } {
+ return [remote_wait host $timeout];
+}
+
+proc sim_load { dest prog args } {
+
+ if ![file exists $prog] then {
+ perror "sim.exp: $prog to be downloaded does not exist."
+ verbose -log "$prog to be downloaded does not exist." 3
+ return [list "untested" ""];
+ }
+
+ set sim_time_limit 240
+
+ set output "";
+
+ set res [remote_spawn target "${prog}"];
+
+ if { $res <= 0 } {
+ return [list "fail" "remote_spawn failed"];
+ }
+
+ set state [remote_wait target $sim_time_limit];
+ set status [lindex $state 0];
+ set output [lindex $state 1];
+ verbose "Output is $output";
+
+ set status2 [check_for_board_status output];
+ if { $status2 >= 0 } {
+ set status $status2
+ }
+
+ # FIXME: Do we need to examine $status?
+ # Yes, we do--what if the simulator itself gets an error and coredumps?
+
+ verbose "Return status was: $status" 2
+ if { $status == 0 } {
+ set result "pass"
+ } else {
+ set result "fail"
+ }
+ return [list $result $output];
+}
+
+set_board_info protocol "sim";
+
+# By default, assume the simulator is slow. This causes some tests
+# to either be simplified or skipped completely.
+set_board_info slow_simulator 1
+
+# -----------------------------------------------------------
+# find_sim -- find a usable simulator
+# This proc is local to this file and is used to locate a simulator to use.
+# First we see if SIM=foo was specified on the command line.
+# Otherwise we search the build tree, then $PATH.
+
+proc find_sim { target_alias sim_dir sim_name } {
+
+ ## XXX - fixme - this should not be hardcoded.
+ ## XXX - fixme - this should vary depending upon endianism selected.
+
+ return "/home/nickc/bin/linux/sim-be";
+}
+
+set_board_info is_simulator 1;
diff --git a/dejagnu/baseboards/mcore-pe.exp b/dejagnu/baseboards/mcore-pe.exp
new file mode 100644
index 00000000000..526f674d642
--- /dev/null
+++ b/dejagnu/baseboards/mcore-pe.exp
@@ -0,0 +1,35 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mcore-pe}
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+# Load the generic configuration for this board. This will define a basic set
+# of routines needed by the tool to communicate with the board.
+load_generic_config "mcore"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "-specs=cmb.specs [libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+set_board_info ldscript ""
+set_board_info gdb,start_symbol "_start"
+
+#set_board_info needs_status_wrapper 1
+
+# The GDB protocol used for this target.
+set_board_info gdb_protocol "picobug"
+set_board_info use_gdb_stub 1
+
+# Doesn't pass arguments or signals, can't return results, and doesn't
+# do inferiorio. It can't handle FP, either.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
+set_board_info gdb,skip_float_tests 1
+
+# Increase the timeout
+set timeout 60
diff --git a/dejagnu/baseboards/mcore-sim.exp b/dejagnu/baseboards/mcore-sim.exp
new file mode 100644
index 00000000000..ae863ca11eb
--- /dev/null
+++ b/dejagnu/baseboards/mcore-sim.exp
@@ -0,0 +1,37 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mcore-elf, mcore-pe}
+
+# Load the generic configuration for this board. This will define a basic set
+# of routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# "mcore" is the name of the sim subdir in devo/sim.
+setup_sim mcore
+
+# No multilib options needed by default.
+process_multilib_options ""
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# No linker script needed.
+set_board_info ldscript "";
+
+# The simulator doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+# Doesn't pass arguments or signals, can't return results, and doesn't
+# do inferiorio.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
+set_board_info gdb,skip_float_tests 1
+
+set timeout 45
diff --git a/dejagnu/baseboards/mips-idt.exp b/dejagnu/baseboards/mips-idt.exp
new file mode 100644
index 00000000000..17c6ca86a91
--- /dev/null
+++ b/dejagnu/baseboards/mips-idt.exp
@@ -0,0 +1,31 @@
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "mips-idt";
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]";
+
+# We don't use any multilib options by default.
+process_multilib_options ""
+
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]";
+
+# Use idt.
+if { [board_info $board obj_format] == "ecoff" } {
+ set_board_info ldscript "-Wl,-Tidtecoff.ld";
+} else {
+ set_board_info ldscript "-Wl,-Tidt.ld";
+}
+
+# The idt interface can't return exit statuses, so gcc (ctorture et
+# al) needs to do what it can to get them.
+set_board_info needs_status_wrapper 1;
+
+# GDB needs to use "target mips" to talk to the board.
+set_board_info gdb_protocol "mips";
+
+# And, it can't do arguments, and doesn't have real signals.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
diff --git a/dejagnu/baseboards/mips-lnews-sim.exp b/dejagnu/baseboards/mips-lnews-sim.exp
new file mode 100644
index 00000000000..b4685dfd010
--- /dev/null
+++ b/dejagnu/baseboards/mips-lnews-sim.exp
@@ -0,0 +1,5 @@
+# lnews linker script.
+set_board_info ldscript "-Wl,-Tlnews.ld"
+
+# Otherwise, it's the same as the standard mips simulator.
+load_base_board_description "mips-sim";
diff --git a/dejagnu/baseboards/mips-lsi-sim.exp b/dejagnu/baseboards/mips-lsi-sim.exp
new file mode 100644
index 00000000000..47cae898520
--- /dev/null
+++ b/dejagnu/baseboards/mips-lsi-sim.exp
@@ -0,0 +1,8 @@
+# We need mips16.
+add_multilib_option "-mips16"
+
+# And we use the lsi linker script.
+set_board_info ldscript "-Wl,-Tlsi.ld"
+
+# Otherwise we're the same as the standard MIPS simulator.
+load_base_board_description "mips-sim";
diff --git a/dejagnu/baseboards/mips-sim.exp b/dejagnu/baseboards/mips-sim.exp
new file mode 100644
index 00000000000..104188a6ea1
--- /dev/null
+++ b/dejagnu/baseboards/mips-sim.exp
@@ -0,0 +1,30 @@
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "sim";
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim";
+
+# This tells it which directory to look in for the simulator.
+setup_sim mips;
+
+# No multilib flags are set by default.
+process_multilib_options "";
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]";
+
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]";
+
+# Use idt.
+if { [board_info $board obj_format] == "ecoff" } {
+ set_board_info ldscript "-Wl,-Tidtecoff.ld";
+} else {
+ set_board_info ldscript "-Wl,-Tidt.ld";
+}
+
+# And, it can't do arguments, and doesn't have real signals.
+set_board_info noargs 1;
+set_board_info gdb,nosignals 1;
diff --git a/dejagnu/baseboards/mips64-sim.exp b/dejagnu/baseboards/mips64-sim.exp
new file mode 100644
index 00000000000..3315619c4bf
--- /dev/null
+++ b/dejagnu/baseboards/mips64-sim.exp
@@ -0,0 +1,29 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mips64vr4300-elf
+ mips64-elf}
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "sim";
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim";
+
+# This tells it which directory to look in for the simulator.
+setup_sim mips;
+
+# No multilib flags are set by default.
+process_multilib_options "";
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]";
+
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]";
+# PMON linker script.
+set_board_info ldscript "-Wl,-Tpmon.ld"
+
+# And, it can't do arguments or signals in GDB.
+set_board_info noargs 1;
+set_board_info gdb,nosignals 1;
diff --git a/dejagnu/baseboards/mips64vr4100-sim.exp b/dejagnu/baseboards/mips64vr4100-sim.exp
new file mode 100644
index 00000000000..6e1d5ebadee
--- /dev/null
+++ b/dejagnu/baseboards/mips64vr4100-sim.exp
@@ -0,0 +1,33 @@
+# This is the name of the installed tools for this target.
+set target_install "mips64vr4100-elf"
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+load_lib "libgloss.exp"
+
+# We need this for find_gcc and *_include_flags/*_link_flags.
+load_board_description "basic-sim"
+
+if ![info exists board_info($board,multilib_flags)] {
+ set board_info($board,multilib_flags) "-mips16"
+}
+
+# This tells it which directory to look in for the simulator.
+setup_sim mips
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set board_info($board,compiler) "[find_gcc]"
+set board_info($board,cflags) "[libgloss_include_flags] [newlib_include_flags] [libio_include_flags]"
+set board_info($board,ldflags) "[libgloss_link_flags] [newlib_link_flags] [libio_link_flags]"
+# IDT linker script.
+set board_info($board,ldscript) "-Wl,-Tidt.ld"
+
+# The simulator doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set board_info($board,needs_status_wrapper) 1
+set board_info($board,gdb,noargs) 1
+set_board_info gdb,nosignals 1;
+set_board_info noargs 1;
diff --git a/dejagnu/baseboards/mn10200-cygmon.exp b/dejagnu/baseboards/mn10200-cygmon.exp
new file mode 100644
index 00000000000..1d122e38627
--- /dev/null
+++ b/dejagnu/baseboards/mn10200-cygmon.exp
@@ -0,0 +1,32 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mn10200-elf}
+
+# Load the generic configuration for this board. This will define a
+# set of generic routines used by the tool to communicate with the
+# board.
+load_generic_config "mn10200-eval";
+
+# It needs no multilib flags by default.
+process_multilib_options ""
+
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags] [board_info $board addl_link_flags]";
+
+# CygMON linker script.
+set_board_info ldscript "-Teval.ld"
+
+# Standard remote protocol.
+set_board_info gdb_protocol "remote";
+# We can't do input in GDB (yet! HA!). It *will* do output, hurrah.
+set_board_info gdb,noinferiorio 1;
+# Or pass arguments.
+set_board_info gdb,noargs 1;
+set_board_info noargs 1;
+# Or do signals.
+set_board_info gdb,nosignals 1;
+
+set_board_info shell_prompt "cygmon>"
+
+
+set_board_info use_gdb_stub 1;
diff --git a/dejagnu/baseboards/mn10200-sim.exp b/dejagnu/baseboards/mn10200-sim.exp
new file mode 100644
index 00000000000..2356e3a8e2d
--- /dev/null
+++ b/dejagnu/baseboards/mn10200-sim.exp
@@ -0,0 +1,45 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mn10200-elf}
+
+# Load the tool-specific configuration for this board, as well as the
+# generic configuration. This will define any routines needed by the
+# tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# This is the name of the sim subdir in devo/sim (and in the build tree).
+setup_sim mn10200
+
+# No multilib flags are set by default.
+process_multilib_options ""
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+# We only support newlib on this target.
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+
+# Simulator linker script.
+set_board_info ldscript "-Tsim.ld"
+
+# The simulator doesn't return exit statuses and we need to indicate this.
+set_board_info needs_status_wrapper 1
+
+# We can't pass args to the simulator or get exit status back from the
+# simulator, nor does the simulator support real signals.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
+
+# The mn10200 doesn't support long long data types or double data types.
+set_board_info no_long_long 1
+set_board_info no_double 1
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 4096;
diff --git a/dejagnu/baseboards/mn10300-cygmon.exp b/dejagnu/baseboards/mn10300-cygmon.exp
new file mode 100644
index 00000000000..86c65e1012b
--- /dev/null
+++ b/dejagnu/baseboards/mn10300-cygmon.exp
@@ -0,0 +1,32 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mn10300-elf}
+
+# Load the generic configuration for this board. This will define a
+# set of generic routines used by the tool to communicate with the
+# board.
+load_generic_config "mn10300-eval";
+
+# It needs no multilib flags by default.
+process_multilib_options ""
+
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags] [board_info $board addl_link_flags]";
+
+# CygMON linker script.
+set_board_info ldscript "-Teval.ld"
+
+# Standard remote protocol.
+set_board_info gdb_protocol "remote";
+# We can't do input in GDB (yet! HA!). It *will* do output, hurrah.
+set_board_info gdb,noinferiorio 1;
+# Or pass arguments.
+set_board_info gdb,noargs 1;
+set_board_info noargs 1;
+# Or do signals.
+set_board_info gdb,nosignals 1;
+
+set_board_info shell_prompt "cygmon>"
+
+
+set_board_info use_gdb_stub 1;
diff --git a/dejagnu/baseboards/mn10300-sim.exp b/dejagnu/baseboards/mn10300-sim.exp
new file mode 100644
index 00000000000..eff6a62aaa7
--- /dev/null
+++ b/dejagnu/baseboards/mn10300-sim.exp
@@ -0,0 +1,41 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mn10300-elf}
+
+# Load the tool-specific configuration for this board, as well as the
+# generic configuration. This will define any routines needed by the
+# tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# This is the name of the sim subdir in devo/sim (and in the build tree).
+setup_sim mn10300
+
+# No multilib flags are set by default.
+process_multilib_options ""
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+# We only support newlib on this target.
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+
+# Simulator linker script.
+set_board_info ldscript "-Tsim.ld"
+
+# The simulator doesn't return exit statuses and we need to indicate this.
+set_board_info needs_status_wrapper 1
+
+# We can't pass args to the simulator or get exit status back from the
+# simulator, nor does the simulator support real signals.
+set_board_info noargs 1
+set_board_info gdb,nosignals 1
+set_board_info gdb,noresults 1
+set_board_info gdb,noinferiorio 1
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 4096;
diff --git a/dejagnu/baseboards/msparc-cygmon.exp b/dejagnu/baseboards/msparc-cygmon.exp
new file mode 100644
index 00000000000..55fc4918844
--- /dev/null
+++ b/dejagnu/baseboards/msparc-cygmon.exp
@@ -0,0 +1 @@
+load_base_board_description "cygmon";
diff --git a/dejagnu/baseboards/op50n.exp b/dejagnu/baseboards/op50n.exp
new file mode 100644
index 00000000000..dee8ca3f633
--- /dev/null
+++ b/dejagnu/baseboards/op50n.exp
@@ -0,0 +1,36 @@
+# Load the tool-specific configuration for this board, as well as the
+# generic configuration. This will define any routines needed by the
+# tool to communicate with the board.
+load_generic_config "proelf";
+
+# GDB needs to use "target op50n" to talk to the board.
+set_board_info gdb_protocol "op50n";
+
+if ![board_info $board exists output_format] {
+ set tempfil [lookfor_file $tool_root_dir binutils/objcopy];
+ if { $tempfil != "" } {
+ set_board_info objcopy $tempfil
+ } else {
+ set_board_info objcopy [transform objcopy]
+ }
+ unset tempfil
+}
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]";
+# It's an op50n board.
+set_board_info ldscript "-Wl,-Top50n.ld";
+# The proelf interface has no way to return status information, so we
+# need to indicate this.
+set_board_info needs_status_wrapper 1;
+
+# No support for signals.
+set_board_info gdb,nosignals 1;
+# Nor can we do I/O.
+set_board_info gdb,noinferiorio 1;
+
+# The monitor interface is really slow.
+set_board_info gdb,timeout 540;
diff --git a/dejagnu/baseboards/powerpc-bug.exp b/dejagnu/baseboards/powerpc-bug.exp
new file mode 100644
index 00000000000..2428f727ea1
--- /dev/null
+++ b/dejagnu/baseboards/powerpc-bug.exp
@@ -0,0 +1,29 @@
+load_generic_config "powerpc-bug";
+
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {powerpc-eabi};
+
+# We need mvme by default.
+process_multilib_options "mvme";
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+
+# No linker script needed for this board.
+set_board_info ldscript "";
+
+# Can't pass arguments to programs on this target..
+set_board_info noargs 1
+# And there's no support for signals.
+set_board_info gdb,nosignals 1
+
+# GDB doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+
+# The GDB protocol for this board is...
+set_board_info gdb_protocol "ppcbug"
diff --git a/dejagnu/baseboards/powerpc-bug1.exp b/dejagnu/baseboards/powerpc-bug1.exp
new file mode 100644
index 00000000000..fe256786be6
--- /dev/null
+++ b/dejagnu/baseboards/powerpc-bug1.exp
@@ -0,0 +1,5 @@
+# This config uses ppcbug1 protocol in GDB.
+set_board_info gdb_protocol "ppcbug1"
+
+# But otherwise we're the same as powerpc-bug.
+load_base_board_description "powerpc-bug"
diff --git a/dejagnu/baseboards/powerpc-sim.exp b/dejagnu/baseboards/powerpc-sim.exp
new file mode 100644
index 00000000000..db579e100a8
--- /dev/null
+++ b/dejagnu/baseboards/powerpc-sim.exp
@@ -0,0 +1,28 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {powerpc-eabi}
+
+# Load the generic configuration for this board, This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# The name of the simulator is "ppc".
+setup_sim ppc
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "-msim [libgloss_link_flags] [newlib_link_flags]"
+
+# No support for signals on this target.
+set_board_info gdb,nosignals 1;
+
+# Can't call functions from GDB.
+set_board_info gdb,cannot_call_functions 1
diff --git a/dejagnu/baseboards/powerpcle-sim.exp b/dejagnu/baseboards/powerpcle-sim.exp
new file mode 100644
index 00000000000..20754fa4cc6
--- /dev/null
+++ b/dejagnu/baseboards/powerpcle-sim.exp
@@ -0,0 +1,28 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {powerpcle-eabi}
+
+# Load the generic configuration for this board, This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# The name of the simulator is "ppc".
+setup_sim ppc
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "-msim [libgloss_link_flags] [newlib_link_flags]"
+
+# No support for signals on this target.
+set_board_info gdb,nosignals 1;
+
+# Can't call functions from GDB.
+set_board_info gdb,cannot_call_functions 1
diff --git a/dejagnu/baseboards/rom68k-idp.exp b/dejagnu/baseboards/rom68k-idp.exp
new file mode 100644
index 00000000000..bdf29def7ca
--- /dev/null
+++ b/dejagnu/baseboards/rom68k-idp.exp
@@ -0,0 +1,69 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {m68k-coff m68k-elf};
+
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "rom68k";
+
+# Need soft-float by default.
+process_multilib_options "-msoft-float"
+
+# The compiler used to build for this board. Note that this has nothing to do
+# with what compiler is tested when testing gcc.
+set_board_info compiler "[find_gcc]"
+
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+
+# Nasty hack.
+if { [board_info $board obj_format] == "a.out" } {
+ # Need to pass the start address to objcopy.
+ set_board_info use_vma_offset 1;
+ # Wrapping has to be specially done for m68k-aout, for whatever reason.
+ set_board_info wrap_m68k_aout 1;
+
+ set extra_m68k_ld_flags "-N"
+
+ # We need to tell GDB to load at the correct offset.
+ set_board_info gdb_load_offset [board_info $board hex_startaddr];
+} else {
+ set extra_m68k_ld_flags ""
+}
+
+set_board_info ldflags "$extra_m68k_ld_flags -nostdlib [libgloss_link_flags] [newlib_link_flags]"
+unset extra_m68k_ld_flags
+
+
+# If no output format is specified, use objcopy.
+if ![board_info $board exists output_format] {
+ set tempfil [lookfor_file $tool_root_dir binutils/objcopy];
+ if { $tempfil != "" } {
+ set_board_info objcopy $tempfil
+ } else {
+ set_board_info objcopy [transform objcopy]
+ }
+ unset tempfil
+}
+
+# IDP linker script.
+set_board_info ldscript "-Wl,-Tidp.ld";
+# The idt interface can't return exit statuses, so gcc (ctorture et
+# al) needs to do what it can to get them.
+set_board_info needs_status_wrapper 1;
+
+# GDB needs to use "target rom68k" to talk to the board.
+set_board_info gdb_protocol "rom68k";
+
+# Can't pass arguments to the program under test.
+set_board_info noargs 1
+
+# Nor can it do I/O in GDB.
+set_board_info gdb,noinferiorio 1
+
+# It has no signals.
+set_board_info gdb,nosignals 1
+
+# It can't return results when debugging with GDB.
+set_board_info gdb,noresults 1
+
+# Pseudo-random guess.
+set_board_info sys_speed_value 200;
diff --git a/dejagnu/baseboards/sh-hms-sim.exp b/dejagnu/baseboards/sh-hms-sim.exp
new file mode 100644
index 00000000000..69da8d6582e
--- /dev/null
+++ b/dejagnu/baseboards/sh-hms-sim.exp
@@ -0,0 +1,48 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sh-hms}
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim"
+
+# The name of the directory in the build tree that the simulator lives in
+# is "sh".
+setup_sim sh
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+# We only support newlib on this target.
+# However, we include libgloss so we can find the linker scripts.
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]"
+set_board_info ldflags "[newlib_link_flags]"
+# No linker script for this board.
+set_board_info ldscript "";
+# The simulator doesn't return exit statuses and we need to indicate this.
+# Doesn't work on SH yet.
+# set_board_info needs_status_wrapper 1
+# Can't pass arguments to this target.
+set_board_info noargs 1
+# No signals.
+set_board_info gdb,nosignals 1
+# And it can't call functions.
+set_board_info gdb,cannot_call_functions 1
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 16384
+
+# Need to pass -mieee in order to for the compiler to be IEEE-fp compliant.
+set_board_info ieee_multilib_flags "-mieee";
+
+#We want to pass "18" to GDB"s "targt sim" command.
+set_board_info gdb,target_sim_options "18"
+#and the standalone simulator
+set_board_info sim,options "-m 18"
diff --git a/dejagnu/baseboards/sh-hms.exp b/dejagnu/baseboards/sh-hms.exp
new file mode 100644
index 00000000000..46537071497
--- /dev/null
+++ b/dejagnu/baseboards/sh-hms.exp
@@ -0,0 +1,47 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sh-hms}
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "sh"
+
+# Default to SH2.
+process_multilib_options "-m2"
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]"
+
+# We only support newlib on this target.
+# However, we include libgloss so we can find the linker scripts.
+set_board_info cflags "[newlib_include_flags]"
+set_board_info ldflags "[newlib_link_flags] [libgloss_link_flags]"
+
+# Linker script for the SH2 board.
+set_board_info ldscript "-Wl,-Tsh2lcevb.ld"
+
+# Can't pass arguments to this target.
+set_board_info noargs 1
+# And it can't call functions.
+set_board_info gdb,cannot_call_functions 1
+
+# We use the remote GDB protocol.
+set_board_info gdb_protocol "remote"
+# Jumping to start is how we get the program started in GDB.
+set_board_info gdb_run_command "jump start"
+# The remote target uses a GDB stub.
+set_board_info use_gdb_stub 1
+# We can't do I/O.
+set_board_info gdb,noinferiorio 1
+# Or signals.
+set_board_info gdb,nosignals 1
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 16384
+
+# Exit statuses returned from GDB are sometimes faulty.
+set_board_info exit_statuses_bad 1
+
+# Need to pass -mieee in order to for the compiler to be IEEE-fp compliant.
+set_board_info ieee_multilib_flags "-mieee";
diff --git a/dejagnu/baseboards/sparc64-sim.exp b/dejagnu/baseboards/sparc64-sim.exp
new file mode 100644
index 00000000000..914a571b3c6
--- /dev/null
+++ b/dejagnu/baseboards/sparc64-sim.exp
@@ -0,0 +1,31 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sparc64-elf}
+
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+# We need this for find_gcc and *_include_flags/*_link_flags.
+load_base_board_description "basic-sim"
+
+# Use long64 by default.
+process_multilib_options "long64"
+
+setup_sim sparc64
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# No linker script.
+set_board_info ldscript "";
+
+# Used by a few gcc.c-torture testcases to delimit how large the stack can
+# be.
+set_board_info gcc,stack_size 16384
+# The simulator doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+# We can't pass arguments to programs.
+set_board_info noargs 1
diff --git a/dejagnu/baseboards/sparclet-aout.exp b/dejagnu/baseboards/sparclet-aout.exp
new file mode 100644
index 00000000000..153549cdb3a
--- /dev/null
+++ b/dejagnu/baseboards/sparclet-aout.exp
@@ -0,0 +1,48 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sparclet-aout}
+
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board,.
+load_generic_config "sparclet";
+
+# It needs broken-saverestore by default.
+process_multilib_options "-mbroken-saverestore"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]"
+set_board_info ldflags "-nostdlib [libgloss_link_flags] [newlib_link_flags] -Wl,-Ttext,0x12020000 -N"
+
+# tsc701 linker script.
+set_board_info ldscript "-Ttsc701.ld"
+
+# The board doesn't return exit statuses and we need to indicate this.
+# However, the standard GCC wrapper won't work with this target because
+# it doesn't return stuff from printf ().
+#set_board_info needs_status_wrapper 1
+
+# The monitor uses a GDB stub.
+set_board_info use_gdb_stub 1
+# The GDB protocol used to communicate with this board.
+set_board_info gdb_protocol "sparclet"
+# The offset in memory that we load programs.
+set_board_info gdb_load_offset "0x12020000"
+# And the place in memory where we load the stub.
+set_board_info gdb_stub_offset "0x12010000"
+# No mathlib.
+set_board_info mathlib "";
+# We can't do I/O in GDB.
+set_board_info gdb,noinferiorio 1;
+# Or pass arguments.
+set_board_info noargs 1;
+
+set_board_info gcc,no_varargs 1
+set_board_info gcc,no_label_values 1
+
+# This is the old GDB prompt for the toolchain.
+# Uncomment for old tests
+set_board_info gdb_prompt "\\(gdb\\)";
+
+# We always have to set a breakpoint at exit(), instead of just _exit().
+set_board_info always_break_exit 1;
diff --git a/dejagnu/baseboards/sparclite-coff.exp b/dejagnu/baseboards/sparclite-coff.exp
new file mode 100644
index 00000000000..61eafc466c2
--- /dev/null
+++ b/dejagnu/baseboards/sparclite-coff.exp
@@ -0,0 +1,41 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sparclite-coff}
+
+# Load the generic configuration for this board. This will define a
+# set of generic routines used by the tool to communicate with the
+# board.
+load_generic_config "slite";
+
+# It needs no multilib flags by default.
+process_multilib_options ""
+
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "-nostdlib [libgloss_link_flags] [newlib_link_flags] -Wl,-Ttext,0x40005000 -N";
+
+# ex930 linker script.
+set_board_info ldscript "-Tex930.ld";
+
+# The address at which the stub needs to be linked.
+set_board_info gdb_stub_offset "0x40000000";
+
+# The board doesn't return exit statuses and we need to indicate this.
+# However, the standard GCC wrapper won't work with this target because
+# it doesn't return stuff from printf ().
+set_board_info needs_status_wrapper 1;
+
+# We use a GDB stub to talk to the board.
+set_board_info use_gdb_stub 1;
+# For GDB, we need to use a real stub (not the separate loader scheme
+# we use for Sparclet).
+set_board_info gdb_stub "";
+# And the protocol is "sparclite serial".
+set_board_info gdb_protocol "sparclite serial";
+# No mathlib.
+set_board_info mathlib "";
+# We can't do I/O in GDB.
+set_board_info gdb,noinferiorio 1;
+# Or pass arguments.
+set_board_info noargs 1;
+# Or do signals.
+set_board_info gdb,nosignals 1;
diff --git a/dejagnu/baseboards/sparclite-cygmon.exp b/dejagnu/baseboards/sparclite-cygmon.exp
new file mode 100644
index 00000000000..956881e01b5
--- /dev/null
+++ b/dejagnu/baseboards/sparclite-cygmon.exp
@@ -0,0 +1,6 @@
+if { [board_info $board obj_format] == "a.out" } {
+ set_board_info addl_link_flags "-N"
+ set_board_info gdb_load_offset "0x40050000"
+}
+
+load_base_board_description "cygmon"
diff --git a/dejagnu/baseboards/sparclite-sim-le.exp b/dejagnu/baseboards/sparclite-sim-le.exp
new file mode 100644
index 00000000000..5daec2e6f11
--- /dev/null
+++ b/dejagnu/baseboards/sparclite-sim-le.exp
@@ -0,0 +1,47 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sparclite-elf}
+
+# Load the generic configuration for this board. This will define a
+# set of generic routines used by the tool to communicate with the
+# board.
+load_generic_config "sim";
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim";
+
+if ![info exists board_info($board,multilib_flags)] {
+ set board_info($board,multilib_flags) "-mlittle-endian-data"
+}
+
+# This tells it which directory to look in for the simulator.
+setup_sim erc32;
+
+# It needs no multilib flags by default.
+process_multilib_options ""
+
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "-nostdlib -nostartfiles [libgloss_link_flags] [newlib_link_flags]";
+
+# ELF simulator linker script.
+set_board_info ldscript "-Telfsim.ld";
+
+# The simulator doesn't return exit statuses and we need to indicate this.
+set_board_info needs_status_wrapper 1;
+
+# We use a GDB stub to talk to the board.
+# set_board_info use_gdb_stub 1;
+# For GDB, we need to use a real stub (not the separate loader scheme
+# we use for Sparclet).
+# set_board_info gdb_stub "";
+# No mathlib.
+# set_board_info mathlib "";
+# We can't do I/O in GDB.
+# set_board_info gdb,noinferiorio 1;
+# Or pass arguments.
+set_board_info noargs 1;
+# Or do signals.
+set_board_info gdb,nosignals 1;
+
+#We want to specify the sparclite emulator in GDB.
+set_board_info gdb,target_sim_options "-sparclite"
diff --git a/dejagnu/baseboards/sparclite-sim.exp b/dejagnu/baseboards/sparclite-sim.exp
new file mode 100644
index 00000000000..a977fface83
--- /dev/null
+++ b/dejagnu/baseboards/sparclite-sim.exp
@@ -0,0 +1,37 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sparclite-elf}
+
+# Load the generic configuration for this board. This will define a
+# set of generic routines used by the tool to communicate with the
+# board.
+load_generic_config "sim";
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim";
+
+# This tells it which directory to look in for the simulator.
+setup_sim erc32;
+
+# It needs no multilib flags by default.
+process_multilib_options ""
+
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "-nostdlib -nostartfiles [libgloss_link_flags] [newlib_link_flags]";
+
+# ELF simulator linker script.
+set_board_info ldscript "-Telfsim.ld";
+
+# The simulator doesn't return exit statuses and we need to indicate this.
+set_board_info needs_status_wrapper 1;
+
+# We can't pass arguments.
+set_board_info noargs 1;
+# Or do signals.
+set_board_info gdb,nosignals 1;
+
+# We want to specify the sparclite emulator in GDB.
+set_board_info gdb,target_sim_options "-sparclite"
+
+# Pass -a -sparclite to the standalone simulator
+set_board_info sim,options "-a -sparclite"
diff --git a/dejagnu/baseboards/strongarm-cygmon.exp b/dejagnu/baseboards/strongarm-cygmon.exp
new file mode 100644
index 00000000000..8e41199cc3d
--- /dev/null
+++ b/dejagnu/baseboards/strongarm-cygmon.exp
@@ -0,0 +1,41 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {strongarm-elf}
+
+# Load the generic configuration for this board. This will define a
+# set of generic routines used by the tool to communicate with the
+# board.
+load_generic_config "cygmon";
+
+# It needs no multilib flags by default.
+process_multilib_options ""
+
+set_board_info compiler "[find_gcc]";
+set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags] [board_info $board addl_link_flags]";
+
+# CygMON linker script.
+
+if {[string compare [board_info $board boardtype] "sa1100dp"] == 0} {
+ set_board_info ldscript "-specs=sa1100dp.specs"
+} elseif {[string compare [board_info $board boardtype] "sa1100mm"] == 0} {
+ set_board_info ldscript "-specs=sa1100mm.specs"
+} elseif {[string compare [board_info $board boardtype] "sa-iop"] == 0} {
+ set_board_info ldscript "-specs=sa-iop.specs"
+} elseif {[string compare [board_info $board boardtype] "ebsa-285"] == 0} {
+ set_board_info ldscript "-specs=ebsa-285.specs"
+}
+
+# Standard remote protocol.
+set_board_info gdb_protocol "remote";
+# We can't do input in GDB (yet! HA!). It *will* do output, hurrah.
+set_board_info gdb,noinferiorio 1;
+# Or pass arguments.
+set_board_info gdb,noargs 1;
+set_board_info noargs 1;
+# Or do signals.
+set_board_info gdb,nosignals 1;
+
+set_board_info shell_prompt "cygmon>"
+
+set_board_info use_gdb_stub 1;
+set_board_info use_cygmon 1
diff --git a/dejagnu/baseboards/tic80-sim.exp b/dejagnu/baseboards/tic80-sim.exp
new file mode 100644
index 00000000000..dc2cecccd53
--- /dev/null
+++ b/dejagnu/baseboards/tic80-sim.exp
@@ -0,0 +1,28 @@
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "sim";
+
+# basic-sim.exp is a basic description for the standard Cygnus simulator.
+load_base_board_description "basic-sim";
+
+# This tells it which directory to look in for the simulator.
+setup_sim tic80;
+
+# No multilib flags are set by default.
+process_multilib_options "";
+
+# The compiler used to build for this board. This has *nothing* to do
+# with what compiler is tested if we're testing gcc.
+set_board_info compiler "[find_gcc]";
+
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]";
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]";
+# No linker script is needed.
+# set_board_info ldscript "";
+
+# And, it can't do arguments, and doesn't have real signals.
+set_board_info noargs 1;
+set_board_info gdb,nosignals 1;
+
+# Used by a few gcc.c-torture testcases when trampolines are used.
+set_board_info gcc,no_varargs 1
diff --git a/dejagnu/baseboards/tx39-dve.exp b/dejagnu/baseboards/tx39-dve.exp
new file mode 100644
index 00000000000..8973e4333a0
--- /dev/null
+++ b/dejagnu/baseboards/tx39-dve.exp
@@ -0,0 +1,48 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mips-tx39-elf mips-elf}
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+if { [board_info $board cygmon] == "yes" } {
+ load_generic_config "cygmon";
+} else {
+ load_generic_config "dve";
+}
+
+# It's a big-endian board.
+process_multilib_options "big-endian"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# DDB linker script.
+set_board_info ldscript "-Wl,-Tdve.ld";
+
+# GDB doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1;
+
+# The GDB protocol used with this board.
+if { [board_info $board cygmon] == "yes" } {
+ set_board_info gdb_protocol "remote"
+} else {
+ set_board_info gdb_protocol "r3900"
+}
+
+# This is needed for compiling nullstone.
+set_board_info nullstone,lib "mips-clock.c"
+set_board_info nullstone,ticks_per_sec 3782018
+
+# Sometimes the board gets into a state where it always generates SIGFPE.
+#set_board_info unreliable 1
+
+# Can't pass arguments to the program.
+set_board_info noargs 1
+
+# No support for signals.
+set_board_info gdb,nosignals 1
+
+# We need to clear the floating-point status register before running.
+#set_board_info gdb_init_command "print/x \$fsr = 0x0"
diff --git a/dejagnu/baseboards/tx39-sim.exp b/dejagnu/baseboards/tx39-sim.exp
new file mode 100644
index 00000000000..8af99128273
--- /dev/null
+++ b/dejagnu/baseboards/tx39-sim.exp
@@ -0,0 +1,8 @@
+# We need mips16.
+add_multilib_option ""
+
+# And we use the lsi linker script.
+set_board_info ldscript "-Wl,-Tdve.ld"
+
+# Otherwise we're the same as the standard MIPS simulator.
+load_base_board_description "mips-sim";
diff --git a/dejagnu/baseboards/unix.exp b/dejagnu/baseboards/unix.exp
new file mode 100644
index 00000000000..98d1ec1edf7
--- /dev/null
+++ b/dejagnu/baseboards/unix.exp
@@ -0,0 +1,8 @@
+# The canonical unix board description.
+load_generic_config "unix";
+
+process_multilib_options "";
+
+set_board_info compiler "[find_gcc]";
+
+set_board_info bmk,use_alarm 1;
diff --git a/dejagnu/baseboards/usparc-cygmon.exp b/dejagnu/baseboards/usparc-cygmon.exp
new file mode 100644
index 00000000000..f827c60d281
--- /dev/null
+++ b/dejagnu/baseboards/usparc-cygmon.exp
@@ -0,0 +1,48 @@
+load_base_board_description "cygmon";
+
+set_board_info testcase_timeout 30;
+
+proc ${board}_init { dest } {
+ global usparc_init_count;
+ set shell_prompt [board_info $dest shell_prompt];
+
+ if ![info exists usparc_init_count] {
+ set usparc_init_count 0;
+ } else {
+ incr usparc_init_count;
+ if { $usparc_init_count == 3 } {
+ return -1;
+ }
+
+ }
+ remote_close $dest;
+ set shell_id [remote_open $dest];
+ if { $shell_id == "" || $shell_id < 0 } {
+ return [remote_reboot $dest];
+ } else {
+ remote_binary $dest;
+ remote_send $dest "\n";
+ set got_one 0;
+ remote_expect $dest 5 {
+ -re "$shell_prompt" { set got_one 1; exp_continue; }
+ default {
+ if { ! $got_one } {
+ remote_close $dest;
+ return [remote_reboot $dest];
+ }
+ }
+ }
+ remote_send $dest "m \[15\]1fff1001f00 32\n";
+ remote_expect $dest 5 {
+ -re "$shell_prompt" {
+ unset usparc_init_count;
+ remote_close $dest;
+ return 0;
+ }
+ default {
+ remote_close $dest;
+ return [remote_reboot $dest];
+ }
+ }
+ }
+}
diff --git a/dejagnu/baseboards/v850-sim.exp b/dejagnu/baseboards/v850-sim.exp
new file mode 100644
index 00000000000..cb7a70a8072
--- /dev/null
+++ b/dejagnu/baseboards/v850-sim.exp
@@ -0,0 +1,31 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {v850-elf}
+
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "sim"
+
+# We need this for find_gcc and *_include_flags/*_link_flags.
+load_base_board_description "basic-sim"
+
+# No multilib flags needed for this target.
+process_multilib_options ""
+
+setup_sim v850
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# DDB linker script.
+set_board_info ldscript "";
+
+# The simulator doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+# We can't pass arguments to programs.
+set_board_info noargs 1
+
+# And we don't support signals.
+set_board_info gdb,nosignals 1
diff --git a/dejagnu/baseboards/vr4100-ddb.exp b/dejagnu/baseboards/vr4100-ddb.exp
new file mode 100644
index 00000000000..e959a6626f8
--- /dev/null
+++ b/dejagnu/baseboards/vr4100-ddb.exp
@@ -0,0 +1,33 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mips64vr4100-elf mips64-elf}
+
+# It's a little-endian board.
+process_multilib_options "-EL -msoft-float"
+
+set_board_info startaddr "a0020000"
+set_board_info hex_startaddr "0xa0020000"
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "vr4100"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# DDB linker script.
+set_board_info ldscript "-Wl,-Tpmon.ld"
+
+# GDB doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+
+# The GDB protocol used with this board.
+set_board_info gdb_protocol "ddb"
+
+set_board_info reboot_delay 10
+
+# This board is unreliable. If a test times out, the board should be
+# rebooted and the test re-run.
+set_board_info unreliable 1
diff --git a/dejagnu/baseboards/vr4100-sim.exp b/dejagnu/baseboards/vr4100-sim.exp
new file mode 100644
index 00000000000..c3b278aa603
--- /dev/null
+++ b/dejagnu/baseboards/vr4100-sim.exp
@@ -0,0 +1,12 @@
+# DDB linker script.
+if { [board_info $board obj_format] == "ecoff" } {
+ set_board_info ldscript "-Wl,-Tddbecoff.ld"
+} else {
+ set_board_info ldscript "-Wl,-Tddb.ld"
+}
+
+# And the simulator doesn't reliably return exit statuses.
+set_board_info needs_status_wrapper 1
+
+# Otherwise, we're a standard MIPS config.
+load_base_board_description "mips64-sim";
diff --git a/dejagnu/baseboards/vr4111-sim.exp b/dejagnu/baseboards/vr4111-sim.exp
new file mode 100644
index 00000000000..c3b278aa603
--- /dev/null
+++ b/dejagnu/baseboards/vr4111-sim.exp
@@ -0,0 +1,12 @@
+# DDB linker script.
+if { [board_info $board obj_format] == "ecoff" } {
+ set_board_info ldscript "-Wl,-Tddbecoff.ld"
+} else {
+ set_board_info ldscript "-Wl,-Tddb.ld"
+}
+
+# And the simulator doesn't reliably return exit statuses.
+set_board_info needs_status_wrapper 1
+
+# Otherwise, we're a standard MIPS config.
+load_base_board_description "mips64-sim";
diff --git a/dejagnu/baseboards/vr4300-ddb.exp b/dejagnu/baseboards/vr4300-ddb.exp
new file mode 100644
index 00000000000..a25afb85033
--- /dev/null
+++ b/dejagnu/baseboards/vr4300-ddb.exp
@@ -0,0 +1,19 @@
+# Danger, Will Robinson! Settings in this file do not override
+# previous settings for the board being defined.
+
+# DDB linker script.
+if { [board_info $board obj_format] == "ecoff" } {
+ set_board_info ldscript "-Wl,-Tddbecoff.ld"
+} else {
+ set_board_info ldscript "-Wl,-Tddb.ld"
+}
+
+# This is needed for compiling nullstone.
+set_board_info nullstone,lib "mips-clock.c"
+set_board_info nullstone,ticks_per_sec 3782018
+
+# The GDB protocol used with this board.
+set_board_info gdb_protocol "ddb"
+
+# Otherwise, we're the same as a generic vr4300 board.
+load_base_board_description "vr4300";
diff --git a/dejagnu/baseboards/vr4300-sim.exp b/dejagnu/baseboards/vr4300-sim.exp
new file mode 100644
index 00000000000..c3b278aa603
--- /dev/null
+++ b/dejagnu/baseboards/vr4300-sim.exp
@@ -0,0 +1,12 @@
+# DDB linker script.
+if { [board_info $board obj_format] == "ecoff" } {
+ set_board_info ldscript "-Wl,-Tddbecoff.ld"
+} else {
+ set_board_info ldscript "-Wl,-Tddb.ld"
+}
+
+# And the simulator doesn't reliably return exit statuses.
+set_board_info needs_status_wrapper 1
+
+# Otherwise, we're a standard MIPS config.
+load_base_board_description "mips64-sim";
diff --git a/dejagnu/baseboards/vr4300.exp b/dejagnu/baseboards/vr4300.exp
new file mode 100644
index 00000000000..a89f943e180
--- /dev/null
+++ b/dejagnu/baseboards/vr4300.exp
@@ -0,0 +1,41 @@
+# Danger, Will Robinson! Settings in this file do not override
+# previous settings for the board being defined.
+
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mips64vr4300-elf mips64-elf}
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "vr4300"
+
+# It's a little-endian board.
+process_multilib_options "little-endian"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# IDT linker script.
+set_board_info ldscript "-Wl,-Tidt.ld"
+
+# GDB doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1
+
+# The GDB protocol used with this board.
+set_board_info gdb_protocol "mips"
+
+# This board is unreliable. If a test times out, the board should be
+# rebooted and the test re-run.
+set_board_info unreliable 1
+
+# Can't pass arguments to the program.
+set_board_info noargs 1
+
+# No support for signals.
+set_board_info gdb,nosignals 1
+
+# We need to clear the floating-point status register before running.
+# This command will be sent after connecting to the board.
+set_board_info gdb_init_command "print/x \$fsr = 0x0"
diff --git a/dejagnu/baseboards/vr5000-ddb.exp b/dejagnu/baseboards/vr5000-ddb.exp
new file mode 100644
index 00000000000..8cf4b0f8856
--- /dev/null
+++ b/dejagnu/baseboards/vr5000-ddb.exp
@@ -0,0 +1,40 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mips64vr5000-elf mips64-elf}
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines needed by the tool to communicate with the board.
+load_generic_config "vr5000";
+
+# It's a big-endian board.
+process_multilib_options "big-endian"
+
+# We only support newlib on this target. We assume that all multilib
+# options have been specified before we get here.
+set_board_info compiler "[find_gcc]"
+set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+# DDB linker script.
+set_board_info ldscript "-Wl,-Tddb.ld";
+
+# GDB doesn't return exit statuses and we need to indicate this;
+# the standard GCC wrapper will work with this target.
+set_board_info needs_status_wrapper 1;
+
+# The GDB protocol used with this board.
+set_board_info gdb_protocol "ddb";
+
+# This is needed for compiling nullstone.
+set_board_info nullstone,lib "mips-clock.c"
+set_board_info nullstone,ticks_per_sec 3782018
+
+# Sometimes the board gets into a state where it always generates SIGFPE.
+set_board_info unreliable 1
+
+# Can't pass arguments to the program.
+set_board_info noargs 1
+
+# No support for signals.
+set_board_info gdb,nosignals 1
+
+# We need to clear the floating-point status register before running.
+set_board_info gdb_init_command "print/x \$fsr = 0x0"
diff --git a/dejagnu/baseboards/vx4300.exp b/dejagnu/baseboards/vx4300.exp
new file mode 100644
index 00000000000..2547b1cc145
--- /dev/null
+++ b/dejagnu/baseboards/vx4300.exp
@@ -0,0 +1,25 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {mips-vxworks5.3}
+
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "vxworks";
+
+# No multilib flags by default.
+process_multilib_options "";
+
+# The compiler used to build for this board. Note that this has nothing to do
+# with what compiler is tested when testing gcc.
+set_board_info compiler "[find_gcc]";
+
+# These are probably wrong.
+set_board_info cflags "-EL";
+# vxworks 5.1 needs the executable to be relinkable.
+set_board_info ldflags "-nostdlib -r";
+set_board_info libs "-lgcc";
+
+# No linker script needed.
+set_board_info ldscript "";
+
+# GDB needs to use "target vxworks" to talk to the board.
+set_board_info gdb_protocol "vxworks";
diff --git a/dejagnu/baseboards/vx68k.exp b/dejagnu/baseboards/vx68k.exp
new file mode 100644
index 00000000000..d79f5bd0600
--- /dev/null
+++ b/dejagnu/baseboards/vx68k.exp
@@ -0,0 +1,25 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {m68k-vxworks5.1 m68k-vxworks5.2}
+
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "vxworks";
+
+# No multilib flags by default.
+process_multilib_options "";
+
+# The compiler used to build for this board. Note that this has nothing to do
+# with what compiler is tested when testing gcc.
+set_board_info compiler "[find_gcc]";
+
+# These are probably wrong.
+set_board_info cflags "";
+# vxworks 5.1 needs the executable to be relinkable.
+set_board_info ldflags "-nostdlib -r";
+set_board_info libs "-lgcc";
+
+# No linker script needed.
+set_board_info ldscript "";
+
+# GDB needs to use "target vxworks" to talk to the board.
+set_board_info gdb_protocol "vxworks";
diff --git a/dejagnu/baseboards/vx960.exp b/dejagnu/baseboards/vx960.exp
new file mode 100644
index 00000000000..e25c79dafcb
--- /dev/null
+++ b/dejagnu/baseboards/vx960.exp
@@ -0,0 +1,29 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {i960-vxworks5.1 i960-vxworks5.2}
+
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "vxworks";
+
+# No multilib flags by default.
+process_multilib_options "";
+
+# The compiler used to build for this board. Note that this has nothing to do
+# with what compiler is tested when testing gcc.
+set_board_info compiler "[find_gcc]";
+
+# These are probably wrong, but at least it is configurable now.
+if { [board_info $board cpu] == "I960CA" } {
+ set_board_info cflags "-mca";
+} else {
+ set_board_info cflags "";
+}
+# vxworks 5.1 needs the executable to be relinkable.
+set_board_info ldflags "-nostdlib -r";
+set_board_info libs "-lgcc";
+
+# No linker script needed.
+set_board_info ldscript "";
+
+# GDB needs to use "target vxworks" to talk to the board.
+set_board_info gdb_protocol "vxworks";
diff --git a/dejagnu/baseboards/vxsparc.exp b/dejagnu/baseboards/vxsparc.exp
new file mode 100644
index 00000000000..c943e70f98e
--- /dev/null
+++ b/dejagnu/baseboards/vxsparc.exp
@@ -0,0 +1,25 @@
+# This is a list of toolchains that are supported on this board.
+set_board_info target_install {sparc-vxworks5.1 sparc-vxworks5.2}
+
+# Load the generic configuration for this board. This will define any
+# routines needed by the tool to communicate with the board.
+load_generic_config "vxworks";
+
+# No multilib flags by default.
+process_multilib_options "";
+
+# The compiler used to build for this board. Note that this has nothing to do
+# with what compiler is tested when testing gcc.
+set_board_info compiler "[find_gcc]";
+
+# These are probably right.
+set_board_info cflags "";
+# vxworks 5.1 needs the executable to be relinkable.
+set_board_info ldflags "-nostdlib -r";
+set_board_info libs "-lgcc";
+
+# No linker script needed.
+set_board_info ldscript "";
+
+# GDB needs to use "target vxworks" to talk to the board.
+set_board_info gdb_protocol "vxworks";
diff --git a/dejagnu/baseboards/x86-cygmon.exp b/dejagnu/baseboards/x86-cygmon.exp
new file mode 100644
index 00000000000..45f2422b79a
--- /dev/null
+++ b/dejagnu/baseboards/x86-cygmon.exp
@@ -0,0 +1,11 @@
+load_base_board_description "cygmon";
+
+# Default to ELF.
+if { [board_info $board obj_format] == "a.out" } {
+ set_board_info gdb,start_symbol "_start"
+} elseif { [board_info $board obj_format] == "coff" } {
+ set_board_info gdb,start_symbol "__start"
+} else {
+ set_board_info gdb,start_symbol "__start"
+}
+
diff --git a/dejagnu/config.guess b/dejagnu/config.guess
new file mode 100755
index 00000000000..500098f14a1
--- /dev/null
+++ b/dejagnu/config.guess
@@ -0,0 +1,960 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+#
+# This file 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# 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.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >dummy.s
+ .globl main
+ .ent main
+main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
+ amiga:NetBSD:*:*)
+ echo m68k-cbm-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ arm32:NetBSD:*:*)
+ echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:NetBSD:*:*)
+ echo m68k-atari-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:NetBSD:*:*)
+ echo m68k-sun-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:NetBSD:*:*)
+ echo m68k-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >dummy.c
+ int main (argc, argv) int argc; char **argv; {
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy \
+ && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i?86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:4)
+ if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=4.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ *9??*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ 9000/[3478]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/6?? ) HP_ARCH=hppa1.0 ;;
+ 9000/78? ) HP_ARCH=hppa1.1 ;; # FIXME: really hppa2.0
+ 9000/7?? ) HP_ARCH=hppa1.1 ;;
+ 9000/8[67]1 | 9000/80[24] | 9000/8[78]9 | 9000/893 )
+ HP_ARCH=hppa1.1 ;; # FIXME: really hppa2.0
+ 9000/8?[13679] ) HP_ARCH=hppa1.1 ;;
+ 9000/8?? ) HP_ARCH=hppa1.0 ;;
+ esac
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
+ hp3[0-9][05]:NetBSD:*:*)
+ echo m68k-hp-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:NetBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin32
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin32
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:Linux:*:*)
+ # uname on the ARM produces all sorts of strangeness, and we need to
+ # filter it out.
+ case "$UNAME_MACHINE" in
+ arm* | sa110*) UNAME_MACHINE="arm" ;;
+ esac
+
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us.
+ ld_help_string=`ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
+ i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
+ sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ elf32ppc)
+ # Determine Lib Version
+ cat >dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#if defined(__GLIBC__)
+ printf("%s %s\n", __libc_version, __libc_release);
+#else
+ printf("unkown\n");
+#endif
+ return 0;
+}
+EOF
+ LIBC=""
+ ${CC-cc} dummy.c -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy | grep 1\.99 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f dummy.c dummy
+ echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ sed 's/^ //' <<EOF >dummy.s
+ .globl main
+ .ent main
+ main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ LIBC=""
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+
+ objdump --private-headers dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >dummy.c <<EOF
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i?86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i?86:*:5:7)
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+# 5.0.4c returns "Pent II". 5.0.5 returns PentII
+ (/bin/uname -X|egrep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|egrep '^Machine.*PentII' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pent II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ pc:*:*:*)
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i?86:LynxOS:2.*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+ printf ("vax-dec-bsd\n"); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/dejagnu/config/README b/dejagnu/config/README
new file mode 100644
index 00000000000..caedebd9fe9
--- /dev/null
+++ b/dejagnu/config/README
@@ -0,0 +1,34 @@
+The files in this directory define a basic set of functionality for each
+board. They are loaded by calling "load_generic_config", normally done
+as part of the baseboard description for a given board.
+
+This functionality is a partial replacement for the tool-specific
+configuration previously found in the testsuite/config directory. Note
+that no tool-specific actions are defined here; they still need to be
+defined by the tool-specific config files. However, for tools that
+simply wish to download and execute programs on a board, the
+functionality here should be sufficient.
+
+The functions that can be defined are:
+
+${board}_open
+${board}_close
+${board}_exec
+${board}_binary
+${board}_reboot
+${board}_download
+${board}_upload
+${board}_transmit
+${board}_send
+${board}_file
+${board}_spawn
+${board}_load
+
+Normally these functions are invoked indirectly by the testcases when
+they invoke the remote_xxx version of the function.
+
+The ${board}_xxx functions will be called in preference to the default
+versions (or the ones specified by the "connect" protocol in the board
+description). However, the version defined by the "connect" protocol
+are still accessible by calling remote_raw_xxx, which will ignore any
+board-specific or generic versions of these functions.
diff --git a/dejagnu/config/arc.exp b/dejagnu/config/arc.exp
new file mode 100644
index 00000000000..3fffb06ca0d
--- /dev/null
+++ b/dejagnu/config/arc.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/arm-ice.exp b/dejagnu/config/arm-ice.exp
new file mode 100644
index 00000000000..3fffb06ca0d
--- /dev/null
+++ b/dejagnu/config/arm-ice.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/base-config.exp b/dejagnu/config/base-config.exp
new file mode 100644
index 00000000000..2cd95813dbd
--- /dev/null
+++ b/dejagnu/config/base-config.exp
@@ -0,0 +1,48 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+#
+# reboot_hook -- called to reboot a target board. Returns 1 on
+# success, 0 otherwise.
+#
+proc reboot_via_x10 { dest } {
+ if [board_info $dest exists name] {
+ set dest [board_info $dest name];
+ }
+
+ if [board_info $dest exists x10] {
+ set x10 [board_info $dest x10];
+ verbose "rebooting x10 unit $x10" 1
+ rsh_exec rtl "/usr/unsupported/bin/x10-hellcab unit $x10 off"
+ sleep 2
+ rsh_exec rtl "/usr/unsupported/bin/x10-hellcab unit $x10 on"
+ sleep 2
+ return 1;
+ }
+ return 0;
+}
+
+proc ${board}_reboot { args } {
+ if { [llength $args] > 0} {
+ set dest [lindex $args 0];
+ } else {
+ set dest target;
+ }
+ return [reboot_via_x10 $dest];
+}
diff --git a/dejagnu/config/base68k.exp b/dejagnu/config/base68k.exp
new file mode 100644
index 00000000000..d105ce8632a
--- /dev/null
+++ b/dejagnu/config/base68k.exp
@@ -0,0 +1,323 @@
+# Copyright (C) 1994, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Bob Manson (manson@cygnus.com)
+# based on earlier work by JT Conklin (jtc@cygnus.com)
+
+#
+# base68k_load -- load the program and execute it
+#
+
+proc base68k_ld { dest prog } {
+ global tmpdir
+
+ set shell_prompt [board_info $dest shell_prompt]
+
+ if ![file exists $prog] then {
+ verbose -log "$prog does not exist."
+ return "untested"
+ }
+ if [is_remote host] {
+ set prog [remote_download host $prog];
+ if { $prog == "" } {
+ verbose -log "Unable to download $prog to host.";
+ return "untested";
+ }
+ }
+
+ if [board_info $dest exists objcopy] {
+ set OBJCOPY [board_info $dest objcopy];
+ set exec_file "${prog}.srec"
+ set objcopy_args ""
+ if [board_info $dest exists use_vma_offset] {
+ set objcopy_args "--adjust-vma=[board_info $dest hex_startaddr]";
+ }
+ set status [remote_exec host "$OBJCOPY $objcopy_args -O srec $prog ${prog}.srec"]
+ set result [lindex $status 1];
+ regsub -all -- "\[\r\n\]*" $result "" result
+ if { $result != "" || [lindex $status 0] != 0 } {
+ warning "Got \"$result\" from $OBJCOPY"
+ verbose -log "Couldn't convert to srecord for downloading"
+ remote_close $dest;
+ return "untested"
+ } else {
+ verbose "Converted $prog to an srecord." 2
+ }
+ } else {
+ set exec_file $prog
+ }
+
+ set value 0;
+ if ![board_info $dest exists fileid] {
+ while { $value < 2 } {
+ set rom68k_shell_id [remote_open $dest]
+ if { $rom68k_shell_id < 0 } {
+ if { $value > 0 || ![remote_reboot $dest] } {
+ verbose -log "$prog not executed, couldn't connect to target."
+ return "untested"
+ }
+ incr value;
+ } else {
+ break;
+ }
+ }
+ # dbug has problems if we go into binary mode, so this allows us to
+ # disable entry into binary mode.
+ if ![board_info $dest exists no_binary_mode] {
+ remote_binary $dest;
+ }
+ }
+
+ # if we built the srecord on a remote host, copy it back here so we
+ # can load it
+ if [is_remote host] {
+ global objdir
+ set exec_file [remote_upload host ${exec_file} "${objdir}/a.out"];
+ }
+
+ set got_p 0;
+ for { set tries 0; } { (! $got_p) && $tries < 5 } { incr tries } {
+ remote_send $dest "\r\n\r\n"
+ remote_expect $dest 5 {
+ -re "${shell_prompt}$" {
+ verbose "Got prompt."
+ set result 0
+ set got_p 1;
+ }
+ timeout {
+ warning "Never got prompt."
+ }
+ }
+ if { ! $got_p } {
+ if $tries<=4 then {
+ if { $tries == 3 } then {
+ remote_reboot $dest;
+ } else {
+ remote_send $dest "\r\n"
+ }
+ }
+ }
+ }
+
+ # We need to do this in case the connection to the remote side is
+ # scrogged -- the remote_expect above will fail in a lot of
+ # non-clean ways.
+ if { ! $got_p } {
+ remote_close $dest;
+ remote_reboot $dest;
+ return "unresolved";
+ } else {
+ # Flush out any remaining cruft.
+ remote_expect $dest 2 {
+ timeout { }
+ -re ".+" { exp_continue }
+ default { }
+ }
+ }
+
+ if [board_info $dest exists download_command] {
+ # Load the program.
+ remote_send $dest "\r\n";
+ # dbug has problems sending download command immediately after a
+ # newline, so we wait for the prompt to come back first.
+ remote_expect $dest 5 {
+ -re "${shell_prompt}$" {
+ verbose -log "Got prompt."
+ }
+ timeout {
+ warning "Never got prompt."
+ }
+ }
+ remote_send $dest [board_info $dest download_command]
+ if [board_info $dest exists download_response] {
+ remote_expect $dest 5 {
+ [board_info $dest download_response] { }
+ timeout {
+ perror "Download command never responded."
+ return "unresolved";
+ }
+ }
+ }
+ }
+
+ verbose "Writing records to target..."
+ set status [remote_transmit $dest $exec_file];
+ if { $exec_file != $prog } {
+ remote_file build delete $exec_file
+ }
+ if { $status != 0 } {
+ remote_close $dest;
+ verbose -log "Transmission of $exec_file to the target failed." 3
+ return "unresolved"
+ }
+ verbose "Wrote records to target...waiting for prompt."
+ remote_send $dest "\n"
+ set got_p 0;
+ remote_expect $dest 50 {
+ -re "$shell_prompt$" {
+ verbose "Got prompt."
+ set got_p 1;
+ }
+ timeout { }
+ }
+ if { $got_p } {
+ # Flush any remaining cruft. 2 seconds may be too long, dunno.
+ remote_expect $dest 2 {
+ timeout { }
+ -re ".+" { exp_continue }
+ default { }
+ }
+ return "pass";
+ } else {
+ remote_close $dest;
+ remote_reboot $dest;
+ return "unresolved";
+ }
+
+}
+
+
+proc base68k_spawn { dest prog args } {
+ set shell_prompt [board_info $dest shell_prompt];
+
+ set result [remote_ld $dest $prog];
+ if { $result != "pass" } {
+ return [list $result ""];
+ }
+
+ if [board_info $dest exists startaddr] {
+ set go_command "[board_info $dest go_command] [board_info $dest startaddr]";
+ } else {
+ set go_command "[board_info $dest go_command]";
+ }
+
+ verbose "Sending $go_command, waiting for results.";
+ remote_send $dest "${go_command}\n";
+ return { "pass" "" };
+}
+
+proc base68k_wait { dest timeout } {
+ set shell_prompt [board_info $dest shell_prompt];
+ set noappend 0;
+ set result -1;
+
+ set output "";
+
+ remote_expect $dest $timeout {
+ -re [board_info $dest go_response] {
+ append output $expect_out(buffer);
+ set noappend 1;
+ set result 0;
+ exp_continue -continue_timer;
+ }
+ -re "$shell_prompt$" {
+ verbose "Got prompt.";
+ set result 0;
+ }
+ -re "\[\r\n\]+" {
+ if { ! $noappend } {
+ append output $expect_out(buffer);
+ if { [string length $output] < 512000 } {
+ exp_continue -continue_timer;
+ } else {
+ set result -1;
+ }
+ }
+ }
+ timeout {
+ warning "Nothing ever came back.";
+ set result -1;
+ }
+ }
+
+ if [board_info $dest exists output_end] {
+ regsub "[board_info $dest output_end]" "$output" "\n" output;
+ }
+
+ # There has got to be a better way. (We need to do this in order to remove
+ # the echoed "go command".
+ if [board_info $dest exists startaddr] {
+ set go_command "[board_info $dest go_command] [board_info $dest startaddr]";
+ } else {
+ set go_command "[board_info $dest go_command]";
+ }
+
+ regsub "^.*$go_command\[\r\n\]*" "$output" "" output;
+ regsub "^.*$go_command\[\r\n\]*" "$output" "" output;
+
+ # We always want to check for a status, even if there was a funky weird
+ # failure above.
+ set status [check_for_board_status output];
+ if { $result == 0 } {
+ set result $status;
+ verbose -log "exit status was $status";
+ }
+ # A negative value indicates that we should reboot. Otherwise, return
+ # the exit status from the program if we got one (and we should have).
+ return [list $result "$output"];
+}
+
+proc base68k_load { dest prog args } {
+ global base68k_retry
+
+ set shell_prompt [board_info $dest shell_prompt];
+
+ if { [llength $args] > 0 } {
+ for { set x 0; } { $x < [llength $args] } { incr x ; } {
+ if { [lindex $args $x] != "" } {
+ verbose -log "Cannot pass parameters or input file to this target";
+ return [list "unsupported" ""];
+ }
+ }
+ }
+
+ set result [remote_spawn $dest $prog];
+ if { [lindex $result 0] != "pass" } {
+ return $result;
+ }
+
+ # FIXME: The value 360 below should be a parameter.
+
+ set result [remote_wait $dest 360];
+ set output [lindex $result 1];
+ set status [lindex $result 0];
+
+ verbose "output from board is $output"
+
+ # Make sure there's a newline before the PASS/FAIL/whatever for the log.
+ send_log "\n"
+
+ if { $status > 0 } {
+ return [list "fail" $output];
+ } elseif { $status == 0 } {
+ return [list "pass" $output];
+ } else {
+ if [info exists base68k_retry] {
+ return [list "fail" $output];
+ }
+ set base68k_retry 1;
+ remote_reboot $dest;
+ set status [eval base68k_load \{$dest\} \{$prog\} $args];
+ unset base68k_retry;
+ return $status;
+ }
+}
+
+set_board_info protocol "base68k";
+set_board_info send_initial_cr 1
diff --git a/dejagnu/config/bug.exp b/dejagnu/config/bug.exp
new file mode 100644
index 00000000000..881ecccb3c2
--- /dev/null
+++ b/dejagnu/config/bug.exp
@@ -0,0 +1,29 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Bob Manson (manson@cygnus.com).
+
+load_generic_config "base68k";
+
+set_board_info shell_prompt "\[0-9\]+Bug>"
+set_board_info download_command "lo 0\r"
+set_board_info download_response "lo 0.*"
+set_board_info go_command "go"
+set_board_info go_response "\*\*\*EXIT code.*"
+set_board_info startaddr "10000"
diff --git a/dejagnu/config/cfdbug.exp b/dejagnu/config/cfdbug.exp
new file mode 100644
index 00000000000..2db0ac739eb
--- /dev/null
+++ b/dejagnu/config/cfdbug.exp
@@ -0,0 +1,31 @@
+# Copyright (C) 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Bob Manson (manson@cygnus.com).
+
+load_generic_config "base68k";
+
+set_board_info shell_prompt "dBUG> *"
+set_board_info download_command "dl\r\n"
+set_board_info download_response "*Escape to local*"
+set_board_info go_command "go"
+set_board_info go_response "\[*\]\[*\]\[*\] EXIT code \[^\r\n\]*\[\r\n\]"
+set_board_info startaddr "10000"
+set_board_info hex_startaddr "0x10000"
+set_board_info no_binary_mode 1
diff --git a/dejagnu/config/cygmon.exp b/dejagnu/config/cygmon.exp
new file mode 100644
index 00000000000..2378a12eb82
--- /dev/null
+++ b/dejagnu/config/cygmon.exp
@@ -0,0 +1,22 @@
+# Copyright (C) 1997, 1998 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb-comm";
+
+set_board_info send_initial_cr 1;
diff --git a/dejagnu/config/d10v.exp b/dejagnu/config/d10v.exp
new file mode 100644
index 00000000000..3fffb06ca0d
--- /dev/null
+++ b/dejagnu/config/d10v.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/ddb-ether.exp b/dejagnu/config/ddb-ether.exp
new file mode 100644
index 00000000000..140c0d2ca60
--- /dev/null
+++ b/dejagnu/config/ddb-ether.exp
@@ -0,0 +1,190 @@
+# Copyright (C) 1997, 1998 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Bob Manson (manson@cygnus.com)
+
+# Reset the prompt to what GDB needs.
+proc ${board}_init { dest } {
+ global doing_ddb_init;
+
+ if ![info exists doing_ddb_init] {
+ set doing_ddb_init 1;
+
+ remote_close $dest;
+ for { set x 0; } { $x < 3 } { incr x; } {
+ set shell_id [remote_open $dest];
+ if { $shell_id == "" || $shell_id < 0 } {
+ remote_reboot $dest;
+ } else {
+ break;
+ }
+ }
+
+ set shell_prompt [board_info $dest shell_prompt];
+
+ remote_send $dest "\n";
+ remote_expect $dest 10 {
+ -re ".*PMON> $" {
+ remote_send $dest "set prompt \"$shell_prompt\"\n";
+ exp_continue;
+ }
+ -re ".*${shell_prompt}$" { }
+ }
+ remote_close $dest;
+ unset doing_ddb_init;
+ } else {
+ return;
+ }
+}
+
+proc ddb_ether_load { dest prog args } {
+ for { set x 0; } { $x < 3 } { incr x } {
+ set result [eval remote_spawn \{$dest\} \{$prog\} $args];
+ if { $result < 0 } {
+ remote_reboot $dest;
+ } else {
+ set result [remote_wait $dest 300];
+ set status [lindex $result 0];
+ set output [lindex $result 1];
+ if { $status >= 0 } {
+ if { $status > 0 } {
+ return [list "fail" $output];
+ } else {
+ return [list "pass" $output];
+ }
+ }
+ }
+ }
+ return [list "fail" ""];
+}
+
+proc ddb_ether_ld { dest prog } {
+ if ![board_info $dest exists tftpdir] {
+ perror "Must set_board_info tftpdir for [board_info $dest name]";
+ return "fail";
+ }
+
+ if ![board_info $dest exists fileid] {
+ set spawn_id [remote_open $dest];
+ if { $spawn_id == "" || $spawn_id < 0 } {
+ return "retry";
+ }
+ remote_binary $dest;
+ }
+
+ set shell_prompt [board_info $dest shell_prompt];
+
+ remote_send $dest "\n";
+ remote_expect $dest 10 {
+ -re ".*${shell_prompt}$" { }
+ default {
+ return "retry";
+ }
+ }
+ set basename "a.out.[pid]";
+ set file "[board_info $dest tftpdir]/$basename";
+ set file [remote_download build $prog $file];
+ if { $file == "" } {
+ perror "download to tftp area failed";
+ return "fail";
+ }
+ set state "pass";
+
+ remote_send $dest "boot /$basename\n";
+ set tries 0;
+ remote_expect $dest 30 {
+ -re "Loading.*Entry address is.*${shell_prompt}$" { }
+ -re "invalid executable.*${shell_prompt}$" {
+ incr tries;
+ if { $tries < 3 } {
+ sleep 2;
+ remote_send $dest "boot /$basename\n";
+ exp_continue;
+ }
+ }
+ -re ".*${shell_prompt}$" {
+ set state "fail";
+ }
+ default {
+ set state "fail";
+ }
+ }
+ remote_file build delete $file;
+ if { $state == "fail" } {
+ return $state;
+ }
+ return "pass";
+}
+
+proc ddb_ether_spawn { dest prog args } {
+ set state [ddb_ether_ld $dest $prog];
+
+ if { $state != "pass" } {
+ return -1;
+ }
+ remote_send $dest "g\n";
+ remote_expect $dest 5 {
+ -re "g\[\r\n\]\[\r\n\]?" { }
+ default { }
+ }
+
+ return [board_info $dest fileid];
+}
+
+proc ddb_ether_wait { dest timeout } {
+ set output "";
+ set shell_prompt [board_info $dest shell_prompt];
+
+ remote_expect $dest $timeout {
+ -re "^g\[\r\n\]\[\r\n\]?" {
+ if { $output != "" } {
+ append output $expect_out(buffer);
+ }
+ exp_continue;
+ }
+ -re "(.*)$shell_prompt" {
+ append output $expect_out(1,string);
+ set status [check_for_board_status output];
+ if { $status > 0 } {
+ return [list $status $output];
+ } else {
+ if [regexp "Exception Cause=" $output] {
+ remote_reboot $dest;
+ return [list -1 $output];
+ }
+ return [list 0 $output];
+ }
+ }
+ -re "\[\r\n\]+" {
+ append output $expect_out(buffer);
+ if { [string length $output] < 512000 } {
+ exp_continue;
+ } else {
+ return [list -1 ""];
+ }
+ }
+ default {
+ return [list -1 ""];
+ }
+ }
+}
+
+set_board_info send_initial_cr 1
+set_board_info protocol "ddb_ether"
+set_board_info shell_prompt "NEC010> "
diff --git a/dejagnu/config/ddb.exp b/dejagnu/config/ddb.exp
new file mode 100644
index 00000000000..13a18e0dc08
--- /dev/null
+++ b/dejagnu/config/ddb.exp
@@ -0,0 +1,96 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Bob Manson (manson@cygnus.com)
+
+# We use GDB to talk to a vr4300 board.
+load_generic_config "base68k";
+
+set_board_info shell_prompt "NEC010> ";
+set_board_info download_command "load tty0\n";
+set_board_info download_response "Downloading from";
+set_board_info go_command "g -e";
+set_board_info startaddr "a0100000"
+set_board_info hex_startaddr "0xa0100000"
+set_board_info go_response "(^|\[\r\n\])(Exception Cause|\[0-9a-z\]+ \[0-9a-z\]+ break|\\*\\*\\*EXIT code )\[^\r\n\]*\[\r\n\]"
+set_board_info output_end "\[\r\n\](Exception Cause|\[0-9a-z\]+ \[0-9a-z\]+ break).*$"
+
+# Reset the prompt to what GDB needs.
+proc ${board}_init { dest } {
+ global doing_ddb_init;
+ if [is_remote host] {
+ return;
+ }
+
+ if ![info exists doing_ddb_init] {
+ set doing_ddb_init 1;
+
+ for { set i 1; } { $i <= 3 } {incr i } {
+ remote_close $dest;
+ for { set x 0; } { $x < 3 } { incr x; } {
+ set shell_id [remote_open $dest];
+ if { $shell_id == "" || $shell_id < 0 } {
+ remote_reboot $dest;
+ } else {
+ break;
+ }
+ }
+
+ set count 0;
+ remote_send $dest "\n";
+ remote_expect $dest 20 {
+ -re ".*PMON> $" {
+ remote_send $dest "set prompt \"NEC010> \"\n";
+ exp_continue;
+ }
+ -re "NEC010> $" {
+ set i 10;
+ }
+ timeout { }
+ -re "0x0" {
+ count++;
+ if(count<5) {
+ exp_continue;
+ }
+ }
+ }
+ if { $i < 3 } {
+ remote_reboot $dest;
+ }
+ }
+ remote_close $dest;
+ unset doing_ddb_init;
+ } else {
+ return;
+ }
+}
+
+set_board_info send_initial_cr 1
+set_board_info dont_wait_for_prompt 1
+
+# If no output format is specified, use objcopy.
+if ![board_info $board exists output_format] {
+ set tempfil [lookfor_file $tool_root_dir binutils/objcopy];
+ if { $tempfil != "" } {
+ set_board_info objcopy $tempfil
+ } else {
+ set_board_info objcopy [transform objcopy]
+ }
+ unset tempfil
+}
diff --git a/dejagnu/config/dos.exp b/dejagnu/config/dos.exp
new file mode 100644
index 00000000000..d1b440da76d
--- /dev/null
+++ b/dejagnu/config/dos.exp
@@ -0,0 +1,484 @@
+# Copyright (C) 1997, 1998, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Bob Manson (manson@cygnus.com)
+
+#
+# Open a connection to the remote DOS host.
+#
+proc dos_open { dest args } {
+ global destbat_num
+
+ if ![info exists destbat_num] {
+ set destbat_num [pid];
+ }
+ if { [board_info $dest conninfo] == "" } {
+ global board_info;
+ set name [board_info $dest name];
+
+ set board_info($name,conninfo) "b${destbat_num}.bat";
+ incr destbat_num;
+ }
+
+ if [board_info $dest exists fileid] {
+ return [board_info $dest fileid];
+ }
+
+ verbose "doing a dos_open to $dest"
+
+ set shell_prompt [board_info $dest shell_prompt];
+
+ set shell_id [remote_raw_open $dest];
+
+ if { $shell_id == "" || $shell_id < 0 } {
+ return -1;
+ }
+
+ if [board_info $dest exists init_command] {
+ remote_send $dest "[board_info $dest init_command]\n";
+ remote_expect $dest 10 {
+ -re "$shell_prompt" { }
+ default {
+ perror "failed connection to DOS on $dest."
+ return -1;
+ }
+ }
+ }
+
+ if [board_info $dest exists ftp_directory] {
+ set dir [board_info $dest ftp_directory];
+ regsub -all "/" "$dir" "\\" dir;
+ remote_send $dest "cd $dir\n";
+ remote_expect $dest 10 {
+ -re "$shell_prompt" { }
+ default {
+ perror "failed connection to DOS on $dest."
+ return -1;
+ }
+ }
+ }
+
+ if [board_info $dest exists dos_dir] {
+ set dos_dir [board_info $dest dos_dir];
+ regsub -all "^(\[a-zA-Z]:).*$" "$dos_dir" "\\1" drive;
+ regsub -all "^\[a-zA-Z]:" "$dos_dir" "" dos_dir;
+ remote_send $dest "${drive}\n";
+ remote_expect $dest 10 {
+ -re "$shell_prompt" { }
+ default {
+ perror "failed connection to DOS on $dest."
+ return -1;
+ }
+ }
+ remote_send $dest "cd $dos_dir\n";
+ remote_expect $dest 10 {
+ -re "$shell_prompt" { }
+ default {
+ perror "failed connection to DOS on $dest."
+ return -1;
+ }
+ }
+ }
+
+ global target_alias
+ if [info exists target_alias] {
+ set talias $target_alias;
+ } else {
+ set talias "foo-bar"
+ }
+
+ global board_info;
+ if [board_info $dest exists name] {
+ set n [board_info $dest name];
+ } else {
+ set n $dest;
+ }
+ set board_info($n,fileid) $shell_id;
+
+ if [board_info $dest exists init_script] {
+ remote_exec $dest "[board_info $dest init_script] $talias"
+ }
+
+ verbose "Succeeded in connecting to DOS."
+ return $shell_id;
+}
+
+#
+# Close the connection to the remote host. If we're telnetting there, we
+# need to exit the connection first (ataman telnetd gets confused otherwise).
+#
+proc dos_close { dest args } {
+ if [board_info $dest exists fileid] {
+ if { [board_info $dest connect] == "telnet" } {
+ remote_send $dest "exit\n";
+ sleep 2;
+ }
+ return [remote_raw_close $dest];
+ }
+}
+
+proc dos_prep_command { dest cmdline } {
+ global board_info;
+
+ set name [board_info $dest name];
+ set shell_id [remote_open "$dest"];
+
+ set localbat "/tmp/b[pid].bat";
+ set remotebat [board_info $dest conninfo];
+
+ verbose "opened"
+ if { $shell_id != "" && $shell_id >= 0 } {
+ set fileid [open "$localbat" "w"];
+ puts -nonewline $fileid "@echo off\r\n$cmdline\r\nif errorlevel 1 echo *** DOSEXIT code 1\r\nif not errorlevel 1 echo *** DOSEXIT code 0\r\n";
+ close $fileid;
+ set result [remote_download $dest $localbat $remotebat];
+ } else {
+ set result ""
+ }
+ remote_file build delete $localbat;
+ return $result;
+}
+
+#
+# Run CMDLINE on DESTHOST. We handle two cases; one is where we're at
+# a DOS prompt, and the other is where we're in GDB.
+# We run CMDLINE by creating a batchfile, downloading it, and then
+# executing it; this handles the case where the commandline is too
+# long for command.com to deal with.
+#
+
+proc dos_exec { dest program pargs inp outp } {
+ set cmdline "$program $pargs"
+
+ set shell_prompt [board_info $dest shell_prompt];
+
+ if { $inp != "" } {
+ set inp [remote_download $dest $inp inpfile];
+ if { $inp != "" } {
+ set inp " < $inp";
+ }
+ }
+
+ if { $outp != "" } {
+ set outpf " > tempout";
+ } else {
+ set outpf "";
+ }
+
+ verbose "cmdline is $cmdline$inp." 2
+
+ # Make a DOS batch file; we use @echo off so we don't have to see
+ # the DOS command prompts and such.
+ for { set i 0; } { $i < 2 } { incr i } {
+ set exit_status -1;
+ verbose "calling open"
+ set batfile [dos_prep_command $dest "$cmdline$inp$outpf"];
+ if { $batfile != "" } {
+ if { [dos_start_command $batfile $dest] == "" } {
+ # FIXME: The 300 below should be a parameter.
+ set result [remote_wait $dest 300];
+ set exit_status [lindex $result 0];
+ set output [lindex $result 1];
+ }
+ }
+ if { $exit_status >= 0 } {
+ if { $outp != "" } {
+ remote_upload $dest tempout $outp;
+ remote_file $dest delete tempout;
+ }
+ return [list $exit_status $output];
+ }
+ if { $exit_status != -2 } {
+ remote_close $dest;
+ remote_reboot $dest;
+ }
+ }
+ return [list -1 "program execution failed"];
+}
+
+#
+# Start CMDLINE executing on DEST.
+# There are two cases that we handle, one where we're at a DOS prompt
+# and the other is when the remote machine is running GDB.
+#
+
+proc dos_start_command { cmdline dest } {
+ set shell_prompt [board_info $dest shell_prompt];
+ set prefix ""
+ set ok 0;
+ for {set i 0;} {$i <= 2 && ! $ok} {incr i;} {
+ set shell_id [remote_open $dest];
+ if { $shell_id != "" && $shell_id > 0 } {
+ remote_send $dest "echo k\r";
+ remote_expect $dest 20 {
+ -re "\\(gdb\\)" {
+ set shell_prompt "\\(gdb\\)";
+ # gdb uses 'shell command'.
+ set prefix "shell ";
+ set ok 1;
+ }
+ -re "$shell_prompt" {
+ set ok 1;
+ }
+ default { }
+ }
+ }
+ if { ! $ok } {
+ remote_close $dest;
+ remote_reboot $dest;
+ }
+ }
+ if { ! $ok } {
+ return "unable to start command"
+ } else {
+ remote_send $dest "${prefix}${cmdline}\n";
+ remote_expect $dest 2 {
+ -re "${cmdline}\[\r\n\]\[\r\n\]?" { }
+ timeout { }
+ }
+ return "";
+ }
+}
+
+#
+# Send STRING to DEST, translating all LFs to CRs first, and sending one
+# line at a time because of strangeness with telnet in some circumstances.
+#
+
+proc dos_send { dest string } {
+ verbose "Sending '$string' to $dest" 2
+ # Convert LFs to CRs, 'cause that is what DOS wants to see.
+ set first 1
+ set string [string trimright $string "\r\n"]
+ foreach line [split $string "\r\n"] {
+ if {$first} {
+ set first 0
+ } else {
+ # small delay between lines, to keep from
+ # overwhelming the stupid telnet server.
+ sleep 1.0
+ }
+ remote_raw_send $dest "$line\r"
+ }
+}
+
+#
+# Spawn PROGRAM on DEST, and return the spawn_id associated with the
+# connection; we can only spawn one command at a time.
+#
+
+proc dos_spawn { dest program args } {
+ verbose "running $program on $dest"
+ set remotebat [dos_prep_command $dest $program];
+
+ for { set x 0; } { $x < 3 } { incr x } {
+ if { [dos_start_command $remotebat $dest] == "" } {
+ return [board_info $dest fileid];
+ }
+ remote_close $dest;
+ remote_reboot $dest;
+ }
+ return -1;
+}
+
+proc dos_wait { dest timeout } {
+ set output "";
+ set shell_prompt [board_info $dest shell_prompt];
+ set status 1;
+
+ verbose "waiting in dos_wait";
+ remote_expect $dest $timeout {
+ -re "(.*)\[*\]\[*\]\[*\] DOSEXIT code (\[0-9\]+)\[\r\n\]\[\r\n\]?" {
+ verbose "got exit status";
+ append output $expect_out(1,string);
+ set status $expect_out(2,string);
+ exp_continue;
+ }
+
+ -re "(.*)${shell_prompt}" {
+ append output $expect_out(1,string);
+ verbose "output from dos is:'$output'";
+ return [list $status $output];
+ }
+
+ -re "(.*)\\(gdb\\)" {
+ append output $expect_out(1,string);
+ return [list $status $output];
+ }
+
+ -re "In.*cygwin.*except" {
+ remote_close $dest;
+ remote_reboot $dest;
+ return [list -2 $output];
+ }
+
+ -re "\[\r\n\]+" {
+ # This is a bit obscure. We only want to put whole
+ # lines into the output string, because otherwise we
+ # might miss a prompt because we only got 1/2 of it the
+ # first time 'round. The other tricky bit is that
+ # expect_out(buffer) will contain everything before and including
+ # the matched pattern.
+ append output $expect_out(buffer);
+ exp_continue -continue_timer;
+ }
+
+ timeout {
+ warning "timeout in dos_wait";
+ if { [dos_interrupt_job $dest] == "" } {
+ return [list 1 $output];
+ }
+ }
+
+ eof {
+ warning "got EOF from dos host.";
+ }
+ }
+
+ remote_close $dest;
+
+ return [list -1 $output];
+}
+
+proc dos_load { dest prog args } {
+ global dos_dll_loaded;
+ set progargs "";
+ set inpfile "";
+ if { [llength $args] > 0 } {
+ set progargs [lindex $args 1];
+ }
+ if { [llength $args] > 1 } {
+ set inpfile [lindex $args 1];
+ }
+ if ![info exists dos_dll_loaded] {
+ if ![is_remote host] {
+ global target_alias;
+
+ set comp [get_multilibs];
+ if [file exists "${comp}/winsup/new-cygwin1.dll"] {
+ set dll "${comp}/winsup/new-cygwin1.dll";
+ set dll_name "cygwin1.dll";
+ } elseif [file exists "${comp}/winsup/new-cygwin.dll"] {
+ set dll "${comp}/winsup/new-cygwin.dll";
+ set dll_name "cygwin.dll";
+ } elseif [file exists ${comp}/lib/cygwin1.dll] {
+ set dll "${comp}/lib/cygwin1.dll";
+ set dll_name "cygwin1.dll";
+ } elseif [file exists ${comp}/lib/cygwin.dll] {
+ set dll "${comp}/lib/cygwin.dll";
+ set dll_name "cygwin.dll";
+ } else {
+ error "couldn't find cygwin.dll:$comp"
+ return "fail";
+ }
+ remote_download $dest $dll $dll_name
+ }
+ set dos_dll_loaded 1;
+ }
+ set remote_prog [remote_download $dest $prog "aout.exe"];
+ set result [remote_exec $dest $remote_prog $progargs $inpfile];
+ set status [lindex $result 0];
+ set output [lindex $result 1];
+ set status2 [check_for_board_status output];
+ if { $status2 >= 0 } {
+ set status $status2;
+ }
+ if { $status != 0 } {
+ set status "fail";
+ } else {
+ set status "pass";
+ }
+ return [list $status $output];
+}
+
+proc dos_file { dest op args } {
+ switch $op {
+ delete {
+ foreach x $args {
+ remote_exec $dest "del" "$x";
+ }
+ return;
+
+ }
+ default {
+ return [eval standard_file \{$dest\} \{$op\} $args];
+ }
+ }
+}
+
+#
+# Interrupt the current spawned command being run; the only tricky
+# part is that we have to handle the "Terminate batch job" prompt.
+#
+proc dos_interrupt_job { host } {
+ set shell_prompt [board_info $host shell_prompt];
+
+ remote_send $host "\003";
+ remote_expect $host 10 {
+ -re "Terminate batch job.*Y/N\[)\]\[?\] *$" {
+ remote_send $host "n\n";
+ exp_continue;
+ }
+ -re "$shell_prompt" {
+ return "";
+ }
+ -re ">" {
+ remote_send $host "\n";
+ exp_continue;
+ }
+ }
+ return "fail";
+}
+
+proc dos_copy_download { host localfile remotefile } {
+ remote_file build delete "[board_info $host local_dir]/$remotefile";
+ if [remote_file build exists $localfile] {
+ set result [remote_download build $localfile "[board_info $host local_dir]/$remotefile"];
+ if { $result != "" } {
+ remote_exec build "chmod" "a+rw $result";
+ return $remotefile;
+ }
+ } else {
+ return ""
+ }
+}
+
+proc dos_copy_upload { host remotefile localfile } {
+ remote_file build delete $localfile;
+ if [file exists "[board_info $host local_dir]/$remotefile"] {
+ set result [remote_download build "[board_info $host local_dir]/$remotefile" $localfile];
+ } else {
+ set result "";
+ }
+ if { $result != "" } {
+ remote_exec build "chmod" "a+rw $result";
+ return $result;
+ }
+}
+
+proc dos_copy_file { dest op args } {
+ if { $op == "delete" } {
+ set file "[board_info $dest local_dir]/[lindex $args 0]";
+ remote_file build delete $file;
+ }
+}
+
+set_board_info protocol "dos";
+set_board_info shell_prompt "(^|\[\r\n\])\[a-zA-Z\]:\[^\r\n\]*>\[ \t\]*$";
+set_board_info needs_status_wrapper 1
diff --git a/dejagnu/config/dve.exp b/dejagnu/config/dve.exp
new file mode 100644
index 00000000000..3582b5b311a
--- /dev/null
+++ b/dejagnu/config/dve.exp
@@ -0,0 +1,22 @@
+# Copyright (C) 1998 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gcc@prep.ai.mit.edu
+
+# For Densan MIPS boards we use gdb to load and execute programs.
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/gdb-comm.exp b/dejagnu/config/gdb-comm.exp
new file mode 100644
index 00000000000..3f4fffcb803
--- /dev/null
+++ b/dejagnu/config/gdb-comm.exp
@@ -0,0 +1,566 @@
+# Copyright (C) 1996, 1997, 1998 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Note: some of this was cribbed from the gdb testsuite since we need
+# to use some pretty standard gdb features (breakpoints in particular).
+
+# Load up some standard junk.
+load_lib remote.exp
+
+if ![info exists board] {
+ perror "$board must be set before loading gdb-comm"
+}
+
+# The number of times we've tried to download/execute this executable.
+set try_again 0
+
+#
+# Delete all breakpoints and verify that they were deleted. If anything
+# goes wrong, return -1.
+#
+proc gdb_comm_delete_breakpoints {} {
+ global gdb_prompt
+
+ remote_send host "delete breakpoints\n";
+ remote_expect host 10 {
+ -re "Delete all breakpoints.*y or n. $" {
+ remote_send host "y\n"
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" { }
+ timeout { perror "Delete all breakpoints (timeout)" ; return -1}
+ }
+ remote_send host "info breakpoints\n"
+ remote_expect host 10 {
+ -re "No breakpoints or watchpoints..*$gdb_prompt $" {}
+ -re ".*$gdb_prompt $" { perror "breakpoints not deleted" ; return -1}
+ timeout { perror "info breakpoints (timeout)" ; return -1}
+ }
+ return 0;
+}
+
+#
+# Inform the debugger that we have a new exec file.
+# return a -1 if anything goes wrong, 0 on success.
+#
+proc gdb_comm_file_cmd { arg } {
+ global verbose
+ global loadpath
+ global loadfile
+ global GDB
+ global gdb_prompt
+ upvar timeout timeout
+
+ # The "file" command loads up a new symbol file for gdb, deal with
+ # the various messages it might spew out.
+ if [is_remote host] {
+ set arg [remote_download host $arg a.out];
+ }
+ remote_send host "file $arg\n"
+ remote_expect host 60 {
+ -re "Reading symbols from.*done.*$gdb_prompt $" {
+ verbose "\t\tLoaded $arg into the $GDB"
+ return 0
+ }
+ -re "has no symbol-table.*$gdb_prompt $" {
+ perror "$arg wasn't compiled with \"-g\""
+ return -1
+ }
+ -re "A program is being debugged already.*Kill it.*y or n. $" {
+ remote_send host "y\n"
+ verbose "\t\tKilling previous program being debugged"
+ exp_continue
+ }
+ -re "Load new symbol table from \".*\".*y or n.*$" {
+ remote_send host "y\n"
+ remote_expect host 60 {
+ -re "Reading symbols from.*done.*$gdb_prompt $" {
+ verbose "\t\tLoaded $arg with new symbol table into $GDB"
+ return 0
+ }
+ timeout {
+ perror "(timeout) Couldn't load $arg, other program already loaded."
+ return -1
+ }
+ }
+ }
+ -re ".*No such file or directory.*$gdb_prompt $" {
+ perror "($arg) No such file or directory\n"
+ return -1
+ }
+ -re "$gdb_prompt $" {
+ perror "couldn't load $arg into $GDB."
+ return -1
+ }
+ timeout {
+ perror "couldn't load $arg into $GDB (timed out)."
+ return -1
+ }
+ eof {
+ # This is an attempt to detect a core dump, but seems not to
+ # work. Perhaps we need to match .* followed by eof, in which
+ # expect does not seem to have a way to do that.
+ perror "couldn't load $arg into $GDB (end of file)."
+ return -1
+ }
+ }
+ return 0;
+}
+
+# Disconnect from the target and forget that we have an executable. Returns
+# -1 on failure, 0 on success.
+
+proc gdb_comm_go_idle { } {
+ global gdb_prompt;
+
+ if ![board_info host exists fileid] {
+ return -1;
+ }
+
+ remote_send host "target exec\n";
+ remote_expect host 10 {
+ -re "Kill it.*y or n.*$" {
+ remote_send host "y\n"
+ exp_continue;
+ }
+ -re "No exec.* file now.*$gdb_prompt $" {
+ return 0;
+ }
+ default {
+ remote_close host;
+ return -1;
+ }
+ }
+}
+
+# Start GDB running with target DEST.
+proc gdb_comm_start { dest } {
+ global GDB
+ global gdb_prompt
+ global tool_root_dir
+
+ # The variable gdb_prompt is a regexp which matches the gdb prompt. Set it
+ # if it is not already set.
+ if ![board_info $dest exists gdb_prompt] then {
+ set gdb_prompt "\\(gdb\\)"
+ } else {
+ set gdb_prompt [board_info $dest gdb_prompt];
+ }
+ # Similarly for GDB. Look in the object directory for gdb if we aren't
+ # provided with one.
+ if ![info exists GDB] then {
+ set GDB "[lookfor_file ${tool_root_dir} gdb/gdb]"
+ if { $GDB == "" } {
+ set GDB [transform gdb]
+ }
+ }
+ if [board_info host exists gdb_opts] {
+ set gdb_opts [board_info host gdb_opts];
+ } else {
+ set gdb_opts ""
+ }
+ # Start up gdb (no startfiles, no windows) and wait for a prompt.
+ remote_spawn host "$GDB $gdb_opts -nw -nx";
+ remote_expect host 60 {
+ -re ".*$gdb_prompt $" { }
+ }
+ remote_send host "set height 0\n";
+ remote_expect host 10 {
+ -re ".*$gdb_prompt $" {}
+ }
+ remote_send host "set width 0\n";
+ remote_expect host 10 {
+ -re ".*$gdb_prompt $" {}
+ }
+}
+
+# Add a breakpoint at function FUNCTION. We assume that GDB has already been
+# started.
+proc gdb_comm_add_breakpoint { function } {
+ global gdb_prompt
+
+ remote_send host "break $function\n"
+ remote_expect host 60 {
+ -re "Breakpoint.*$gdb_prompt $" { return "" }
+ -re "Function.*not defined.*$gdb_prompt $" { return "undef" }
+ -re "No symbol table.*$gdb_prompt $" { return "undef" }
+ default {
+ return "untested"
+ }
+ }
+}
+
+#
+# quit_gdb -- try to quit GDB gracefully
+#
+
+proc quit_gdb { } {
+ global gdb_prompt;
+
+ set spawn_id [board_info host fileid];
+
+ if { $spawn_id != "" && $spawn_id > -1 } {
+ if { [remote_send host "quit\n"] == "" } {
+ remote_expect host 10 {
+ -re ".*y or n.*$" {
+ remote_send host "y\n";
+ exp_continue;
+ }
+ -re ".*\[*\]\[*\]\[*\].*EXIT code" { }
+ default { }
+ }
+ }
+ }
+ if ![is_remote host] {
+ remote_close host;
+ }
+}
+
+proc gdb_comm_leave { } {
+ if [is_remote host] {
+ quit_gdb;
+ } else {
+ gdb_comm_go_idle;
+ }
+}
+#
+# gdb_comm_load -- load the program and execute it
+#
+# PROG is a full pathname to the file to load, no arguments.
+# Result is "untested", "pass", "fail", etc.
+#
+
+proc gdb_comm_load { dest prog args } {
+ global GDB
+ global GDBFLAGS
+ global gdb_prompt
+ global timeout
+ set argnames { "command-line arguments" "input file" "output file" }
+
+ for { set x 0; } { $x < [llength $args] } { incr x } {
+ if { [lindex $args $x] != "" } {
+ return [list "unsupported" "no support for [lindex $argnames $x] on this target"];
+ }
+ }
+ # Make sure the file we're supposed to load really exists.
+ if ![file exists $prog] then {
+ perror "$prog does not exist."
+ return [list "untested" ""];
+ }
+
+ if { [is_remote host] || ![board_info host exists fileid] } {
+ gdb_comm_start $dest;
+ }
+
+ # Remove all breakpoints, then tell the debugger that we have
+ # new exec file.
+ if { [gdb_comm_delete_breakpoints] != 0 } {
+ gdb_comm_leave;
+ return [gdb_comm_reload $dest $prog $args];
+ }
+ if { [gdb_comm_file_cmd $prog] != 0 } {
+ gdb_comm_leave;
+ return [gdb_comm_reload $dest $prog $args];
+ }
+ if [board_info $dest exists gdb_sect_offset] {
+ set textoff [board_info $dest gdb_sect_offset];
+ remote_send host "sect .text $textoff\n";
+ remote_expect host 10 {
+ -re "(0x\[0-9a-z]+) - 0x\[0-9a-z\]+ is \\.data" {
+ set dataoff $expect_out(1,string);
+ exp_continue;
+ }
+ -re "(0x\[0-9a-z\]+) - 0x\[0-9a-z\]+ is \\.bss" {
+ set bssoff $expect_out(1,string);
+ exp_continue;
+ }
+ -re "$gdb_prompt" { }
+ }
+ set dataoff [format 0x%x [expr $dataoff + $textoff]];
+ set bssoff [format 0x%x [expr $bssoff + $textoff]];
+ remote_send host "sect .data $dataoff\n";
+ remote_expect host 10 {
+ -re "$gdb_prompt" { }
+ }
+ remote_send host "sect .bss $bssoff\n";
+ remote_expect host 10 {
+ -re "$gdb_prompt" { }
+ }
+ }
+
+ # Now set up breakpoints in exit, _exit, and abort. These
+ # are used to determine if a c-torture test passed or failed. More
+ # work would be necessary for things like the g++ testsuite which
+ # use printf to indicate pass/fail status.
+
+ if { [gdb_comm_add_breakpoint _exit] != "" } {
+ gdb_comm_add_breakpoint exit;
+ }
+ gdb_comm_add_breakpoint abort;
+
+ set protocol [board_info $dest gdb_protocol];
+ if [board_info $dest exists gdb_serial] {
+ set targetname [board_info $dest gdb_serial];
+ } elseif [board_info $dest exists netport] {
+ set targetname [board_info $dest netport];
+ } else {
+ if [board_info $dest exists serial] {
+ set targetname [board_info $dest serial];
+ } else {
+ set targetname ""
+ }
+ }
+ if [board_info $dest exists baud] {
+ remote_send host "set remotebaud [board_info $dest baud]\n"
+ remote_expect host 10 {
+ -re ".*$gdb_prompt $" {}
+ default {
+ warning "failed setting baud rate";
+ }
+ }
+ }
+ remote_send host "target $protocol $targetname\n";
+ remote_expect host 60 {
+ -re "Couldn.t establish conn.*$gdb_prompt $" {
+ warning "Unable to connect to $targetname with GDB."
+ quit_gdb;
+ return [gdb_comm_reload $dest $prog $args]
+ }
+ -re "Ending remote.*$gdb_prompt $" {
+ warning "Unable to connect to $targetname with GDB."
+ quit_gdb;
+ return [gdb_comm_reload $dest $prog $args]
+ }
+ -re "Remote target $protocol connected to.*$gdb_prompt $" { }
+ -re "Remote target $targetname connected to.*$gdb_prompt $" { }
+ -re "Connected to ARM RDI target.*$gdb_prompt $" { }
+ -re "Connected to the simulator.*$gdb_prompt $" { }
+ -re "Remote.*using $targetname.*$gdb_prompt $" { }
+ -re "$gdb_prompt $" {
+ warning "Unable to connect to $targetname with GDB."
+ quit_gdb;
+ return [gdb_comm_reload $dest $prog $args]
+ }
+ -re ".*RDI_open.*should reset target.*" {
+ warning "RDI Open Failed"
+ quit_gdb;
+ return [gdb_comm_reload $dest $prog $args]
+ }
+ default {
+ warning "Unable to connect to $targetname with GDB."
+ quit_gdb;
+ return [gdb_comm_reload $dest $prog $args]
+ }
+ }
+
+ if [target_info exists gdb_init_command] {
+ remote_send host "[target_info gdb_init_command]\n";
+ remote_expect host 10 {
+ -re ".*$gdb_prompt $" { }
+ default {
+ gdb_comm_leave;
+ return [list "fail" ""];
+ }
+ }
+ }
+ # Now download the executable to the target board. If communications
+ # with the target are very slow the timeout might need to be increased.
+ if [board_info $dest exists gdb_load_offset] {
+ remote_send host "load $prog [board_info $dest gdb_load_offset]\n";
+ } else {
+ remote_send host "load\n"
+ }
+ remote_expect host 600 {
+ -re "text.*data.*$gdb_prompt $" { }
+ -re "data.*text.*$gdb_prompt $" { }
+ -re "$gdb_prompt $" {
+ warning "Unable to send program to target board."
+ gdb_comm_leave;
+ return [gdb_comm_reload $dest $prog $args];
+ }
+ default {
+ warning "Unable to send program to target board."
+ gdb_comm_leave;
+ return [gdb_comm_reload $dest $prog $args];
+ }
+ }
+
+ set output ""
+
+ # Now start up the program and look for our magic breakpoints.
+ # And a whole lot of other magic stuff too.
+
+ if [board_info $dest exists gdb_run_command] {
+ remote_send host "[board_info $dest gdb_run_command]\n";
+ } else {
+ remote_send host "run\n"
+ }
+ # FIXME: The value 300 below should be a parameter.
+ if [board_info $dest exists testcase_timeout] {
+ set testcase_timeout [board_info $dest testcase_timeout];
+ } else {
+ set testcase_timeout 300;
+ }
+ remote_expect host $testcase_timeout {
+ -re "Line.*Jump anyway.*.y or n.*" {
+ remote_send host "y\n";
+ exp_continue;
+ }
+ -re "Continuing( at |\\.| with no signal\\.)\[^\r\n\]*\[\r\n\]" {
+ exp_continue;
+ }
+ -re ".*Start it from the beginning?.*y or n.*" {
+ remote_send host "n\n";
+ remote_expect host 10 {
+ -re ".*$gdb_prompt $" {
+ remote_send host "signal 0\n";
+ remote_expect host 10 {
+ -re "signal 0\[\r\n\]+" { exp_continue; }
+ -re "Continuing(\\.| with no signal\\.)\[\r\n\]" {}
+ }
+ }
+ }
+ exp_continue
+ }
+ -re "(run\[\r\n\]*|)Starting program: \[^\r\n\]*\[\r\n\]" {
+ exp_continue
+ }
+ -re "$gdb_prompt (signal 0|continue)\[\r\n\]+Continuing(\\.| with no signal\\.)\[\r\n\]" {
+ exp_continue
+ }
+ -re "(.*)Breakpoint.*exit.*=0.*$gdb_prompt $" {
+ append output $expect_out(1,string);
+ set result [check_for_board_status output];
+ gdb_comm_leave;
+ if { $result > 0 } {
+ return [list "fail" $output];
+ }
+ return [list "pass" $output];
+ }
+ -re "(.*)Breakpoint.*exit.*=\[1-9\]\[0-9\]*.*$gdb_prompt $" {
+ append output $expect_out(1,string);
+ set result [check_for_board_status output];
+ gdb_comm_leave;
+ if { $result == 0 } {
+ return [list "pass" $output];
+ }
+ if [board_info $dest exists exit_statuses_bad] {
+ return [list "pass" $output];
+ }
+ return [list "fail" $output];
+ }
+ -re "(.*)Breakpoint.*exit.*$gdb_prompt $" {
+ append output $expect_out(1,string);
+ set status [check_for_board_status output];
+ gdb_comm_leave;
+ if { $status > 0 } {
+ return [list "fail" $output];
+ }
+ return [list "pass" $output];
+ }
+ -re "(.*)Breakpoint.*abort.*$gdb_prompt $" {
+ append output $expect_out(1,string);
+ check_for_board_status output;
+ gdb_comm_leave;
+ return [list "fail" $output];
+ }
+ -re "SIGTRAP.*$gdb_prompt $" {
+ return [gdb_comm_reload $dest $prog $args];
+ }
+ -re "(.*)Program (received |terminated ).*$gdb_prompt $" {
+ set output $expect_out(1,string);
+ check_for_board_status output;
+ gdb_comm_leave;
+ remote_reboot $dest;
+ return [list "fail" $output];
+ }
+ -re "(.*)Program exited with code \[0-9\]+.*$gdb_prompt $" {
+ set output $expect_out(1,string);
+ set status [check_for_board_status output];
+ gdb_comm_leave;
+ if { $status > 0 } {
+ return [list "fail" $output];
+ }
+ return [list "pass" $output];
+ }
+ default {
+ gdb_comm_leave;
+ if [board_info $dest exists unreliable] {
+ if { [board_info $dest unreliable] > 0 } {
+ global board_info;
+ set name [board_info $dest name];
+ incr board_info($name,unreliable) -1;
+ set result [gdb_comm_reload $dest $prog $args];
+ incr board_info($name,unreliable);
+ return $result;
+ }
+ }
+ return [list "fail" ""];
+ }
+ }
+ gdb_comm_leave;
+ return [list "fail" ""];
+}
+
+# If we've tried less than 4 times to load PROG, reboot the target, restart GDB
+# and try again. Otherwise, return "untested".
+proc gdb_comm_reload { dest prog aargs } {
+ global try_again;
+
+ # how many times have we done this?
+ set n_reloads [board_info $dest n_reloads]
+ if {$n_reloads == ""} {
+ set n_reloads 0
+ }
+
+ # increment it
+ global board_info
+ set name [board_info $dest name]
+ set board_info($dest,n_reloads) [expr {$n_reloads + 1}]
+
+ # how many times are we allowed to do this?
+ set max [board_info $dest max_reload_reboots]
+ if {$max == ""} {
+ set max 15
+ }
+
+ # if we've been doing this too much, something's very
+ # wrong. just give up, to reduce stress on boards.
+ if {$max == $n_reloads} {
+ perror "Too many reboots. Giving up."
+ }
+ if {$max <= $n_reloads} {
+ return {untested {}}
+ }
+
+ if { $try_again < 4 } {
+ global GDB;
+ remote_reboot $dest;
+ remote_close host;
+ incr try_again;
+ set result [eval remote_load \"$dest\" \"$prog\" $aargs]
+ set try_again 0;
+ return "$result";
+ } else {
+ set try_again 0;
+ return [list "untested" ""];
+ }
+}
+
+set_board_info protocol "gdb_comm";
diff --git a/dejagnu/config/gdb_stub.exp b/dejagnu/config/gdb_stub.exp
new file mode 100644
index 00000000000..127c6ebc887
--- /dev/null
+++ b/dejagnu/config/gdb_stub.exp
@@ -0,0 +1,638 @@
+# Copyright (C) 1996-98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Michael Snyder <msnyder@cygnus.com>.
+
+#
+# Stub remote run command.
+#
+
+proc gdb_stub_init { dest args } {
+ global gdb_prompt
+ global GDB
+ global tool_root_dir
+
+ if ![info exists GDB] then {
+ set GDB "[lookfor_file ${tool_root_dir} gdb/gdb]"
+ if { $GDB == "" } {
+ set GDB [transform gdb]
+ }
+ }
+
+ if [board_info $dest exists gdb_prompt] {
+ set gdb_prompt [board_info $dest gdb_prompt];
+ } else {
+ set gdb_prompt "\\(gdb\\)"
+ }
+
+ return 1;
+}
+
+proc gdb_stub_restart { dest } {
+ global gdb_prompt
+ global GDB
+
+ gdb_stub_init $dest;
+
+ for {set x 1;} { $x < 4 } {incr x} {
+ remote_close $dest;
+ sleep 2;
+ set command "$GDB -nw -nx";
+ if [host_info exists gdb_opts] {
+ append command " [host_info gdb_opts]";
+ }
+ set spawn_id [remote_spawn host $command];
+ remote_expect host 30 {
+ -re "$gdb_prompt" { }
+ }
+ if { $spawn_id >= 0 } {
+ if [board_info $dest exists baud] {
+ remote_send host "set remotebaud [board_info $dest baud]\n";
+ remote_expect host 5 {
+ -re "$gdb_prompt" { }
+ default {
+ warning "Error setting baud rate."
+ return -1;
+ }
+ }
+ }
+
+
+ set value [gdb_stub_startup $dest];
+ if { $value > 0 } {
+ break;
+ }
+ verbose "got $value from gdb_stub_startup";
+ remote_send host "quit\n";
+ }
+ remote_reboot $dest;
+ }
+ if { ${x} < 4 } {
+ global board_info;
+ set name [board_info $dest name];
+
+ set board_info($name,gdb_is_running) 1;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+proc gdb_stub_remote_check { dest } {
+ global gdb_prompt
+
+ if [board_info $dest exists gdb_serial] {
+ set serial [board_info $dest gdb_serial];
+ } elseif [board_info $dest exists serial] {
+ set serial [board_info $dest serial];
+ } else {
+ set serial [board_info $dest netport];
+ }
+ remote_send host "target remote $serial\n";
+ remote_expect host 10 {
+ -re "Couldn't establish connection.*$gdb_prompt" {
+ return 0;
+ }
+ -re "Remote debugging.*$gdb_prompt" {
+ verbose "stub is already running"
+ return 1;
+ }
+ -re "$gdb_prompt" {
+ return 0;
+ }
+ timeout {
+ remote_send host "\003";
+ remote_expect host 10 {
+ -re "$gdb_prompt" { }
+ }
+ return 0;
+ }
+ default {
+ return 0;
+ }
+ }
+}
+
+proc gdb_stub_startup { dest } {
+ global gdb_prompt
+ global GDB
+
+ set is_running_stub 0;
+
+ if [gdb_stub_remote_check $dest] {
+ set is_running_stub 1;
+ }
+
+ if [board_info $dest exists serial] {
+ set serial [board_info $dest serial];
+ } else {
+ set serial [board_info $dest netport];
+ }
+
+ if { ! $is_running_stub } {
+ set command "target [board_info $dest gdb_protocol] $serial\n";
+ remote_send host $command;
+ remote_expect host 5 {
+ -re "already.*y or n." {
+ remote_send host "y\n";
+ exp_continue;
+ }
+ -re "appears to be alive.*$gdb_prompt" { }
+ -re "Remote target.*connected to.*$gdb_prompt" { }
+ default {
+ return -1;
+ }
+ }
+ }
+ if { $is_running_stub == 0 } {
+ global libdir
+
+ verbose "building loader";
+ set loader "loader";
+ if ![file exists $loader] {
+ if [board_info $dest exists gdb_stub_offset] {
+ set result [target_compile "${libdir}/stub-loader.c" $loader executable "libs=-Wl,-Ttext,[board_info $dest gdb_stub_offset]"];
+ } else {
+ set result [target_compile "${libdir}/stub-loader.c" $loader executable "ldscript=[board_info $dest gdb_stub_ldscript]"];
+ }
+ verbose "result is $result";
+ if [is_remote host] {
+ set loader [remote_download host $loader];
+ }
+ }
+ remote_send host "file $loader\n";
+ remote_expect host 20 {
+ -re "A program is being debug.*Kill it.*y or n. $" {
+ remote_send host "y\n"
+ exp_continue
+ }
+ -re "Load new symbol table.*y or n. $" {
+ remote_send host "y\n"
+ exp_continue
+ }
+ -re "Reading symbols from.*done..*$gdb_prompt $" {}
+ -re "$gdb_prompt $" { warning "GDB couldn't find loader" }
+ timeout {
+ warning "(timeout) read symbol file" ;
+ return -1
+ }
+ }
+
+ if [board_info $dest exists serial] {
+ set serial [board_info $dest serial];
+ } else {
+ set serial [board_info $dest netport];
+ }
+ remote_send host "target [board_info $dest gdb_protocol] $serial\n";
+ remote_expect host 60 {
+ -re "appears to be alive.*$gdb_prompt" { }
+ -re "Remote target.*connected to.*$gdb_prompt" { }
+ -re "$gdb_prompt" {
+ warning "Error reconnecting to stub.";
+ return -1;
+ }
+ default {
+ warning "Error reconnecting to stub.";
+ return -1;
+ }
+ }
+
+ # We only send the offset if gdb_load_offset is set. Otherwise, we
+ # assume that sending the offset isn't needed.
+ if [board_info $dest exists gdb_load_offset] {
+ remote_send host "load $loader [board_info $dest gdb_stub_offset]\n"
+ } else {
+ remote_send host "load $loader\n";
+ }
+ verbose "Loading $loader into $GDB" 2
+ global verbose
+ set no_run_command 0;
+ # FIXME: The value 1200 below should be a parameter.
+ remote_expect host 1200 {
+ -re "Transfer rate:.*Switching to remote protocol.*Remote debugging" {
+ set no_run_command 1;
+ remote_send host "";
+ sleep 2;
+ remote_send host "";
+ sleep 1;
+ }
+ -re "Loading.*Starting.*at.*$gdb_prompt $" {
+ verbose "Loaded $loader into $GDB" 1
+ set no_run_command 1;
+ }
+ -re "Loading.*$gdb_prompt $" {
+ verbose "Loaded $loader into $GDB" 1
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ warning "GDB couldn't load."
+ }
+ }
+ timeout {
+ if $verbose>1 then {
+ warning "Timed out trying to load $arg."
+ }
+ }
+ }
+
+ if { ! $no_run_command } {
+ remote_send host "run\n";
+ remote_expect host 60 {
+ -re "A program is being debug.*Kill it.*y or n. $" {
+ remote_send host "y\n"
+ exp_continue
+ }
+ -re "The program being debugged .*y or n. $" {
+ remote_send host "y\n"
+ exp_continue
+ }
+ -re "Starting program:.*loader.*$" {
+ verbose "Starting loader succeeded"
+ }
+ timeout {
+ warning "(timeout) starting the loader" ;
+ return -1
+ }
+ default {
+ warning "error starting the loader";
+ }
+ }
+ sleep 2;
+ remote_send host ""
+ sleep 1;
+ remote_send host ""
+ verbose "Sent ^C^C"
+ remote_expect host 30 {
+ -re "Give up .and stop debugging it.*$" {
+ remote_send host "y\n"
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ verbose "Running loader succeeded"
+ }
+ timeout {
+ warning "(timeout) interrupting the loader" ;
+ return -1
+ }
+ default {
+ warning "error interrupting the loader";
+ }
+ }
+ }
+ remote_send host "quit\n";
+ return [gdb_stub_restart $dest];
+ }
+ return 1;
+}
+
+#
+# Delete all breakpoints and verify that they were deleted. If anything
+# goes wrong we just exit.
+#
+proc gdb_stub_delete_breakpoints {} {
+ global gdb_prompt
+
+ remote_send host "delete breakpoints\n"
+ remote_expect host 10 {
+ -re "Delete all breakpoints.*y or n. $" {
+ remote_send host "y\n"
+ exp_continue
+ }
+ -re "$gdb_prompt $" { }
+ timeout { warning "Delete all breakpoints (timeout)" ; return -1}
+ }
+ remote_send host "info breakpoints\n"
+ remote_expect host 10 {
+ -re "No breakpoints or watchpoints..*$gdb_prompt $" {}
+ -re "$gdb_prompt $" { warning "breakpoints not deleted" ; return -1}
+ timeout { warning "info breakpoints (timeout)" ; return -1}
+ }
+ return 0;
+}
+
+proc gdb_stub_go_idle { dest } {
+ gdb_stub_delete_breakpoints
+}
+
+proc gdb_stub_add_breakpoint { function args } {
+ global gdb_prompt
+
+ remote_send host "break $function\n"
+ remote_expect host 60 {
+ -re "Breakpoint (\[0-9\]+).*$gdb_prompt $" { return $expect_out(1,string) }
+ -re "Function.*not defined.*$gdb_prompt $" { return "undef" }
+ -re "No symbol table.*$gdb_prompt $" { return "undef" }
+ default {
+ return "undef"
+ }
+ }
+}
+
+proc gdb_stub_start { dest } {
+ global gdb_prompt;
+
+ set exit_brnum [gdb_stub_add_breakpoint _exit];
+ if { $exit_brnum == "undef" || [board_info $dest exists always_break_exit] } {
+ set exit_brnum [gdb_stub_add_breakpoint exit];
+ }
+ set abort_brnum [gdb_stub_add_breakpoint abort];
+
+ upvar #0 gdb_stub_info I
+ set I($dest,exit_brnum) $exit_brnum
+ set I($dest,abort_brnum) $abort_brnum
+
+ remote_send host "set \$fp=0\n";
+ remote_expect host 10 {
+ -re "$gdb_prompt" { }
+ }
+ # This is needed for the SparcLite. Whee.
+ if [board_info $dest exists gdb,start_symbol] {
+ set start_comm "jump *[board_info $dest gdb,start_symbol]\n";
+ } else {
+ set start_comm "jump *start\n";
+ }
+ remote_send host "break copyloop\n";
+ remote_expect host 10 {
+ -re "Breakpoint.*$gdb_prompt $" {
+ set start_comm "continue\n";
+ }
+ -re "Function.*not defined.*$gdb_prompt $" { }
+ default { }
+ }
+ remote_send host $start_comm;
+ remote_expect host 10 {
+ -re "y or n. $" {
+ remote_send host "y\n"
+ exp_continue;
+ }
+ -re "Breakpoint.*in copyloop.*$gdb_prompt $" {
+ remote_send host "jump relocd\n";
+ exp_continue;
+ }
+ -re "Continuing at.*\[\r\n\]" { }
+ default {
+ return { "fail" "" };
+ }
+ }
+ return { "pass" "" };
+}
+
+proc gdb_stub_spawn { dest prog args } {
+ for { set x 0; } { $x < 3 } { incr x } {
+ if { [remote_ld $dest $prog] != 1 } {
+ return [list "fail" "remote_ld failed"];
+ }
+
+ set result [gdb_stub_start $dest];
+ if { [lindex $result 0] != "pass" } {
+ remote_reboot target;
+ } else {
+ return 666; # does anyone use this value?
+ }
+ }
+ return -1;
+}
+
+proc gdb_stub_wait { dest timeout } {
+ global gdb_prompt
+
+
+ upvar #0 gdb_stub_info I
+ set exit_brnum $I($dest,exit_brnum)
+ set abort_brnum $I($dest,abort_brnum)
+
+ remote_expect host $timeout {
+ -re "Breakpoint.*exit.*=0.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest
+ return [list 0 ""];
+ }
+ -re "Breakpoint.*exit.*=\[1-9\]\[0-9\]*.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest
+ return [list 0 ""];
+ }
+ -re "Breakpoint.*exit.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest
+ return [list 0 ""];
+ }
+ -re "Breakpoint.*abort.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest
+ return [list 1 ""];
+ }
+ -re " EXIT code 0.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest;
+ return [list 0 ""];
+ }
+ -re " EXIT code \[1-9]\[0-9]*.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest;
+ return [list 0 ""];
+ }
+ -re " EXIT code 4242.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest;
+ return [list 1 ""];
+ }
+ -re "Program received.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest
+ return [list 1 ""];
+ }
+ -re "Program exited.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest
+ return [list 1 ""];
+ }
+ -re "Breakpoint $exit_brnum.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest;
+ return [list 0 ""];
+ }
+ -re "Breakpoint $abort_brnum.*$gdb_prompt $" {
+ gdb_stub_go_idle $dest;
+ return [list 1 ""];
+ }
+ default {
+ remote_close $dest;
+ remote_reboot $dest;
+ return [list -1 ""];
+ }
+ }
+ return [list -1 ""];
+}
+
+proc gdb_stub_load { dest prog args } {
+ global gdb_prompt
+ set argnames { "command-line arguments" "input file" "output file" }
+
+ for { set x 0; } { $x < [llength $args] } { incr x } {
+ if { [lindex $args $x] != "" } {
+ return [list "unsupported" "no support for [lindex $argnames $x] on this target"];
+ }
+ }
+
+ set result [remote_spawn $dest $prog];
+
+ if { $result < 0 } {
+ return [list "fail" "remote_spawn failed"];
+ }
+
+ # FIXME: The value 120 should be a parameter.
+ set result [remote_wait $dest 120];
+ set status [lindex $result 0];
+ set output [lindex $result 1];
+
+ if { $status == 0 } {
+ return [list "pass" $output];
+ } elseif { $status > 0 } {
+ return [list "fail" $output];
+ } else {
+ global gdb_stub_retry;
+
+ if ![info exists gdb_stub_retry] {
+ set gdb_stub_retry 1;
+
+ set result [eval gdb_stub_load \{$dest\} \{$prog\} $args];
+ unset gdb_stub_retry;
+ return $result;
+ } else {
+ return [list "fail" $output];
+ }
+ }
+}
+
+
+#
+# gdb_stub_ld -- load PROG into the board;
+# Returns a 0 if there was an error,
+# 1 if it loaded successfully.
+#
+proc gdb_stub_ld { dest prog } {
+ global gdb_prompt
+ global GDB
+
+ if ![board_info $dest exists gdb_is_running] {
+ if ![gdb_stub_restart $dest] {
+ return 0;
+ }
+ }
+
+ set loadfile [file tail $prog]
+ set loadpath [file dirname $prog]
+
+ remote_send host "file $prog\n"
+ remote_expect host 30 {
+ -re "A program is being debug.*Kill it.*y or n. $" {
+ remote_send host "y\n"
+ exp_continue
+ }
+ -re "Load new symbol table.*y or n. $" {
+ remote_send host "y\n"
+ exp_continue
+ }
+ -re "Reading symbols from.*done..*$gdb_prompt $" {}
+ -re "$gdb_prompt $" {
+ # Hmmm...is retrying going to help? I kinda doubt it.
+ warning "GDB couldn't read file"
+ return [gdb_stub_retry_ld "$dest" "$prog"];
+ }
+ timeout {
+ warning "(timeout) read symbol file";
+ return [gdb_stub_retry_ld "$dest" "$prog"];
+ }
+ }
+
+ # just in case there are old breakpoints lying around.
+ gdb_stub_delete_breakpoints
+
+ if [board_info $dest exists gdb_serial] {
+ set serial [board_info $dest gdb_serial];
+ } elseif [board_info $dest exists serial] {
+ set serial [board_info $dest serial];
+ } else {
+ set serial [board_info $dest netport];
+ }
+
+ remote_send host "target remote $serial\n"
+ remote_expect host 60 {
+ -re "Kill it?.*y or n.*" {
+ remote_send host "y\n";
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ verbose "Set remote target to $serial" 2
+ }
+ timeout {
+ warning "Couldn't set remote target."
+ return 0
+ }
+ }
+
+ if [board_info $dest exists gdb_load_offset] {
+ set offset "[board_info $dest gdb_load_offset]";
+ } else {
+ set offset "";
+ }
+ remote_send host "load $prog $offset\n"
+ verbose "Loading $prog into $GDB" 2
+ global verbose;
+ remote_expect host 1200 {
+ -re "Loading.*$gdb_prompt $" {
+ verbose "Loaded $prog into $GDB" 1
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ warning "GDB couldn't load."
+ }
+ }
+ timeout {
+ if $verbose>1 then {
+ perror "Timed out trying to load $prog."
+ }
+ }
+ }
+ return 1
+}
+
+#
+# Retry the ld operation, but only once.
+#
+
+proc gdb_stub_retry_ld { dest prog } {
+ global gdb_stub_retry_ld;
+
+ remote_reboot $dest;
+ if [info exists gdb_stub_retry_ld] {
+ unset gdb_stub_retry_ld;
+ return 0;
+ } else {
+ set gdb_stub_retry_ld 1;
+ }
+ gdb_stub_restart $dest;
+ set status [gdb_stub_ld $dest $prog];
+ if [info exists gdb_stub_retry_ld] {
+ unset gdb_stub_retry_ld;
+ }
+ return $status;
+}
+
+proc gdb_stub_close { dest } {
+ global board_info
+ set name [board_info $dest name];
+ if [info exists board_info($name,gdb_is_running)] {
+ unset board_info($name,gdb_is_running);
+ }
+ return [remote_close host];
+}
+
+set_board_info protocol "gdb_stub"
diff --git a/dejagnu/config/h8300.exp b/dejagnu/config/h8300.exp
new file mode 100644
index 00000000000..3fffb06ca0d
--- /dev/null
+++ b/dejagnu/config/h8300.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/i386-bozo.exp b/dejagnu/config/i386-bozo.exp
new file mode 100644
index 00000000000..563da320b9e
--- /dev/null
+++ b/dejagnu/config/i386-bozo.exp
@@ -0,0 +1,46 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb-comm";
+
+proc ${board}_init { args } {
+ set linux_box [target_info linux_box];
+ set bozo_server [target_info bozo_server];
+ remote_spawn $linux_box "$bozo_server unknown";
+ remote_expect $linux_box 60 {
+ -re "port is (\[0-9\]+)" {
+ set_currtarget_info netport "${linux_box}:$expect_out(1,string)";
+ }
+ }
+}
+
+proc ${board}_close { board } {
+ set linux_box [board_info $board linux_box];
+ if [board_info $linux_box exists fileid] {
+ remote_send $linux_box "\003";
+ remote_close $linux_box;
+ }
+ standard_close $board;
+}
+
+proc ${board}_reboot { board args } {
+ remote_close $board;
+ unset_currtarget_info netport;
+ return 1;
+}
diff --git a/dejagnu/config/i960.exp b/dejagnu/config/i960.exp
new file mode 100644
index 00000000000..dcca835c679
--- /dev/null
+++ b/dejagnu/config/i960.exp
@@ -0,0 +1,221 @@
+# Copyright (C) 1997, 1998, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+#
+# Initialize the board on initial connection or after rebooting.
+# Since the board autobauds, we have to be a bit aggressive about
+# getting a valid prompt.
+#
+proc ${board}_init { dest } {
+ global i960_try_count;
+
+ set prompt [board_info $dest shell_prompt];
+ set done 0;
+
+ if ![info exists i960_try_count] {
+ set i960_try_count 1;
+ }
+
+ remote_close $dest;
+ if { [remote_open $dest] != "" } {
+ for { set tries 0; } { $tries < 7 && ! $done } { incr tries } {
+ remote_send $dest "\n";
+ remote_expect $dest 1 {
+ -re "${prompt}" {
+ set done 1;
+ }
+ -re ".+" { exp_continue }
+ timeout { }
+ }
+ }
+ }
+
+ remote_close $dest;
+ if { ! $done } {
+ if { $i960_try_count == 3 } {
+ perror "Couldn't connect to board.";
+ } else {
+ incr i960_try_count;
+ remote_close $dest;
+ remote_reboot $dest;
+ }
+ }
+ if [info exists i960_try_count] {
+ unset i960_try_count;
+ }
+}
+
+proc i960_ld { dest prog } {
+ if ![file exists $prog] {
+ perror "$prog does not exist."
+ return "untested"
+ }
+ set shell_prompt [board_info $dest shell_prompt];
+ set strip [board_info $dest strip];
+ set rprog [remote_download host $prog a.out];
+ if { $strip != "" } {
+ remote_exec host $strip $rprog;
+ }
+ remote_upload host $rprog a.out;
+
+ set id [remote_open $dest];
+ if { $id < 0 } {
+ return -1;
+ }
+ remote_binary $dest;
+ remote_send $dest "\n";
+ remote_expect $dest 5 {
+ -re $shell_prompt { }
+ }
+ remote_send $dest "do\n";
+ remote_expect $dest 5 {
+ -re "Downloading" { }
+ }
+ # Nasty.
+ if { [board_info $dest connect] == "telnet" } {
+ global board_info;
+
+ remote_close $dest;
+ set hp [split [board_info $dest netport] ":"];
+ set host [lindex $hp 0];
+ set port [lindex $hp 1];
+ set status -1;
+ while { $status != 0 } {
+ set status [catch "socket $host $port" id2];
+ if { $status != 0 } {
+ sleep 5;
+ }
+ }
+ } else {
+ set id2 [exp_open -leaveopen -i $id];
+ }
+ if [catch "exec sx -bX a.out <@$id2 >@$id2 2>/dev/null" error] {
+ perror "exec sx failed: $error"
+ }
+ if { [board_info $dest connect] == "telnet" } {
+ close $id2;
+ sleep 2;
+ remote_open $dest;
+ remote_binary $dest;
+ }
+ set result 1;
+ remote_send $dest "\n";
+ remote_expect $dest 1 {
+ -re "$shell_prompt" {
+ set result 0;
+ exp_continue;
+ }
+ timeout { }
+ }
+ return $result;
+}
+
+proc i960_spawn { dest prog args } {
+ set shell_prompt [board_info $dest shell_prompt];
+
+ for { set tries 0 ; } { $tries < 3 } { incr tries } {
+ set result [remote_ld $dest $prog];
+ if { $result == 0 } {
+ set comm "go [board_info $dest start_addr]";
+ remote_send $dest "$comm\n";
+ remote_expect $dest 10 {
+ -re "$comm\[\r\n\]\[\r\n\]?" { }
+ default { }
+ }
+ return [board_info $dest fileid];
+ } else {
+ remote_reboot $dest;
+ }
+ }
+ return -1;
+}
+
+proc i960_wait { dest timeout } {
+ set output "";
+ set shell_prompt [board_info $dest shell_prompt];
+
+ remote_expect $dest $timeout {
+ -re " fault at \[0-9a-h\]+, subtype \[0-9a-h\]+" {
+ set status -1;
+ exp_continue;
+ }
+ -re "(.*)(\[\r\n\]|^)Program Exit: (\[0-9\]+)\[\r\n\]" {
+ append output $expect_out(1,string);
+ set status $expect_out(3,string);
+ exp_continue;
+ }
+ -re "(.*)$shell_prompt" {
+ append output $expect_out(1,string);
+ set bstatus [check_for_board_status output];
+ if { $bstatus >= 0 } {
+ set status $bstatus;
+ }
+ }
+ -re "\[\r\n\]+" {
+ # Sometimes the board goes wacky in the head, and we have
+ # to shoot it.
+ append output $expect_out(buffer);
+ if { [string length $output] < 512000 } {
+ exp_continue;
+ } else {
+ set status -1;
+ }
+ }
+ default {
+ set status -1;
+ }
+ }
+ return [list $status $output];
+}
+
+proc i960_load { dest prog args } {
+ for { set x 0; } { $x < 3 } { incr x; } {
+ set id [eval remote_spawn \{$dest\} \{$prog\} $args];
+ if { $id < 0 } {
+ return [list "fail" ""];
+ }
+ set result [remote_wait $dest 120];
+ set status [lindex $result 0];
+ set output [lindex $result 1];
+
+ if { $status == 0 } {
+ return [list "pass" $output];
+ } else {
+ global i960_retry;
+
+ if { [board_info $dest exists unreliable] && ![info exists i960_retry] } {
+ set i960_retry 1;
+ remote_reboot $dest;
+ set result [eval i960_load \{$dest\} \{$prog\} $args];
+ unset i960_retry;
+ return $result;
+ } else {
+ if { $status < 0 } {
+ remote_reboot $dest;
+ }
+ return [list "fail" $output];
+ }
+ }
+ }
+}
+
+set_board_info shell_prompt "=>";
+set_board_info send_initial_cr 1;
+# We take care of getting a prompt in ${board}_init.
+set_board_info dont_wait_for_prompt 1;
diff --git a/dejagnu/config/m32r-stub.exp b/dejagnu/config/m32r-stub.exp
new file mode 100644
index 00000000000..7cdfd2392ca
--- /dev/null
+++ b/dejagnu/config/m32r-stub.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb_stub";
diff --git a/dejagnu/config/m32r.exp b/dejagnu/config/m32r.exp
new file mode 100644
index 00000000000..3fffb06ca0d
--- /dev/null
+++ b/dejagnu/config/m32r.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/m68k-emc.exp b/dejagnu/config/m68k-emc.exp
new file mode 100644
index 00000000000..852453ca8fc
--- /dev/null
+++ b/dejagnu/config/m68k-emc.exp
@@ -0,0 +1,52 @@
+proc ${board}_init { dest } {
+ global doing_emc_init;
+
+ if [info exists doing_emc_init] {
+ return;
+ }
+ set doing_emc_init 1;
+ remote_close $dest;
+ set dos_host [board_info $dest dos_host];
+ remote_reboot $dos_host;
+ unset doing_emc_init;
+}
+
+proc m68k_emc_board_connect { dest } {
+ global board_info;
+ set tname [board_info $dest name];
+
+ set board_info($tname,m68k_connected) 1;
+ set dos_host [board_info $dest dos_host];
+
+ for { set x 0; } { $x < 3 } { incr x; } {
+ set shell_id [remote_open $dos_host];
+ if { $shell_id == "" || $shell_id < 0 } {
+ remote_reboot $dos_host;
+ } else {
+ break;
+ }
+ }
+ remote_send $dos_host "c:\\symetrix.bat\n";
+ remote_expect $dos_host 300 {
+ -re "SymmComm.*Installed.*\033.2J.*\033.2J" { }
+ default {
+ warning "Never got clear screen sequence from remote side."
+ }
+ }
+ # Flush the buffer.
+ remote_expect $dos_host 2 {
+ -re ".+" { exp_continue; }
+ }
+ # Get past first menu.
+ remote_send $dos_host "\n";
+ remote_expect $dos_host 10 {
+ -re "\033.07;02H" { }
+ default { }
+ }
+ # We don't want a log file.
+ remote_send $dos_host "\n";
+ remote_expect $dos_host 10 {
+ -re "\033.02;24H" { }
+ default { }
+ }
+}
diff --git a/dejagnu/config/mips-idt.exp b/dejagnu/config/mips-idt.exp
new file mode 100644
index 00000000000..eacdb4d52bb
--- /dev/null
+++ b/dejagnu/config/mips-idt.exp
@@ -0,0 +1,24 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gcc@prep.ai.mit.edu
+
+# For MIPS/IDT we use gdb to load and execute programs.
+
+load_generic_config "gdb-comm";
+
+set_board_info gdb_init_command "set syn-garbage-limit 0";
diff --git a/dejagnu/config/mn10200-eval.exp b/dejagnu/config/mn10200-eval.exp
new file mode 100644
index 00000000000..9af6ae5036b
--- /dev/null
+++ b/dejagnu/config/mn10200-eval.exp
@@ -0,0 +1,22 @@
+# Copyright (C) 1998 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gcc@prep.ai.mit.edu
+
+# For MN10200 evaluation boards we use gdb to load and execute programs.
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/mn10300-eval.exp b/dejagnu/config/mn10300-eval.exp
new file mode 100644
index 00000000000..1070b422a41
--- /dev/null
+++ b/dejagnu/config/mn10300-eval.exp
@@ -0,0 +1,22 @@
+# Copyright (C) 1998 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gcc@prep.ai.mit.edu
+
+# For MN10300 evaluation boards we use gdb to load and execute programs.
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/netware.exp b/dejagnu/config/netware.exp
new file mode 100644
index 00000000000..75d81491e3e
--- /dev/null
+++ b/dejagnu/config/netware.exp
@@ -0,0 +1,214 @@
+# Copyright (C) 1994, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gcc@prep.ai.mit.edu
+
+# This file was written by J.T. Conklin. (jtc@cygnus.com)
+
+#
+# load support libraries
+#
+load_lib remote.exp
+
+# set target variables only if needed
+
+proc ${board}_init { args } {
+ global NLMCONV
+ if ![info exists NLMCONV] then {
+ set NLMCONV [findfile "$rootme/../binutils/nlmconv"]
+ }
+ global LD
+ if ![info exists LD] then {
+ set LD [findfile "$rootme/../ld/ld-new" "$rootme/../ld/ld-new" [transform "ld"]]
+ }
+
+ set shell_prompt "Password:"
+ set shell_id [remote_open target];
+ if [target_info exists passwd] {
+ set passwd [target_info passwd];
+ } else {
+ set passwd "";
+ }
+ if $shell_id<0 then {
+ warning "Couldn't connect to target"
+ return -1
+ }
+
+ if [string match "" $passwd] then {
+ stty -echo
+ send_user "Password: "
+ expect_user -re "(.*)\n"
+ send_user "\n"
+ set passwd "$expect_out(1,string)"
+ stty echo
+ }
+
+ send -i $shell_id "$passwd\n"
+ expect {
+ -i $shell_id ":" {
+ verbose "Got termtype prompt" 0
+ }
+
+ -i $shell_id timeout {
+ warning "Connection timed out"
+ return -1
+ }
+ }
+
+ # FIXME
+ set shell_prompt "[string toupper [target_info name]]:"
+ send -i $shell_id "1\n"
+
+ expect {
+ -i $shell_id -re "$shell_prompt" {}
+ -i $shell_id timeout {
+ warning "Connection timed out"
+ return -1
+ }
+ }
+}
+
+
+#
+# ${board}_load -- load the program and execute it
+#
+# See default.exp for explanation of arguments and results.
+#
+
+proc ${board}_load { dest prog args } {
+ global LD NLMCONV
+ global tmpdir
+ global errorCode
+
+ if [board_info $dest exists fileid] {
+ set shell_id [board_info $dest fileid];
+ } else {
+ set shell_id -1;
+ }
+
+ set output ""
+
+ if $shell_id<0 then {
+ verbose -log "$prog not executed because there is no target" 3
+ return "untested"
+ }
+
+ #
+ set exe [file tail $prog]
+
+ # We can't blindly append a suffix to the object name, because the
+ # result may not be valid on netware's 8.3 filesystem.
+ set nlm "$tmpdir/x.nlm"
+ set lnk "$tmpdir/x.lnk"
+
+ # build *.lnk file
+ set fd [open $lnk w]
+ puts $fd "description \"$exe\""
+ puts $fd "screenname \"System Console\""
+ puts $fd "module clib.nlm"
+ puts $fd "module mathlib.nlm"
+ puts $fd "stack 65536"
+ puts $fd "debug"
+ # FIXME: don't hardcode location of prelude.o
+ puts $fd "input /s1/cygnus/dejagnu/i386-netware/lib/prelude.o"
+ puts $fd "input $prog"
+ puts $fd "output $nlm"
+ close $fd
+
+ # run nlmconv
+ verbose "Executing: $NLMCONV -l$LD -T$lnk" 1
+ catch "exec $NLMCONV -l$LD -T$lnk" output
+ if ![string match "" $output] then {
+ verbose $output 1
+ }
+ if ![string match "NONE" $errorCode] {
+ verbose -log "Can't link $prog" 3
+ return "fail"
+ }
+
+ # download
+ verbose "Downloading $nlm" 1
+ catch "exec cp $nlm /.NetWare/[board_info $dest name].nws/sys.nwv/tmp/x.nlm" output
+ if ![string match "" $output] then {
+ verbose $output 1
+ verbose -log "cp failed for $nlm" 3
+ return "unresolved"
+ }
+
+ # Wait a second for the file to "settle" on the NetWare server.
+ # I've encountered unexplained failures without this delay.
+# sleep 1
+
+
+ # The NetWare remote console expects to be connected to a vt100
+ # compatible terminal. It isn't very efficent, and it seems to
+ # send screen repaints for no reason. So we have to clear the
+ # screen as we run each test, otherwise a shell prompt or abort
+ # message from a previous test could cause incorrect results.
+ send -i $shell_id "CLS\r\n"
+ set timeout 1
+ expect {
+ -i $shell_id -re "$shell_prompt" {
+ exp_continue
+ }
+ }
+ set timeout 10
+
+
+ # Netware does not support exit status. The best we can do to
+ # detect failures is to look for the "ABNORMAL NLM TERMINATION"
+ # message printed by abort().
+ set ret 0
+ send -i $shell_id "LOAD X.NLM\r\n"
+ expect {
+ -i $shell_id "ABNORMAL NLM TERMINATION" {
+ set ret 1
+ exp_continue
+ }
+ -i $shell_id "Unable to find load file" {
+ perror "Couldn't execute program"
+ verbose -log "Couldn't execute program" 3
+ return "unresolved"
+ }
+ -i $shell_id timeout {
+ perror "Couldn't execute program (timed out)"
+ verbose -log "Couldn't execute program (timed out)" 3
+ return "unresolved"
+ }
+ -i $shell_id -re "[format "%sLOAD" $shell_prompt]" {
+ exp_continue
+ }
+ -i $shell_id -re "$shell_prompt" {}
+ }
+
+ catch [exec rm -f $lnk]
+ catch [exec rm -f $nlm]
+
+ if { $ret == 0 } {
+ return "pass"
+ } else {
+ return "fail"
+ }
+}
+
+#
+# ${tool}_exit -- shutdown the connection
+#
+
+proc ${board}_exit {} {
+ remote_close target;
+}
diff --git a/dejagnu/config/powerpc-bug.exp b/dejagnu/config/powerpc-bug.exp
new file mode 100644
index 00000000000..3fffb06ca0d
--- /dev/null
+++ b/dejagnu/config/powerpc-bug.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/proelf.exp b/dejagnu/config/proelf.exp
new file mode 100644
index 00000000000..310af214556
--- /dev/null
+++ b/dejagnu/config/proelf.exp
@@ -0,0 +1,27 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "base68k";
+set_board_info shell_prompt "#"
+set_board_info download_command "r 0\n";
+set_board_info go_command "g"
+set_board_info startaddr "40000"
+
+set_board_info go_response "\[\r\n\]+\[a-z \]+\\(\[0-9\]+\\) pc=\[0-9A-Ha-h\]+\[\r\n\]+\[0-9A-H\]+ \[0-9A-H\]+ \[^\r\n\]+\[\r\n\]+|\\*\\*\\*EXIT code "
+set_board_info output_end "\[\r\n\]+\[a-z \]+\\(\[0-9\]+\\) pc=\[0-9A-Ha-h\]+\[\r\n\]+.*$"
diff --git a/dejagnu/config/rom68k.exp b/dejagnu/config/rom68k.exp
new file mode 100644
index 00000000000..63721f83abc
--- /dev/null
+++ b/dejagnu/config/rom68k.exp
@@ -0,0 +1,32 @@
+# Copyright (C) 1995, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Bob Manson (manson@cygnus.com)
+# based on earlier work by J.T. Conklin (jtc@cygnus.com)
+
+load_generic_config "base68k";
+
+set_board_info shell_prompt "ROM68K :-> "
+set_board_info download_command "DC\n";
+set_board_info download_response "Waiting for S-records from host... ";
+set_board_info go_command "GO"
+set_board_info startaddr "10000"
+set_board_info hex_startaddr "0x10000"
+set_board_info go_response "(Emul|RS Except|TRAP #\[1-9\]|\\*\\*\\*EXIT code ).*"
+set_board_info output_end "\[\r\n\]((\[^\r\n\]*\[\r\n\]-----*)|Emul|RS Except|TRAP #|Bus/Address).*$"
diff --git a/dejagnu/config/sh.exp b/dejagnu/config/sh.exp
new file mode 100644
index 00000000000..3fffb06ca0d
--- /dev/null
+++ b/dejagnu/config/sh.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb-comm";
diff --git a/dejagnu/config/sim.exp b/dejagnu/config/sim.exp
new file mode 100644
index 00000000000..74edc6f73c6
--- /dev/null
+++ b/dejagnu/config/sim.exp
@@ -0,0 +1,124 @@
+# Copyright (C) 1993, 1994, 1996, 1997, 1998 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+#
+# sim_load -- load the program and execute it
+#
+# See default.exp for explanation of arguments and results.
+#
+
+proc sim_spawn { dest cmdline args } {
+ if ![board_info $dest exists sim] {
+ perror "no simulator defined for [board_info $dest name]"
+ exit 1
+ } else {
+ set sim [board_info $dest sim];
+ }
+
+ if [board_info $dest exists sim,options] {
+ set simflags [board_info $dest sim,options]
+ } else {
+ set simflags ""
+ }
+
+ if ![is_remote host] {
+ if { [which $sim] == 0 } {
+ verbose -log "Simulator $sim missing." 3
+ return -1;
+ }
+ }
+
+ if [is_remote host] {
+ # download the program to remote.
+ # we're assuming the program is the first word in the command.
+ # FIXME: "prog < infile" won't work until we download infile.
+ set prog [lindex $cmdline 0]
+ set prog [remote_download host $prog a.out];
+ set cmdline [lreplace $cmdline 0 0 $prog]
+ }
+
+ return [eval remote_spawn host \{ $sim $simflags $cmdline \} $args];
+}
+
+proc sim_wait { dest timeout } {
+ return [remote_wait host $timeout];
+}
+
+proc sim_load { dest prog args } {
+ set inpfile ""
+ if { [llength $args] > 1 } {
+ if { [lindex $args 1] != "" } {
+ set inpfile "[lindex $args 1]"
+ }
+ }
+
+ if ![file exists $prog] then {
+ perror "sim.exp: $prog to be downloaded does not exist."
+ verbose -log "$prog to be downloaded does not exist." 3
+ return [list "untested" ""];
+ }
+
+ if [board_info $dest exists sim_time_limit] {
+ set sim_time_limit [board_info $dest sim_time_limit];
+ } else {
+ set sim_time_limit 240
+ }
+
+ set output "";
+
+ # Run the program with a limited amount of real time. While
+ # this isn't as nice as limiting the amount of CPU time, it
+ # will have to do.
+ if { $inpfile != "" } {
+ set res [remote_spawn target "${prog} < $inpfile" "readonly"];
+ } else {
+ set res [remote_spawn target "${prog}"];
+ }
+
+ if { $res <= 0 } {
+ return [list "fail" "remote_spawn failed"];
+ }
+
+ set state [remote_wait target $sim_time_limit];
+ set status [lindex $state 0];
+ set output [lindex $state 1];
+ verbose "Output is $output";
+
+ set status2 [check_for_board_status output];
+ if { $status2 >= 0 } {
+ set status $status2
+ }
+
+ # FIXME: Do we need to examine $status?
+ # Yes, we do--what if the simulator itself gets an error and coredumps?
+
+ verbose "Return status was: $status" 2
+ if { $status == 0 } {
+ set result "pass"
+ } else {
+ set result "fail"
+ }
+ return [list $result $output];
+}
+
+set_board_info protocol "sim";
+
+# By default, assume the simulator is slow. This causes some tests
+# to either be simplified or skipped completely.
+set_board_info slow_simulator 1
diff --git a/dejagnu/config/slite.exp b/dejagnu/config/slite.exp
new file mode 100644
index 00000000000..19bf612c986
--- /dev/null
+++ b/dejagnu/config/slite.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_generic_config "gdb_stub";
diff --git a/dejagnu/config/sparclet.exp b/dejagnu/config/sparclet.exp
new file mode 100644
index 00000000000..3f860988f34
--- /dev/null
+++ b/dejagnu/config/sparclet.exp
@@ -0,0 +1,26 @@
+# Copyright (C) 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Michael Snyder <msnyder@cygnus.com>.
+
+load_generic_config "gdb_stub";
+
+# This is the old GDB prompt for the toolchain.
+# Uncomment for old tests
+#set_board_info gdb_prompt "\\(gdbslet\\)";
diff --git a/dejagnu/config/tic80.exp b/dejagnu/config/tic80.exp
new file mode 100644
index 00000000000..ef12778309e
--- /dev/null
+++ b/dejagnu/config/tic80.exp
@@ -0,0 +1,81 @@
+#
+# Nasty ugly stuff.
+#
+# We have to maintain two connections to the DOS box where the board
+# is being held. One of them runs an I/O monitor process, while the other
+# is used to actually start the program under test running on the board.
+#
+
+proc tic80_load { dest prog args } {
+ set dos_box [board_info $dest dos_host];
+
+ remote_spawn $dos_box [board_info $dest io_program];
+
+ set status [remote_ld $dest $prog];
+
+ if { $status != "pass" } {
+ return $status;
+ }
+
+ set result [remote_wait $dos_box 300];
+ set output [lindex $result 1];
+ if { [lindex $result 0] < 0 } {
+ if [board_info $dos_box exists fileid] {
+ dos_interrupt_job $dos_box;
+ } else {
+ remote_close $dos_box;
+ }
+ }
+
+ set status "fail";
+ regsub "(\\*\\*\\* EXIT code \[0-9\]+\[\r\n]+).*$" "$output" "\\1" output;
+ verbose "board out is $output";
+ set bstatus [check_for_board_status output];
+ if { [lindex $result 0] >= 0 } {
+ if { $bstatus == 0 } {
+ set status "pass";
+ }
+ }
+ remote_file build delete "a.fix";
+ return [list $status $output];
+}
+
+proc tic80_ld { dest prog } {
+ set dos_box [board_info $dest dos_host];
+ set dopush 0;
+
+ if { [remote_swap_conn $dos_box] == "fail" } {
+ if { [remote_push_conn $dos_box] == "fail" } {
+ set dopush 1;
+ }
+ remote_open $dos_box;
+ }
+ set prog [remote_download $dos_box $prog "a.fix"];
+
+ remote_spawn $dos_box "[board_info $dest start_program] $prog";
+ remote_expect $dos_box 10 {
+ -re "file\[(\]s\[)\] copied" {}
+ }
+ sleep 3;
+ dos_interrupt_job $dos_box;
+ if { $dopush } {
+ remote_push_conn $dos_box;
+ } else {
+ remote_swap_conn $dos_box;
+ }
+ return "pass";
+}
+#
+# Close the connection to the DOS box.
+#
+proc tic80_close { host } {
+ set dos_box [board_info $host dos_host];
+
+ return [remote_close $dos_box];
+}
+
+set_board_info protocol "tic80";
+set_board_info gdb,use_standard_load 1;
+set_board_info gdb,no_push_conn 1;
+set_board_info gdb,do_reload_on_run 1;
+set_board_info gdb,use_breakpoint_for_stub 1
diff --git a/dejagnu/config/udi.exp b/dejagnu/config/udi.exp
new file mode 100644
index 00000000000..4e10c4fff23
--- /dev/null
+++ b/dejagnu/config/udi.exp
@@ -0,0 +1,158 @@
+# Copyright (C) 1994, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was originally written by Rob Savoye. (rob@cygnus.com)
+# and modified by Bob Manson (manson@cygnus.com)
+
+# When using the simulator (-n iss) and running nice'd, things can naturally
+# take a little longer, so increase the timeout.
+
+#
+# udi_load -- load the program and execute it
+#
+# See default.exp for explanation of arguments and results.
+#
+
+proc udi_load { dest prog args } {
+ set shell_prompt [board_info $dest shell_prompt];
+ set output "";
+
+ if ![file exists $prog] then {
+ perror "$prog does not exist."
+ verbose -log "$prog does not exist." 3
+ return [list "untested" ""];
+ }
+
+ # Load the program.
+ if ![board_info $dest exists fileid] then {
+ remote_open $dest;
+ if ![board_info $dest exists fileid] then {
+ verbose -log "$prog not executed, couldn't connect to $dest." 3
+ return "untested"
+ }
+ }
+
+ if { [remote_ld $dest $prog] == "" } {
+ verbose -log "$prog not executed, load failed." 3
+ return [list "unresolved" ""];
+ }
+
+ # Execute it.
+ set result -1
+ set output "";
+ set noappend 0;
+
+ verbose "Executing $prog." 2
+ remote_send $dest "g\n"
+ # FIXME: The value 300 below should be a parameter.
+ remote_expect $dest 300 {
+ -re "(.*)Process exited with 0x0\[^\r\n\]*\[\r\n\]" {
+ append output $expect_out(1,string);
+ verbose "$prog executed successfully" 2
+ set noappend 1;
+ set result 0;
+ exp_continue;
+ }
+ -re "(.*)Halt instruction encountered" {
+ append output $expect_out(1,string);
+ verbose "$prog got a HALT instruction" 2
+ set result 1;
+ set noappend 1;
+ exp_continue;
+ }
+ -re "(^|\[\r\n\])$shell_prompt" {
+ if { $result == -1 } {
+ exp_continue;
+ }
+ }
+ -re "(^|\[\r\n\]+)g\[\r\n\]+" {
+ exp_continue;
+ }
+ -re "\[\r\n\]+" {
+ if { ! $noappend } {
+ append output $expect_out(buffer);
+ if { [string length $output] < 512000 } {
+ exp_continue;
+ } else {
+ set result 1;
+ }
+ } else {
+ exp_continue;
+ }
+ }
+ timeout {
+ warning "$prog timed out."
+ }
+ }
+
+ # See what happened.
+ switch -- $result {
+ 0 {
+ set status [check_for_board_status output];
+ if { $status < 0 } {
+ blammo
+ }
+ if { $status > 0 } {
+ set result "fail";
+ } else {
+ set result "pass"
+ }
+ }
+ 1 - -1 {
+ warning "Resetting $dest."
+ remote_send $dest "r\n"
+ remote_expect $dest 5 {
+ -re "r.*$shell_prompt.*" {
+ verbose "Target reset." 2
+ }
+ timeout {
+ # Get nastier. We want to leave the system in a state
+ # ready to run the next testcase.
+ remote_send $dest "q\n"
+ remote_close $dest;
+ set udi_shell_id [remote_open $dest]
+ if { $udi_shell_id < 0 } {
+ perror "Couldn't reset $dest."
+ }
+ }
+ }
+ if { $result == 1 } {
+ set result "fail"
+ } else {
+ set result "unresolved"
+ }
+ }
+ default {
+ set result "unresolved"
+ }
+ }
+ return [list $result $output];
+}
+
+#
+# udi_exit -- shutdown the connection (or simulator)
+#
+
+proc udi_exit {} {
+ remote_close target;
+}
+
+set_board_info protocol "udi";
+set_board_info connect "mondfe";
+set_board_info shell_prompt "mondfe>";
diff --git a/dejagnu/config/unix.exp b/dejagnu/config/unix.exp
new file mode 100644
index 00000000000..d3e7fabfaa4
--- /dev/null
+++ b/dejagnu/config/unix.exp
@@ -0,0 +1,134 @@
+# Copyright (C) 92, 1993, 1994, 1996, 1997, 1998 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gcc@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if ![info exists board] {
+ error "must set $board before loading unix.exp"
+}
+
+# For rcp_download, rsh_exec.
+load_lib remote.exp
+
+#
+# unix_load -- load the program and execute it
+#
+# See default.exp for explanation of arguments and results.
+#
+
+
+proc unix_load { dest prog args } {
+ global ld_library_path
+ set output "";
+
+ if { [llength $args] > 0 } {
+ set parg [lindex $args 0];
+ } else {
+ set parg ""
+ }
+
+ if { [llength $args] > 1 } {
+ set inp [lindex $args 1];
+ } else {
+ set inp ""
+ }
+
+ if ![file exists $prog] then {
+ # We call both here because this should never happen.
+ perror "$prog does not exist in unix_load."
+ verbose -log "$prog does not exist." 3
+ return "untested"
+ }
+ verbose "loading to $dest" 2
+ if ![is_remote $dest] {
+ if { "$inp" != "" } {
+ set command "$prog $parg < $inp"
+ } else {
+ set command "$prog $parg";
+ }
+
+ if [info exists ld_library_path] {
+ setenv LD_LIBRARY_PATH $ld_library_path
+ setenv SHLIB_PATH $ld_library_path
+ }
+
+ set id [remote_spawn $dest "$command" "readonly"];
+ if { $id < 0 } {
+ set output "remote_spawn failed"
+ set status -1;
+ } else {
+ set status [remote_wait $dest 300];
+ set output [lindex $status 1];
+ set status [lindex $status 0];
+ }
+ # Unset them so we don't potentially get hosed when we try to run a
+ # non-testcase executable. (Setting LD_LIBRARY_PATH is the wrong
+ # fix in the first place; this just tries to minimize the resulting
+ # crap.)
+ if [info exists ld_library_path] {
+ unsetenv LD_LIBRARY_PATH
+ unsetenv SHLIB_PATH
+ }
+ } else {
+ set remotefile "/tmp/[file tail $prog].[pid]"
+ set remotefile [remote_download $dest $prog $remotefile];
+ if { $remotefile == "" } {
+ verbose -log "Download of $prog to [board_info $dest name] failed." 3
+ return [list "unresolved" ""];
+ }
+ if [board_info $dest exists remote_link] {
+ if [[board_info $dest remote_link] $remotefile] {
+ verbose -log "Couldn't do remote link"
+ remote_exec $dest "\\rm -f $remotefile"
+ return [list "unresolved" ""]
+ }
+
+ verbose "$prog linked ok" 3
+ } else {
+ # rcp's to lynx seem not to get marked executable
+ set status [remote_exec $dest "chmod +x $remotefile"]
+ if { [lindex $status 0] != 0 } {
+ remote_file $dest delete ${remotefile}.o $remotefile
+ verbose -log "chmod +x of $prog on $dest failed." 3
+ return [list "unresolved" ""];
+ }
+ }
+ set status [remote_exec $dest "$remotefile" $parg $inp]
+ remote_file $dest delete $remotefile.o $remotefile;
+ if { [lindex $status 0] < 0 } {
+ verbose -log "Couldn't execute $prog, [lindex $status 1]" 3
+ return [list "unresolved" ""]
+ }
+ set output [lindex $status 1]
+ set status [lindex $status 0]
+ }
+
+ verbose "Executed $prog, status $status" 2
+ if ![string match "" $output] {
+ verbose -- "$output" 2
+ }
+ if { $status == 0 } {
+ set result "pass";
+ } else {
+ set result "fail";
+ }
+ return [list $result $output];
+}
+
+set_board_info protocol "unix";
diff --git a/dejagnu/config/vr4100.exp b/dejagnu/config/vr4100.exp
new file mode 100644
index 00000000000..16d20b84591
--- /dev/null
+++ b/dejagnu/config/vr4100.exp
@@ -0,0 +1,21 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# We're using a ddb monitor.
+load_generic_config "ddb";
diff --git a/dejagnu/config/vr4300.exp b/dejagnu/config/vr4300.exp
new file mode 100644
index 00000000000..16d20b84591
--- /dev/null
+++ b/dejagnu/config/vr4300.exp
@@ -0,0 +1,21 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# We're using a ddb monitor.
+load_generic_config "ddb";
diff --git a/dejagnu/config/vr5000.exp b/dejagnu/config/vr5000.exp
new file mode 100644
index 00000000000..01945cf10f7
--- /dev/null
+++ b/dejagnu/config/vr5000.exp
@@ -0,0 +1,21 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# We're using a ddb monitor, but we want to use the ethernet to load files.
+load_generic_config "ddb-ether";
diff --git a/dejagnu/config/vrtx.exp b/dejagnu/config/vrtx.exp
new file mode 100644
index 00000000000..cff962cb6b5
--- /dev/null
+++ b/dejagnu/config/vrtx.exp
@@ -0,0 +1,50 @@
+# Copyright (C) 1994, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gcc@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+# This file uses the xsh protocol.
+
+#
+# load support libraries
+#
+load_lib remote.exp
+
+#
+# ${tool}_load -- load the program and execute it
+#
+# See default.exp for explanation of arguments and results.
+#
+
+proc vrtx_load { dest prog args } {
+ remote_open $dest;
+
+ switch -- [remote_download $dest $prog] {
+ 0 { return "pass" }
+ 1 { return "fail" }
+ -1 {
+ # FIXME: This needs work (as does xsh_load).
+ verbose -log "Unable to run $prog, internal spectra error." 3
+ return "unresolved"
+ }
+ }
+}
+
+set_board_info protocol "vrtx"
+set_board_info connect "xsh"
diff --git a/dejagnu/config/vxworks.exp b/dejagnu/config/vxworks.exp
new file mode 100644
index 00000000000..3ab4a71734d
--- /dev/null
+++ b/dejagnu/config/vxworks.exp
@@ -0,0 +1,511 @@
+# Copyright (C) 92, 93, 94, 95, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was originally written by Rob Savoye. (rob@cygnus.com)
+# and modified by Bob Manson (manson@cygnus.com)
+
+#
+# Try to boot the machine into the requested OS.
+#
+proc ${board}_init { dest } {
+ # This is not the right way to determine the required OS...
+ global target_os;
+ set shell_prompt [board_info $dest shell_prompt];
+ set do_reboot 0;
+
+ set desired_kernel [board_info $dest "kernel,$target_os"];
+
+ if { $desired_kernel == "" } {
+ vxworks_final_init $dest;
+ # Nothing to see here, nothing to do. Move along.
+ return;
+ }
+
+ remote_raw_open $dest raw;
+ remote_send $dest "\n";
+ remote_expect $dest 5 {
+ -re "$shell_prompt" {
+ set do_reboot 1;
+ }
+ -re "Press any key to stop auto-boot" {
+ remote_send $dest "\n";
+ exp_continue;
+ }
+ -re "VxWorks Boot" {
+ set boot_mon 0;
+ set boot_mon_prompt "VxWorks Boot";
+ }
+ -re "\[0-9\]\[\r\n\]+ *\[0-9\]\[\r\n\]" {
+ remote_send $dest "\n";
+ exp_continue;
+ }
+ timeout {
+ set do_reboot 1;
+ }
+ }
+
+ if { $do_reboot } {
+ remote_close $dest;
+ remote_reboot $dest;
+ return;
+ }
+ remote_binary $dest;
+ remote_send $dest "\n\n";
+ remote_expect $dest 3 {
+ timeout {}
+ -re ".+" { exp_continue; }
+ }
+ remote_send $dest "p\n";
+ remote_expect $dest 20 {
+ -re "file name\[ \t\]+: (\[^ \r\n\]+)\[ \r\n\]+" {
+ set curr_file $expect_out(1,string);
+ exp_continue;
+ }
+ -re "$boot_mon_prompt" { }
+ }
+ if ![info exists curr_file] {
+ remote_close $dest;
+ remote_reboot $dest;
+ return;
+ }
+ if { $curr_file != $desired_kernel } {
+ verbose "$curr_file != '$desired_kernel'";
+ # Oh boy.
+ remote_send $dest "c\n";
+ remote_expect $dest 20 {
+ -re "file name\[ \t\]+:.*$" {
+ remote_send $dest "$desired_kernel\n";
+ exp_continue;
+ }
+ -re "\[a-z() \t\]+:.*$" {
+ remote_send $dest "\n";
+ exp_continue;
+ }
+ -re "$boot_mon_prompt" {}
+ }
+ }
+ remote_send $dest "@\n";
+ remote_expect $dest 30 {
+ -re "(^|\[\r\n\])$shell_prompt" {}
+ -re ".+" {
+ exp_continue;
+ }
+ }
+ vxworks_final_init $dest;
+ remote_close $dest;
+}
+
+proc vxworks_final_init { dest } {
+ if [board_info $dest exists preload_obj] {
+ if { [target_compile [board_info $dest preload_obj] foo.out object [board_info $dest preload_obj_flags]] == "" } {
+ vxworks_ld $dest foo.out
+ }
+ remote_file build delete foo.out;
+ }
+}
+#
+# Execute the command PROGRAM on VxWorks.
+#
+
+proc vxworks_exec { dest program pargs inp outp } {
+ global decimal hex;
+
+ set shell_id [vxworks_open $dest];
+ if { $shell_id < 0 } {
+ return [list -1 "open failure"];
+ }
+
+ if { $inp != "" } {
+ set inp [remote_download $dest $inp];
+ set suffix " < $inp";
+ } else {
+ set suffix ""
+ }
+
+ set shell_prompt [board_info $dest shell_prompt];
+ remote_send $dest "${program} ${pargs}$suffix\n";
+ # FIXME: The value 300 below should probably be a parameter passed in.
+ remote_expect $dest 300 {
+ -re "\\\[VxWorks Boot\\\]:" {
+ remote_send $dest "@\n";
+ sleep 20;
+ exp_continue;
+ }
+ -re "(.*)value = (-*$decimal) = $hex\[^\r\n\]*\[\r\n\]+$shell_prompt" {
+ set result [list $expect_out(2,string) $expect_out(1,string)];
+ }
+ -re "undefined symbol: .*$shell_prompt" {
+ set result [list 1 "unknown command"];
+ }
+ -re "syntax error.*$shell_prompt" {
+ set result [list -1 "syntax error in command"];
+ }
+ default {
+ set result [list -1 "unable to execute command"];
+ }
+ }
+ if { $suffix != "" } {
+ remote_file $dest delete $inp;
+ }
+ return $result;
+}
+
+proc vxworks_download { dest localfile remotefile } {
+ if [board_info $dest exists vxworks_homedir] {
+ set rfile "[board_info $dest vxworks_homedir]/$remotefile";
+ remote_download build $localfile $rfile;
+ return $rfile;
+ }
+ return [remote_raw_download $dest $localfile $remotefile];
+}
+
+proc vxworks_file { dest op args } {
+ set file [lindex $args 0];
+ if [board_info $dest exists vxworks_homedir] {
+ set dir "[board_info $dest vxworks_homedir]";
+ switch $op {
+ exists {
+ set file "${dir}/[file tail $file]";
+ return [file exists $file];
+ }
+ delete {
+ foreach x $args {
+ set x "${dir}/[file tail $x]";
+ if { [file exists $x] && [file isfile $x] } {
+ exec rm -f $x;
+ }
+ }
+ return;
+ }
+ }
+ }
+ return [eval remote_raw_file \"$dest\" \"$op\" $args];
+}
+
+proc vxworks_send { dest string } {
+ # Convert LFs to CRs, 'cause that is what VxWorks wants to see.
+ regsub -all "\n" $string "\r" string;
+ verbose "Sending '$string' to $dest" 2
+ return [remote_raw_send $dest "$string"];
+}
+
+proc vxworks_open { dest args } {
+ if [board_info $dest exists fileid] {
+ return [board_info $dest fileid];
+ }
+
+ set shell_prompt [board_info $dest shell_prompt]
+
+ set shell_id [remote_raw_open $dest];
+
+ if { $shell_id == "" || $shell_id < 0 } {
+ return -1;
+ }
+
+ if [board_info $dest exists logname] {
+ set logname [board_info $dest logname];
+ if [board_info $dest exists password] {
+ remote_send $dest "iam \"$logname\",\"[board_info $dest passwd]\"\r"
+ } else {
+ remote_send $dest "iam \"$logname\"\r"
+ }
+
+ remote_expect $dest 30 {
+ "iam*value = 0 = 0x0*$shell_prompt" {
+ verbose "Set default user." 2
+ }
+ timeout {
+ # ??? This is really an error. It's not clear whether `perror'
+ # or `warning' should be used here. There are *lots* of other
+ # cases like this.
+ perror "Couldn't set default user."
+ return -1;
+ }
+ }
+ }
+
+ set dir "";
+ if [board_info $dest exists ftp_directory] {
+ set dir [board_info $dest ftp_directory];
+ }
+ if [board_info $dest exists vxworks_homedir] {
+ set dir [board_info $dest vxworks_homedir];
+ }
+ if { $dir != "" } {
+ set status [remote_exec $dest "cd" "\"$dir\""];
+ if [lindex $status 0] {
+ perror "Error in cd to $dir--[lindex $status 1]";
+ return 1;
+ }
+ }
+ return $shell_id;
+}
+#
+# Load a file into vxworks
+#
+# The result is:
+# 0 - success
+# 1 - failed (eg: link failed so testcase should fail)
+# -1 - unresolved (eg: timeout), may be fixed by rebooting
+#
+proc vxworks_ld { dest prog } {
+ global decimal hex
+ global board_info
+
+ if { $prog == "" } {
+ return 1;
+ }
+
+ set shell_id [remote_open $dest];
+
+ if { $shell_id < 0 } {
+ return -1;
+ }
+
+ set prog [remote_download $dest $prog];
+
+ set shell_prompt [board_info $dest shell_prompt];
+
+ # We always want to exit the program via the code at the end.
+ # If the load fails we want `expect_out' stored in the log and this
+ # saves duplicating that code.
+
+ for { set x 0 ; } { $x < 3 } {incr x; } {
+ remote_send $dest "\n";
+ remote_expect $dest 30 {
+ -re ".*$shell_prompt $" { set x 20; }
+ -re "\\\[VxWorks Boot\\\]:" {
+ remote_send $dest "@\n";
+ sleep 20;
+ exp_continue;
+ }
+ timeout { return -1; }
+ }
+ }
+
+ set tries 0
+ set maxtries 3
+ set result -7 ;# -7 is a local value meaning "not done"
+
+ while { $result == -7 && $tries < $maxtries } {
+ verbose "Loading $prog into vxworks."
+ remote_send $dest "ld < $prog\n";
+ incr tries
+ remote_expect $dest 300 {
+ -re "USER.*command not understood" {
+ perror "Need to set the user and password."
+ set result 1
+ }
+ -re "Stale NFS file handle.*$shell_prompt $" {
+ # Need to retry.
+ }
+ -re "undefined symbol:.*$shell_prompt $" {
+ # This is an error in the testcase, don't call perror.
+ warning "Undefined symbol, $prog not loaded."
+ set result 1
+ }
+ -re "memPartAlloc: block too.*$shell_prompt $" {
+ perror "Not enough memory to load $prog."
+ set result -1
+ }
+ -re "can't open input.*$shell_prompt $" {
+ perror "Can't access $prog."
+ set result 1
+ }
+ -re "value = (-*${decimal}) = ${hex}.*$shell_prompt $" {
+ verbose "Loaded $prog into vxworks."
+ set board_info([board_info $dest name],vx_module) $expect_out(1,string);
+ set result 0
+ }
+ -re "(.*)$shell_prompt $" {
+ warning "Load failed: $expect_out(1,string)"
+ }
+ timeout {
+ warning "Timed out trying load $prog."
+ set result -1
+ }
+ }
+ }
+
+ if { $result && [info exists expect_out(buffer)] } {
+ send_log "$expect_out(buffer)"
+ }
+
+ remote_file $dest delete $prog;
+ return $result
+}
+
+#
+# Start a thread (process) executing
+#
+# The result is:
+# 0 - success
+# 1 - failed (eg: testcase aborted)
+# -1 - unresolved, may be fixed by rebooting
+#
+proc vxworks_run { dest function pargs inp outp } {
+ global hex decimal;
+
+ set shell_prompt [board_info $dest shell_prompt];
+ set output "";
+
+ # There isn't a command to wait for a thread to finish, so we have to keep
+ # polling. Instead, we expect the status wrapper to return an exit
+ # status.
+
+ set status [remote_exec $dest "sp" "$function $pargs" $inp $outp];
+
+ set tid [lindex $status 0];
+
+ # Bad task id, reboot and try again.
+ if { $tid == -1 || $tid == 0 } {
+ return -1;
+ }
+
+ set result 1;
+ # FIXME: The value 300 below should be a parameter.
+ remote_expect $dest 300 {
+ -re "task ${hex} - aborted.*$shell_prompt $" {
+ # FIXME: It's not clear we'll ever get here.
+ verbose "$function aborted"
+ set result 1
+ }
+ -re "\[\r\n\]syntax error\[\r\n\]" {
+ verbose "weirdness after task started"
+ set result -1;
+ }
+ -re "(.*)\\*\\*\\* EXIT code ($decimal)\[\r\n\]" {
+ set output "$expect_out(1,string)";
+ set exit_code "$expect_out(2,string)";
+ if { ($exit_code + 0) != 0 } {
+ set result 1;
+ } else {
+ set result 0;
+ }
+ }
+ -re "Operation Fault.*fault type:" {
+ set result 1;
+ }
+ -re "Bus Error" {
+ # This is here to try to cope with apparently flaky h/w.
+ # This is potentially an error in the testcase, but we don't
+ # really know, do we?
+ warning "Bus Error."
+ set result 1;
+ set output "Bus Error";
+ remote_reboot $dest;
+ }
+ timeout {
+ # Infinite loop? probably.
+ remote_exec $dest "td" "$tid";
+ set result 1;
+ }
+ }
+
+ return [list $result $output];
+}
+
+#
+# Unload the last executable that we loaded, so we can free up its memory.
+#
+proc vxworks_unld { dest } {
+ global board_info;
+
+ if [board_info $dest exists vx_module] {
+ # Vxworks5.0 does not have the unld command.
+ if { [board_info $dest os] != "vxworks5.0" } {
+ remote_exec $dest "unld" "[board_info $dest vx_module]";
+ }
+ unset board_info([board_info $dest name],vx_module);
+ }
+}
+
+#
+# We loop around rebooting the box until either the load and run
+# "work" or we give up.
+#
+proc vxworks_load {dest prog args} {
+ set result "";
+ set output "";
+
+ if { [llength $args] > 0 } {
+ set pargs "[lindex $args 0]";
+ } else {
+ set pargs ""
+ }
+
+ if { [llength $args] > 1 } {
+ set inp "[lindex $args 1]";
+ } else {
+ set inp ""
+ }
+
+ if { [llength $args] > 2 } {
+ set outp "[lindex $args 2]";
+ } else {
+ set outp ""
+ }
+
+ for { set x 0; } { $x < 3 } { incr x } {
+ set status [vxworks_ld $dest $prog];
+ if { $status >= 0 } {
+ if { $status > 0 } {
+ set result "fail";
+ } else {
+ set out [vxworks_run $dest __wrap_main $pargs $inp $outp];
+ set status [lindex $out 0];
+ set output [lindex $out 1];
+ # Get rid of the carriage returns, because they confuse
+ # callers that try to parse the result.
+ regsub -all "\r" $output "" output
+ if { $status != 0 } {
+ if { $status > 0 } {
+ set result "fail";
+ }
+ } else {
+ set result "pass";
+ }
+ }
+ }
+ if { $result != "" } {
+ vxworks_unld $dest;
+ return [list $result $output];
+ }
+ remote_reboot $dest;
+ }
+ return [list "fail" ""];
+}
+
+set_board_info protocol "vxworks"
+# -lm under vxworks isn't needed.
+set_board_info mathlib ""
+set_board_info shell_prompt "->"
+set_board_info needs_status_wrapper 1
+# FTP doesn't work in passive mode to this board.
+set_board_info ftp_no_passive 1
+# Wait 15 seconds after powercycling.
+set_board_info reboot_delay 15
+
+# We don't have sys/unistd.h.
+set_board_info wrap_compile_flags "-DNO_UNISTD_H"
+
+set_board_info gdb_prompt "\[(\]vxgdb\[)\]"
+
+set_board_info is_vxworks 1;
+set_board_info gdb,nosignals 1;
diff --git a/dejagnu/configure b/dejagnu/configure
new file mode 100755
index 00000000000..b845748c729
--- /dev/null
+++ b/dejagnu/configure
@@ -0,0 +1,1594 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=runtest.exp
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in .. $srcdir/..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in .. $srcdir/.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# 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"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:560: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:613: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# 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 (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $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".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+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"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:670: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=dejagnu
+
+VERSION=1.4
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:716: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:729: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:742: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:755: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:768: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:782: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:805: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:832: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 837 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:848: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:865: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 870 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:877: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:896: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:930: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:960: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1011: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1043: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1054 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1085: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1090: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1099: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1118: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# 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
+# 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"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1161: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+BOARDS='$(boards)'
+
+CONFIG='$(config)'
+
+
+subdirs="example/calc"
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile doc/Makefile example/Makefile testsuite/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@CC@%$CC%g
+s%@BOARDS@%$BOARDS%g
+s%@CONFIG@%$CONFIG%g
+s%@subdirs@%$subdirs%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile doc/Makefile example/Makefile testsuite/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+if test "$no_recursion" != yes; then
+
+ # Remove --cache-file and --srcdir arguments so they do not pile up.
+ ac_sub_configure_args=
+ ac_prev=
+ for ac_arg in $ac_configure_args; do
+ if test -n "$ac_prev"; then
+ ac_prev=
+ continue
+ fi
+ case "$ac_arg" in
+ -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=*)
+ ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ ;;
+ *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+ esac
+ done
+
+ for ac_config_dir in example/calc; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+ if test ! -d $srcdir/$ac_config_dir; then
+ continue
+ fi
+
+ echo configuring in $ac_config_dir
+
+ case "$srcdir" in
+ .) ;;
+ *)
+ if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :;
+ else
+ { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; }
+ fi
+ ;;
+ esac
+
+ ac_popdir=`pwd`
+ cd $ac_config_dir
+
+ # A "../" for each directory in /$ac_config_dir.
+ ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
+
+ case "$srcdir" in
+ .) # No --srcdir option. We are building in place.
+ ac_sub_srcdir=$srcdir ;;
+ /*) # Absolute path.
+ ac_sub_srcdir=$srcdir/$ac_config_dir ;;
+ *) # Relative path.
+ ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;;
+ esac
+
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_sub_srcdir/configure; then
+ ac_sub_configure=$ac_sub_srcdir/configure
+ elif test -f $ac_sub_srcdir/configure.in; then
+ ac_sub_configure=$ac_configure
+ else
+ echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2
+ ac_sub_configure=
+ fi
+
+ # The recursion is here.
+ if test -n "$ac_sub_configure"; then
+
+ # Make the cache file name correct relative to the subdirectory.
+ case "$cache_file" in
+ /*) ac_sub_cache_file=$cache_file ;;
+ *) # Relative path.
+ ac_sub_cache_file="$ac_dots$cache_file" ;;
+ esac
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
+ # The eval makes quoting arguments work.
+ if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
+ then :
+ else
+ { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
+ fi
+ fi
+
+ cd $ac_popdir
+ done
+fi
+
+
diff --git a/dejagnu/configure.in b/dejagnu/configure.in
new file mode 100644
index 00000000000..fb0bf0d80ec
--- /dev/null
+++ b/dejagnu/configure.in
@@ -0,0 +1,24 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.13)
+AC_INIT(runtest.exp)
+AC_CONFIG_AUX_DIR(..)
+
+dnl These are required by automake
+AM_INIT_AUTOMAKE(dejagnu, 1.4)
+AM_MAINTAINER_MODE
+AC_PROG_MAKE_SET
+AC_EXEEXT
+
+AC_PROG_CC
+AC_PROG_INSTALL
+
+dnl Level of indirection for automake macro (baseboards:boards_DATA)
+BOARDS='$(boards)'
+AC_SUBST(BOARDS)
+CONFIG='$(config)'
+AC_SUBST(CONFIG)
+
+AC_CONFIG_SUBDIRS(example/calc)
+
+AC_OUTPUT(Makefile doc/Makefile example/Makefile testsuite/Makefile)
+
diff --git a/dejagnu/contrib/README b/dejagnu/contrib/README
new file mode 100644
index 00000000000..d776f6e7e50
--- /dev/null
+++ b/dejagnu/contrib/README
@@ -0,0 +1,16 @@
+These are "user" contributed scripts that automate testing. These all
+depend on using "make check", so they are included here as an aid to
+helping others automate their own testing. All of these script do
+report filtering on the output from DejaGnu. test-tool and test-g++
+are basically the same script. test-target is the script I use for our
+quarterly release and it is the most sophisticated. It still uses
+"make check" (a make target that start runtest) to produce the
+results, but tests our entire tool chain for native and crosses. It
+also produces a short summary report that gets emailed, as well as
+summary reports. It does regression analysis using the previous test
+run. testit is a very crude and simple Tk GUI for accessing all the
+testing results. Hope these are helpful to anyone, I'd like to collect
+more from the net as they get developed.
+
+ - rob -
+
diff --git a/dejagnu/contrib/test-g++ b/dejagnu/contrib/test-g++
new file mode 100755
index 00000000000..91f14c1de3d
--- /dev/null
+++ b/dejagnu/contrib/test-g++
@@ -0,0 +1,89 @@
+#!/bin/sh
+
+# Default DEVOSRCDIR
+if [ "$DEVOSRCDIR" = "" ]; then
+ DEVOSRCDIR=$HOME/devo ; export DEVOSRCDIR
+fi
+
+# Check DEVOSRCDIR
+if [ ! -d "$DEVOSRCDIR" ]; then
+ echo "$0: no directory $DEVOSRCDIR" >&2
+ exit 2
+fi
+
+# Default DEVOBINDIR
+if [ "$DEVOBINDIR" = "" ]; then
+ CPU=`$DEVOSRCDIR/config.guess`
+ if [ $? != 0 ]; then
+ echo "$0: cannot run config.guess" >&2
+ exit 2
+ fi
+ DEVOBINDIR=$HOME/$CPU ; export DEVOBINDIR
+fi
+
+# Check DEVOBINDIR
+if [ ! -d "$DEVOBINDIR" ]; then
+ echo "$0: no directory $DEVOBINDIR" >&2
+ exit 2
+fi
+
+# Default LOGDIR
+if [ "$LOGDIR" = "" ]; then
+ LOGDIR=$HOME/logs ; export LOGDIR
+fi
+
+# Check LOGDIR
+if [ ! -d "$LOGDIR" ]; then
+ echo "$0: no directory $LOGDIR" >&2
+ exit 2
+fi
+
+cd $LOGDIR || exit 2
+
+sum=g++-`date '+%y%m%d'`
+
+$DEVOSRCDIR/dejagnu/contrib/test-tool g++ > $sum 2>&1
+status=$?
+
+if [ -d $DEVOBINDIR/libg++ ]; then
+
+cd $DEVOBINDIR/libg++
+make check >/tmp/clgpp$$ 2>&1
+if [ $? != 0 ]; then
+ cd $LOGDIR
+ echo "" >> $sum
+ echo "libg++ fails to make check:" >> $sum
+ tail -20 /tmp/clgpp$$ >> $sum
+ if [ $status = 0 ]; then
+ status=1
+ fi
+fi
+
+# libg++?
+fi
+
+cd $DEVOBINDIR/libio
+make check >/tmp/clgpp$$ 2>&1
+if [ $? != 0 ]; then
+ cd $LOGDIR
+ echo "" >> $sum
+ echo "libio fails to make check:" >> $sum
+ tail -20 /tmp/clgpp$$ >> $sum
+ if [ $status = 0 ]; then
+ status=1
+ fi
+fi
+
+cd $DEVOBINDIR/libstdc++
+make check >/tmp/clgpp$$ 2>&1
+if [ $? != 0 ]; then
+ cd $LOGDIR
+ echo "" >> $sum
+ echo "libstdc++ fails to make check:" >> $sum
+ tail -20 /tmp/clgpp$$ >> $sum
+ if [ $status = 0 ]; then
+ status=1
+ fi
+fi
+
+exit $status
diff --git a/dejagnu/contrib/test-tool b/dejagnu/contrib/test-tool
new file mode 100755
index 00000000000..32ab8870918
--- /dev/null
+++ b/dejagnu/contrib/test-tool
@@ -0,0 +1,378 @@
+#!/bin/sh
+# This script automatically test the given tool with the tool's test cases,
+# reporting anything of interest.
+
+# exits with 1 if there is nothing of interest
+# exits with 0 if there is something interesting
+# exits with 2 if an error occurred
+
+# Syntax: test-tool [-expectedpass] [-keepoutput] [-noupdate] g++|gcc|gdb|...
+#
+# -expectedpass: Turn XFAIL into "pass", XPASS into "fail".
+# The default is XFAIL->fail, XPASS->pass.
+# -keepoutput: Save "make check" output in test-$tool.log.
+# -noupdate: Don't update log files.
+
+# Limitations, don't run this multiple times in one day, unless the -noupdate
+# flag is given.
+
+# Written by Mike Stump <mrs@cygnus.com>
+
+expectedpass=no
+keepoutput=no
+update=yes
+tool=""
+
+# See if cp -p works.
+pwd=`pwd`
+cd /tmp
+rm -f test-tool-$$-1 test-tool-$$-2
+touch test-tool-$$-1
+cp -p test-tool-$$-1 test-tool-$$-2 2>/dev/null
+if [ $? = 0 -a -f test-tool-$$-2 ] ; then
+ CP="cp -p"
+else
+ CP=cp
+fi
+rm -f test-tool-$$-1 test-tool-$$-2
+cd $pwd
+
+for arg in $*
+do
+ case $arg in
+ -expectedpass) expectedpass=yes ;;
+ -keepoutput) keepoutput=yes ;;
+ -noupdate) update=no ;;
+ -*)
+ echo "Usage: [-expectedpass] [-keepoutput] [-noupdate] tool_name" >&2
+ exit 2
+ ;;
+ *)
+ if [ "$tool" != "" ]; then
+ echo "Usage: [-expectedpass] [-keepoutput] [-noupdate] tool_name" >&2
+ exit 2
+ fi
+ tool=$arg
+ ;;
+ esac
+done
+
+# FIXME: It sure would be nice if `testdir' wasn't necessary. :-(
+
+case $tool in
+ g++)
+ devoname=gcc
+ checktarget=check-g++
+ testdir=testsuite
+ ;;
+ gcc)
+ devoname=gcc
+ checktarget=check-gcc
+ testdir=testsuite
+ ;;
+ ld|gld)
+ devoname=ld
+ checktarget=check
+ testdir=.
+ ;;
+ binutils)
+ devoname=binutils
+ checktarget=check
+ testdir=.
+ ;;
+ *)
+ devoname=$tool
+ checktarget=check
+ testdir=testsuite
+ ;;
+esac
+
+# Default DEVOSRCDIR
+if [ "$DEVOSRCDIR" = "" ]; then
+ DEVOSRCDIR=$HOME/devo ; export DEVOSRCDIR
+fi
+
+# Check DEVOSRCDIR
+if [ ! -d "$DEVOSRCDIR" ]; then
+ echo "$0: no directory $DEVOSRCDIR" >&2
+ exit 2
+fi
+
+# Default DEVOBINDIR
+if [ "$DEVOBINDIR" = "" ]; then
+ CPU=`$DEVOSRCDIR/config.guess`
+ if [ $? != 0 ]; then
+ echo "$0: cannot run config.guess" >&2
+ exit 2
+ fi
+ DEVOBINDIR=$HOME/$CPU ; export DEVOBINDIR
+fi
+
+# Check DEVOBINDIR
+if [ ! -d "$DEVOBINDIR" ]; then
+ echo "$0: no directory $DEVOBINDIR" >&2
+ exit 2
+fi
+
+# Specialize DEVOSRCDIR
+if [ -d "$DEVOSRCDIR/$devoname" ]; then
+ DEVOSRCDIR=$DEVOSRCDIR/$devoname
+else
+ echo "$0: Cannot find source directory." >&2
+ exit 2
+fi
+
+# Default LOGDIR
+if [ "$LOGDIR" = "" ]; then
+ LOGDIR=$HOME/logs ; export LOGDIR
+fi
+
+# Check LOGDIR
+if [ ! -d "$LOGDIR" ]; then
+ echo "$0: no directory $LOGDIR" >&2
+ exit 2
+fi
+
+# Specialize DEVOBINDIR
+if [ -d "$DEVOBINDIR/$devoname" ]; then
+ DEVOBINDIR=$DEVOBINDIR/$devoname
+else
+ echo "$0: Cannot find binary directory." >&2
+ exit 2
+fi
+
+# Binary directory
+cd $DEVOBINDIR || exit 2
+
+TMPDIR=${TMPDIR-/tmp}
+
+tmp=$TMPDIR/$tool-testing.$$a
+tmp1=$TMPDIR/$tool-testing.$$b
+tmp2=$TMPDIR/$tool-testing.$$c
+now_s=$TMPDIR/$tool-testing.$$d
+before_s=$TMPDIR/$tool-testing.$$e
+
+if [ "$keepoutput" = yes ]; then
+ rm -f test-$tool.log
+ make RUNTESTFLAGS="-v -v" $checktarget >test-$tool.log 2>&1
+else
+ make RUNTESTFLAGS="-v -v" $checktarget >/dev/null 2>&1
+fi
+
+# Check for DEJAGNU errors that prevented any output at all.
+if [ ! -f $testdir/$tool.sum ]; then
+ echo "Tests didn't run, probably because of a framework error."
+ if [ "$keepoutput" = yes ]; then
+ echo
+ tail -20 test-$tool.log
+ else
+ echo "Unable to determine why. Rerun with -keepoutput."
+ fi
+ exit 2
+fi
+
+# Canonicalize XFAIL and XPASS so the rest of the script can ignore them.
+if [ "$expectedpass" = yes ]; then
+ sed 's/^XFAIL/PASS(XFAIL)/; s/^XPASS/FAIL(XPASS)/' <$testdir/$tool.sum >$testdir/$tool.1.sum || exit 2
+else
+ sed 's/^XFAIL/FAIL(XFAIL)/; s/^XPASS/PASS(XPASS)/' <$testdir/$tool.sum >$testdir/$tool.1.sum || exit 2
+fi
+mv $testdir/$tool.1.sum $testdir/$tool.sum
+
+patterns="$LOGDIR/$tool-??????.sum $LOGDIR/$tool-??????.sum.gz $LOGDIR/$tool-??????????.sum $LOGDIR/$tool-??????????.sum.gz"
+before=`ls -1t $patterns 2>/dev/null | sed 1q`
+
+todayname=`date '+%y%m%d'`
+if [ "$update" = no ]; then
+ now=$testdir/$tool.sum
+else
+ mv -f $testdir/$tool.sum $LOGDIR/$tool-$todayname.sum || exit 2
+ mv -f $testdir/$tool.log $LOGDIR/$tool-$todayname.log || exit 2
+
+ # Say where the logs are stored so they appear in email messages.
+ echo
+ echo "Log files: $LOGDIR/$tool-$todayname.*"
+ echo
+
+ now="$LOGDIR/$tool-$todayname.sum";
+fi
+
+trap "rm -f $tmp $tmp1 $tmp2 $now_s $before_s" 0 1 2 3 5 9 13 15
+
+case $before in
+ "") before="cat /dev/null" ;;
+ *.gz) before="gunzip -c $before" ;;
+ *) before="cat $before" ;;
+esac
+
+# First, the test summary.
+egrep '^# of |===.*Summary.*===' "$now" || echo "(No test summary?)"
+echo
+
+# Pick out the PASS/FAIL/Ufoo messages.
+# We grep for them again later but that's for robustness' sake.
+grep '^[PFU][A-Z()]*:' "$now" | sort -t ':' +1 > "$now_s"
+$before | grep '^[PFU][A-Z()]*:' | sort -t ':' +1 > "$before_s"
+
+grep '^FAIL:' "$now_s" | sed 's/^[^:]*:[ ]*//' >$tmp1
+grep '^PASS' "$before_s" | sed 's/^[^:]*:[ ]*//' | comm -12 $tmp1 - >$tmp2
+
+grep -s . $tmp2 >/dev/null
+if [ $? = 0 ]; then
+ echo "Tests that now unexpectedly fail, but worked before:"
+ echo
+ cat $tmp2
+ showchangelog=1
+ echo
+fi
+
+grep '^FAIL:' "$now_s" | sed 's/^[^:]*:[ ]*//' >$tmp1
+grep '^[PFU][A-Z()]*:' "$before_s" | sed 's/^[^:]*:[ ]*//' | comm -23 $tmp1 - >$tmp2
+
+grep -s . $tmp2 >/dev/null
+if [ $? = 0 ]; then
+ echo "New tests that unexpectedly FAIL:"
+ echo
+ cat $tmp2
+ echo
+fi
+
+grep '^FAIL:' "$now_s" | sed 's/^[^:]*:[ ]*//' >$tmp1
+grep '^FAIL' "$before_s" | sed 's/^[^:]*:[ ]*//' | comm -12 $tmp1 - >$tmp2
+
+grep -s . $tmp2 >/dev/null
+if [ $? = 0 ]; then
+ echo "Tests that still don't work:"
+ echo
+ cat $tmp2
+ echo
+fi
+
+grep '^PASS' "$now_s" | sed 's/^[^:]*:[ ]*//' >$tmp1
+grep '^FAIL' "$before_s" | sed 's/^[^:]*:[ ]*//' | comm -12 $tmp1 - >$tmp2
+
+grep -s . $tmp2 >/dev/null
+if [ $? = 0 ]; then
+ echo "Tests that now work, but didn't before:"
+ echo
+ cat $tmp2
+ echo
+fi
+
+grep '^PASS' "$now_s" | sed 's/^[^:]*:[ ]*//' >$tmp1
+grep '^[PFU][A-Z()]*:' "$before_s" | sed 's/^[^:]*:[ ]*//' | comm -23 $tmp1 - >$tmp2
+
+grep -s . $tmp2 >/dev/null
+if [ $? = 0 ]; then
+ echo "New tests that PASS:"
+ echo
+ cat $tmp2
+ echo
+fi
+
+grep '^[PFU][A-Z()]*:' "$now_s" | sed 's/^[^:]*:[ ]*//' >$tmp1
+grep '^PASS' "$before_s" | sed 's/^[^:]*:[ ]*//' | comm -13 $tmp1 - >$tmp2
+
+grep -s . $tmp2 >/dev/null
+if [ $? = 0 ]; then
+ echo "Old tests that passed, that have disappeared: (Eeek!)"
+ echo
+ cat $tmp2
+ echo
+fi
+
+grep '^[PFU][A-Z()]*:' "$now_s" | sed 's/^[^:]*:[ ]*//' >$tmp1
+grep '^FAIL' "$before_s" | sed 's/^[^:]*:[ ]*//' | comm -13 $tmp1 - >$tmp2
+
+grep -s . $tmp2 >/dev/null
+if [ $? = 0 ]; then
+ echo "Old tests that failed, that have disappeared: (Eeek!)"
+ echo
+ cat $tmp2
+ echo
+fi
+
+egrep '^(ERROR|WARNING):' "$now" >$tmp1
+
+if grep -s . $tmp1 > /dev/null; then
+ echo "Errors and warnings:"
+ echo
+ cat $tmp1
+ echo
+fi
+
+if [ "$tool" = g++ ]; then
+ if [ -f $DEVOBINDIR/libio/run-make-check ]; then
+ cd $DEVOBINDIR/libio
+ make check >$TMPDIR/clgpp$$ 2>&1
+ if [ $? != 0 ]; then
+ echo
+ echo "libio fails to make check:"
+ tail -20 $TMPDIR/clgpp$$
+ fi
+ fi
+ if [ -f $DEVOBINDIR/libstdc++/run-make-check ]; then
+ cd $DEVOBINDIR/libstdc++
+ make check >$TMPDIR/clgpp$$ 2>&1
+ if [ $? != 0 ]; then
+ echo
+ echo "libstdc++ fails to make check:"
+ tail -20 $TMPDIR/clgpp$$
+ fi
+ fi
+ if [ -f $DEVOBINDIR/libg++/run-make-check ]; then
+ cd $DEVOBINDIR/libg++
+ make check >$TMPDIR/clgpp$$ 2>&1
+ if [ $? != 0 ]; then
+ echo
+ echo "libg++ fails to make check:"
+ tail -20 $TMPDIR/clgpp$$
+ fi
+ fi
+ rm -f $TMPDIR/clgpp$$
+ cd $DEVOBINDIR
+fi
+
+if [ "$devoname" != "" ]; then
+ if [ "$showchangelog" = 1 ]; then
+ echo "Here is what's new in the ChangeLog:"
+ echo
+ diff -c $LOGDIR/$devoname.ChangeLog $DEVOSRCDIR/ChangeLog
+ echo
+ if [ "$tool" = g++ ]; then
+ echo
+ echo "Here is what's new in the ChangeLog.egcs:"
+ echo
+ diff -c $LOGDIR/gcc.ChangeLog.egcs $DEVOSRCDIR/ChangeLog.egcs
+
+ echo
+ echo "Here is what's new in the cp/ChangeLog:"
+ echo
+ diff -c $LOGDIR/g++.ChangeLog $DEVOSRCDIR/cp/ChangeLog
+ fi
+ echo
+ fi
+ if [ "$update" != no ]; then
+ # save the old ChangeLog as a reference for next time
+ rm -f $LOGDIR/$devoname.ChangeLog.BAK
+ mv $LOGDIR/$devoname.ChangeLog $LOGDIR/$devoname.ChangeLog.BAK 2>/dev/null
+ $CP $DEVOSRCDIR/ChangeLog $LOGDIR/$devoname.ChangeLog
+ if [ "$tool" = g++ ]; then
+ rm -f $LOGDIR/gcc.ChangeLog.egcs.BAK
+ mv $LOGDIR/gcc.ChangeLog.egcs $LOGDIR/gcc.ChangeLog.egcs.BAK 2>/dev/null
+ $CP $DEVOSRCDIR/ChangeLog.egcs $LOGDIR/gcc.ChangeLog.egcs
+
+ rm -f $LOGDIR/g++.ChangeLog.BAK
+ mv $LOGDIR/g++.ChangeLog $LOGDIR/g++.ChangeLog.BAK 2>/dev/null
+ $CP $DEVOSRCDIR/cp/ChangeLog $LOGDIR/g++.ChangeLog
+ fi
+ fi
+fi
+
+$before | diff - $now | grep -s . >/dev/null
+if [ $? = 0 ]; then
+ echo "Details:"
+ echo
+ $before | diff - $now
+ echo
+fi
diff --git a/dejagnu/contrib/testit b/dejagnu/contrib/testit
new file mode 100755
index 00000000000..e866aa6350e
--- /dev/null
+++ b/dejagnu/contrib/testit
@@ -0,0 +1,1149 @@
+#!/usr/latest/bin/wish -f
+# Program: testit
+# Tcl version: 7.2 (Tcl/Tk/XF)
+# Tk version: 3.5
+# XF version: 2.2
+#
+
+
+# procedure to show window .
+proc ShowWindow. {args} {# xf ignore me 7
+
+ # Window manager configurations
+ global tkVersion
+ wm positionfrom . user
+ wm sizefrom . ""
+ wm maxsize . 1152 900
+ wm title . {xf}
+
+ # bindings
+ bind . <Button-3> {MenuPopupPost .frame0.menubutton3.m.menu4 %X %Y}
+ bind . <ButtonRelease-3> {MenuPopupRelease .frame0.menubutton3.m.menu4 %W}
+
+ # build widget .frame0
+ frame .frame0 \
+ -background {white} \
+ -borderwidth {2} \
+ -relief {raised}
+
+ # build widget .frame0.menubutton0
+ menubutton .frame0.menubutton0 \
+ -background {white} \
+ -foreground {black} \
+ -menu {.frame0.menubutton0.m} \
+ -text {Summaries}
+
+ # build widget .frame0.menubutton0.m
+ menu .frame0.menubutton0.m \
+ -background {white} \
+ -foreground {black}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/gcc.sum
+
+} \
+ -label {Gcc}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/g++.sum
+
+} \
+ -label {G++}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/gdb.sum
+
+} \
+ -label {Gdb}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/gas.sum
+
+} \
+ -label {Gas}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/binutils.sum
+
+} \
+ -label {Binutils}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/runtest.sum
+
+} \
+ -label {Runtest}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/tcl.sum
+
+} \
+ -label {Tcl}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/expect.sum
+
+} \
+ -label {Expect}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/libg++.sum
+
+} \
+ -label {Libg++}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/libio.sum
+
+} \
+ -label {Libio}
+ .frame0.menubutton0.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/libm.sum
+
+} \
+ -label {Libm}
+
+ # build widget .frame0.menubutton1
+ menubutton .frame0.menubutton1 \
+ -background {white} \
+ -foreground {black} \
+ -menu {.frame0.menubutton1.m} \
+ -text {Misc}
+
+ # build widget .frame0.menubutton1.m
+ menu .frame0.menubutton1.m \
+ -background {white} \
+ -foreground {black}
+ .frame0.menubutton1.m add command \
+ -command {EndSrc
+destroy .} \
+ -label {Exit}
+ .frame0.menubutton1.m add command \
+ -command {.frame6.frame.text2 delete 0.0 end} \
+ -label {Clear window}
+ .frame0.menubutton1.m add command \
+ -command {dialogbox} \
+ -label {Editor}
+ .frame0.menubutton1.m add command \
+ -command {.frame6.frame.text2 insert 0.0 "Top of tree is $testbase\n"} \
+ -label {Show filename}
+
+ # build widget .frame0.menubutton3
+ menubutton .frame0.menubutton3 \
+ -background {white} \
+ -foreground {black} \
+ -menu {.frame0.menubutton3.m} \
+ -text {Host}
+
+ # build widget .frame0.menubutton3.m
+ menu .frame0.menubutton3.m \
+ -background {white} \
+ -foreground {black}
+ .frame0.menubutton3.m add command \
+ -command {set host "alpha-dec-osf1.3"} \
+ -label {alpha-dec-osf1.3}
+ .frame0.menubutton3.m add command \
+ -command {set host "hppa1.1-hp-hpux"} \
+ -label {hppa1.1-hp-hpux}
+ .frame0.menubutton3.m add command \
+ -command {set host "i386-unknown-sysv4.2"} \
+ -label {i386-unknown-sysv4.2}
+ .frame0.menubutton3.m add command \
+ -command {set host "m68k-hp-hpux"} \
+ -label {m68k-hp-hpux}
+ .frame0.menubutton3.m add command \
+ -command {set host "m68k-sun-sunos4.1.1"} \
+ -label {m68k-sun-sunos4.1.1}
+ .frame0.menubutton3.m add command \
+ -command {set host "mips-dec-ultrix4.2"} \
+ -label {mips-dec-ultrix4.2}
+ .frame0.menubutton3.m add command \
+ -command {set host "mips-sgi-irix4.0.5H"} \
+ -label {mips-sgi-irix4.0.5H}
+ .frame0.menubutton3.m add command \
+ -command {set host "rs6000-ibm-aix3.2"} \
+ -label {rs6000-ibm-aix3.2}
+ .frame0.menubutton3.m add command \
+ -command {set host "sparc-sun-solaris2.3"} \
+ -label {sparc-sun-solaris2.3}
+ .frame0.menubutton3.m add command \
+ -command {set host "sparc-sun-sunos4.1.3"} \
+ -label {sparc-sun-sunos4.1.3}
+
+ # build widget .frame0.menubutton2
+ menubutton .frame0.menubutton2 \
+ -background {white} \
+ -foreground {black} \
+ -menu {.frame0.menubutton2.m} \
+ -text {Target}
+
+ # build widget .frame0.menubutton2.m
+ menu .frame0.menubutton2.m \
+ -background {white} \
+ -foreground {black}
+ .frame0.menubutton2.m add command \
+ -command {set target "a29k-amd-udi"} \
+ -label {a29k-amd-udi}
+ .frame0.menubutton2.m add command \
+ -command {set target "h8300-hms"} \
+ -label {h8300-hms}
+ .frame0.menubutton2.m add command \
+ -command {set target "i386-aout"} \
+ -label {i386-aout}
+ .frame0.menubutton2.m add command \
+ -command {set target "i386-lynx"} \
+ -label {i386-lynx}
+ .frame0.menubutton2.m add command \
+ -command {set target "i960-intel-nindy"} \
+ -label {i960-intel-nindy}
+ .frame0.menubutton2.m add command \
+ -command {set target "i960-vxwork"} \
+ -label {i960-vxworks}
+ .frame0.menubutton2.m add command \
+ -command {set target "m68k-aout"} \
+ -label {m68k-aout}
+ .frame0.menubutton2.m add command \
+ -command {set target "m68k-coff"} \
+ -label {m68k-coff}
+ .frame0.menubutton2.m add command \
+ -command {set target "m68k-lynx"} \
+ -label {m68k-lynx}
+ .frame0.menubutton2.m add command \
+ -command {set target "m68k-vxworks"} \
+ -label {m68k-vxworks}
+ .frame0.menubutton2.m add command \
+ -command {set target "mips-idt-ecoff"} \
+ -label {mips-idt-ecoff}
+ .frame0.menubutton2.m add command \
+ -command {set target "sh-hms"} \
+ -label {sh-hms}
+ .frame0.menubutton2.m add command \
+ -command {set target "sparc-aout"} \
+ -label {sparc-aout}
+ .frame0.menubutton2.m add command \
+ -command {set target "sparc-sun-sunos4.1.3"} \
+ -label {sparc-sun-sunos4.1.3}
+ .frame0.menubutton2.m add command \
+ -command {set target "sparc-vxworks"} \
+ -label {sparc-vxworks}
+ .frame0.menubutton2.m add command \
+ -command {set target "sparclite-aout"} \
+ -label {sparclite-aout}
+ .frame0.menubutton2.m add command \
+ -command {set target "sparclite-coff"} \
+ -label {sparclite-coff}
+ .frame0.menubutton2.m add command \
+ -command {set target "hppa1.1-hp-hpux"} \
+ -label {hppa1.1-hp-hpux}
+ .frame0.menubutton2.m add command \
+ -command {set target "i386-unknown-sysv4.2"} \
+ -label {i386-unknown-sysv4.2}
+ .frame0.menubutton2.m add command \
+ -command {set target "m68k-hp-hpux"} \
+ -label {m68k-hp-hpux}
+ .frame0.menubutton2.m add command \
+ -command {set target "m68k-sun-sunos4.1.1"} \
+ -label {m68k-sun-sunos4.1.1}
+ .frame0.menubutton2.m add command \
+ -command {set target "mips-dec-ultrix4.2"} \
+ -label {mips-dec-ultrix4.2}
+ .frame0.menubutton2.m add command \
+ -command {set target "mips-sgi-irix4.0.5H"} \
+ -label {mips-sgi-irix4.0.5H}
+ .frame0.menubutton2.m add command \
+ -command {set target "rs6000-ibm-aix3.2"} \
+ -label {rs6000-ibm-aix3.2}
+ .frame0.menubutton2.m add command \
+ -command {set target "sparc-sun-solaris2.3"} \
+ -label {sparc-sun-solaris2.3}
+
+ # build widget .frame0.menubutton9
+ menubutton .frame0.menubutton9 \
+ -background {white} \
+ -foreground {black} \
+ -menu {.frame0.menubutton9.m} \
+ -text {Results}
+
+ # build widget .frame0.menubutton9.m
+ menu .frame0.menubutton9.m \
+ -background {white} \
+ -foreground {black}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/gcc
+
+} \
+ -label {Gcc}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/g++
+
+} \
+ -label {G++}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/gdb
+
+} \
+ -label {Gdb}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/gas
+
+} \
+ -label {Gas}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/binutils
+
+} \
+ -label {Binutils}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/runtest
+} \
+ -label {Runtest}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/tcl
+
+} \
+ -label {Tcl}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/expect
+
+} \
+ -label {Expect}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/libg++
+
+} \
+ -label {Libg++}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/libio
+} \
+ -label {Libio}
+ .frame0.menubutton9.m add command \
+ -command {getresult $testbase/objdir/$host/$target/logs/libm
+
+} \
+ -label {Libm}
+
+ # build widget .frame0.menubutton10
+ menubutton .frame0.menubutton10 \
+ -background {white} \
+ -foreground {black} \
+ -menu {.frame0.menubutton10.m} \
+ -text {Logs}
+
+ # build widget .frame0.menubutton10.m
+ menu .frame0.menubutton10.m \
+ -background {white} \
+ -foreground {black}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/gcc.log
+
+} \
+ -label {Gcc}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/g++.log
+
+} \
+ -label {G++}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/gdb.log
+
+} \
+ -label {Gdb}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/gas.log
+
+} \
+ -label {Gas}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/binutils.log
+
+} \
+ -label {Binutils}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/runtest.log
+
+} \
+ -label {Runtest}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/tcl.log
+
+} \
+ -label {Tcl}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/expect.log
+
+} \
+ -label {Expect}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/libg++.log
+
+} \
+ -label {Libg++}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/libio.log
+
+} \
+ -label {Libio}
+ .frame0.menubutton10.m add command \
+ -command {loadfile $testbase/objdir/$host/$target/logs/libm.log
+
+} \
+ -label {Libm}
+
+ # pack widget .frame0
+ pack append .frame0 \
+ .frame0.menubutton0 {left frame center} \
+ .frame0.menubutton1 {right frame center} \
+ .frame0.menubutton3 {left frame center} \
+ .frame0.menubutton2 {left frame center} \
+ .frame0.menubutton9 {left frame center} \
+ .frame0.menubutton10 {left frame center}
+
+ # build widget .frame1
+ frame .frame1 \
+ -background {white} \
+ -borderwidth {2} \
+ -relief {raised}
+
+ # build widget .frame1.message3
+ message .frame1.message3 \
+ -aspect {1500} \
+ -background {white} \
+ -borderwidth {0} \
+ -foreground {black} \
+ -padx {5} \
+ -pady {2} \
+ -relief {raised} \
+ -text {sparc-sun-sunos4.1.3} \
+ -textvariable {host}
+
+ # build widget .frame1.message4
+ message .frame1.message4 \
+ -aspect {1500} \
+ -background {white} \
+ -borderwidth {0} \
+ -foreground {black} \
+ -padx {5} \
+ -pady {2} \
+ -relief {raised} \
+ -text {sparc-sun-sunos4.1.3} \
+ -textvariable {target}
+
+ # pack widget .frame1
+ pack append .frame1 \
+ .frame1.message3 {left frame center} \
+ .frame1.message4 {right frame center}
+
+ # build widget .frame6
+ frame .frame6 \
+ -background {white} \
+ -borderwidth {2} \
+ -relief {raised}
+
+ # build widget .frame6.frame
+ frame .frame6.frame \
+ -background {white} \
+ -relief {raised}
+
+ # build widget .frame6.frame.scrollbar1
+ scrollbar .frame6.frame.scrollbar1 \
+ -background {white} \
+ -command {.frame6.frame.text2 yview} \
+ -foreground {black} \
+ -relief {raised}
+
+ # build widget .frame6.frame.text2
+ text .frame6.frame.text2 \
+ -background {white} \
+ -borderwidth {2} \
+ -foreground {black} \
+ -relief {raised} \
+ -wrap {word} \
+ -yscrollcommand {.frame6.frame.scrollbar1 set}
+
+ # pack widget .frame6.frame
+ pack append .frame6.frame \
+ .frame6.frame.scrollbar1 {left frame center filly} \
+ .frame6.frame.text2 {top frame center expand fill}
+
+ # pack widget .frame6
+ pack append .frame6 \
+ .frame6.frame {top frame center fill}
+
+ # pack widget .
+ pack append . \
+ .frame0 {top frame center fillx} \
+ .frame1 {bottom frame center fillx} \
+ .frame6 {top frame center expand fill}
+
+ .frame6.frame.text2 insert end {}
+
+
+
+ if {"[info procs XFEdit]" != ""} {
+ catch "XFMiscBindWidgetTree ."
+ after 2 "catch {XFEditSetShowWindows}"
+ }
+}
+
+
+# Procedure: Alias
+if {"[info procs Alias]" == ""} {
+proc Alias { args} {
+# xf ignore me 7
+##########
+# Procedure: Alias
+# Description: establish an alias for a procedure
+# Arguments: args - no argument means that a list of all aliases
+# is returned. Otherwise the first parameter is
+# the alias name, and the second parameter is
+# the procedure that is aliased.
+# Returns: nothing, the command that is bound to the alias or a
+# list of all aliases - command pairs.
+# Sideeffects: internalAliasList is updated, and the alias
+# proc is inserted
+##########
+ global internalAliasList
+
+ if {[llength $args] == 0} {
+ return $internalAliasList
+ } {
+ if {[llength $args] == 1} {
+ set xfTmpIndex [lsearch $internalAliasList "[lindex $args 0] *"]
+ if {$xfTmpIndex != -1} {
+ return [lindex [lindex $internalAliasList $xfTmpIndex] 1]
+ }
+ } {
+ if {[llength $args] == 2} {
+ eval "proc [lindex $args 0] {args} {#xf ignore me 4
+return \[eval \"[lindex $args 1] \$args\"\]}"
+ set xfTmpIndex [lsearch $internalAliasList "[lindex $args 0] *"]
+ if {$xfTmpIndex != -1} {
+ set internalAliasList [lreplace $internalAliasList $xfTmpIndex $xfTmpIndex "[lindex $args 0] [lindex $args 1]"]
+ } {
+ lappend internalAliasList "[lindex $args 0] [lindex $args 1]"
+ }
+ } {
+ error "Alias: wrong number or args: $args"
+ }
+ }
+ }
+}
+}
+
+
+# Procedure: GetSelection
+if {"[info procs GetSelection]" == ""} {
+proc GetSelection {} {
+# xf ignore me 7
+##########
+# Procedure: GetSelection
+# Description: get current selection
+# Arguments: none
+# Returns: none
+# Sideeffects: none
+##########
+
+ # the save way
+ set xfSelection ""
+ catch "selection get" xfSelection
+ if {"$xfSelection" == "selection doesn't exist or form \"STRING\" not defined"} {
+ return ""
+ } {
+ return $xfSelection
+ }
+}
+}
+
+
+# Procedure: MenuPopupAdd
+if {"[info procs MenuPopupAdd]" == ""} {
+proc MenuPopupAdd { xfW xfButton xfMenu {xfModifier ""} {xfCanvasTag ""}} {
+# xf ignore me 7
+# the popup menu handling is from (I already gave up with popup handling :-):
+#
+# Copyright 1991,1992 by James Noble.
+# Everyone is granted permission to copy, modify and redistribute.
+# This notice must be preserved on all copies or derivates.
+#
+##########
+# Procedure: MenuPopupAdd
+# Description: attach a popup menu to widget
+# Arguments: xfW - the widget
+# xfButton - the button we use
+# xfMenu - the menu to attach
+# {xfModifier} - a optional modifier
+# {xfCanvasTag} - a canvas tagOrId
+# Returns: none
+# Sideeffects: none
+##########
+ global tk_popupPriv
+
+ set tk_popupPriv($xfMenu,focus) ""
+ set tk_popupPriv($xfMenu,grab) ""
+ if {"$xfModifier" != ""} {
+ set press "$xfModifier-"
+ set motion "$xfModifier-"
+ set release "Any-"
+ } {
+ set press ""
+ set motion ""
+ set release ""
+ }
+
+ bind $xfMenu "<${motion}B${xfButton}-Motion>" "MenuPopupMotion $xfMenu %W %X %Y"
+ bind $xfMenu "<${release}ButtonRelease-${xfButton}>" "MenuPopupRelease $xfMenu %W"
+ if {"$xfCanvasTag" == ""} {
+ bind $xfW "<${press}ButtonPress-${xfButton}>" "MenuPopupPost $xfMenu %X %Y"
+ bind $xfW "<${release}ButtonRelease-${xfButton}>" "MenuPopupRelease $xfMenu %W"
+ } {
+ $xfW bind $xfCanvasTag "<${press}ButtonPress-${xfButton}>" "MenuPopupPost $xfMenu %X %Y"
+ $xfW bind $xfCanvasTag "<${release}ButtonRelease-${xfButton}>" "MenuPopupRelease $xfMenu %W"
+ }
+}
+}
+
+
+# Procedure: MenuPopupMotion
+if {"[info procs MenuPopupMotion]" == ""} {
+proc MenuPopupMotion { xfMenu xfW xfX xfY} {
+# xf ignore me 7
+##########
+# Procedure: MenuPopupMotion
+# Description: handle the popup menu motion
+# Arguments: xfMenu - the topmost menu
+# xfW - the menu
+# xfX - the root x coordinate
+# xfY - the root x coordinate
+# Returns: none
+# Sideeffects: none
+##########
+ global tk_popupPriv
+
+ if {"[info commands $xfW]" != "" && [winfo ismapped $xfW] &&
+ "[winfo class $xfW]" == "Menu" &&
+ [info exists tk_popupPriv($xfMenu,focus)] &&
+ "$tk_popupPriv($xfMenu,focus)" != "" &&
+ [info exists tk_popupPriv($xfMenu,grab)] &&
+ "$tk_popupPriv($xfMenu,grab)" != ""} {
+ set xfPopMinX [winfo rootx $xfW]
+ set xfPopMaxX [expr $xfPopMinX+[winfo width $xfW]]
+ if {$xfX >= $xfPopMinX && $xfX <= $xfPopMaxX} {
+ $xfW activate @[expr $xfY-[winfo rooty $xfW]]
+ if {![catch "$xfW entryconfig @[expr $xfY-[winfo rooty $xfW]] -menu" result]} {
+ if {"[lindex $result 4]" != ""} {
+ foreach binding [bind $xfMenu] {
+ bind [lindex $result 4] $binding [bind $xfMenu $binding]
+ }
+ }
+ }
+ } {
+ $xfW activate none
+ }
+ }
+}
+}
+
+
+# Procedure: MenuPopupPost
+if {"[info procs MenuPopupPost]" == ""} {
+proc MenuPopupPost { xfMenu xfX xfY} {
+# xf ignore me 7
+##########
+# Procedure: MenuPopupPost
+# Description: post the popup menu
+# Arguments: xfMenu - the menu
+# xfX - the root x coordinate
+# xfY - the root x coordinate
+# Returns: none
+# Sideeffects: none
+##########
+ global tk_popupPriv
+
+ if {"[info commands $xfMenu]" != ""} {
+ if {![info exists tk_popupPriv($xfMenu,focus)]} {
+ set tk_popupPriv($xfMenu,focus) [focus]
+ } {
+ if {"$tk_popupPriv($xfMenu,focus)" == ""} {
+ set tk_popupPriv($xfMenu,focus) [focus]
+ }
+ }
+ set tk_popupPriv($xfMenu,grab) $xfMenu
+
+ catch "$xfMenu activate none"
+ catch "$xfMenu post $xfX $xfY"
+ catch "focus $xfMenu"
+ catch "grab -global $xfMenu"
+ }
+}
+}
+
+
+# Procedure: MenuPopupRelease
+if {"[info procs MenuPopupRelease]" == ""} {
+proc MenuPopupRelease { xfMenu xfW} {
+# xf ignore me 7
+##########
+# Procedure: MenuPopupRelease
+# Description: remove the popup menu
+# Arguments: xfMenu - the topmost menu widget
+# xfW - the menu widget
+# Returns: none
+# Sideeffects: none
+##########
+ global tk_popupPriv
+ global tkVersion
+
+ if {"[info commands $xfW]" != "" && [winfo ismapped $xfW] &&
+ "[winfo class $xfW]" == "Menu" &&
+ [info exists tk_popupPriv($xfMenu,focus)] &&
+ "$tk_popupPriv($xfMenu,focus)" != "" &&
+ [info exists tk_popupPriv($xfMenu,grab)] &&
+ "$tk_popupPriv($xfMenu,grab)" != ""} {
+ if {$tkVersion >= 3.0} {
+ catch "grab release $tk_popupPriv($xfMenu,grab)"
+ } {
+ catch "grab none"
+ }
+ catch "focus $tk_popupPriv($xfMenu,focus)"
+ set tk_popupPriv($xfMenu,focus) ""
+ set tk_popupPriv($xfMenu,grab) ""
+ if {"[$xfW index active]" != "none"} {
+ $xfW invoke active; catch "$xfMenu unpost"
+ }
+ }
+ catch "$xfMenu unpost"
+}
+}
+
+
+# Procedure: NoFunction
+if {"[info procs NoFunction]" == ""} {
+proc NoFunction { args} {
+# xf ignore me 7
+##########
+# Procedure: NoFunction
+# Description: do nothing (especially with scales and scrollbars)
+# Arguments: args - a number of ignored parameters
+# Returns: none
+# Sideeffects: none
+##########
+}
+}
+
+
+# Procedure: SN
+if {"[info procs SN]" == ""} {
+proc SN { {xfName ""}} {
+# xf ignore me 7
+##########
+# Procedure: SN
+# Description: map a symbolic name to the widget path
+# Arguments: xfName
+# Returns: the symbolic name
+# Sideeffects: none
+##########
+
+ SymbolicName $xfName
+}
+}
+
+
+# Procedure: SymbolicName
+if {"[info procs SymbolicName]" == ""} {
+proc SymbolicName { {xfName ""}} {
+# xf ignore me 7
+##########
+# Procedure: SymbolicName
+# Description: map a symbolic name to the widget path
+# Arguments: xfName
+# Returns: the symbolic name
+# Sideeffects: none
+##########
+
+ global symbolicName
+
+ if {"$xfName" != ""} {
+ set xfArrayName ""
+ append xfArrayName symbolicName ( $xfName )
+ if {![catch "set \"$xfArrayName\"" xfValue]} {
+ return $xfValue
+ } {
+ if {"[info commands XFProcError]" != ""} {
+ XFProcError "Unknown symbolic name:\n$xfName"
+ } {
+ puts stderr "XF error: unknown symbolic name:\n$xfName"
+ }
+ }
+ }
+ return ""
+}
+}
+
+
+# Procedure: Unalias
+if {"[info procs Unalias]" == ""} {
+proc Unalias { aliasName} {
+# xf ignore me 7
+##########
+# Procedure: Unalias
+# Description: remove an alias for a procedure
+# Arguments: aliasName - the alias name to remove
+# Returns: none
+# Sideeffects: internalAliasList is updated, and the alias
+# proc is removed
+##########
+ global internalAliasList
+
+ set xfIndex [lsearch $internalAliasList "$aliasName *"]
+ if {$xfIndex != -1} {
+ rename $aliasName ""
+ set internalAliasList [lreplace $internalAliasList $xfIndex $xfIndex]
+ }
+}
+}
+
+
+# Procedure: getbase
+proc getbase {} {
+ global env
+ global testbase
+ if [info exists env(TESTBASE)] then {
+ set testbase $env(TESTBASE)
+ } else {
+ set testbase /lisa/test/rob
+ }
+ return $testbase
+}
+
+
+# Procedure: getresult
+proc getresult { name} {
+set tmp "[lsort [glob -nocomplain $name-results-??????-????]]"
+set tmp [lindex $tmp [expr [llength $tmp] - 1]]
+if [string match "" $tmp] then {
+ .frame6.frame.text2 delete 0.0 end
+ .frame6.frame.text2 insert 0.0 "Couldn't find results for: $name\n"
+ return
+} else {
+ return [loadfile $tmp]
+}
+}
+
+# Procedure: dialogbox
+proc dialogbox {} {
+ set w .frame6.top2
+ catch {destroy $w}
+ catch {destroy $w.e1}
+ toplevel $w
+# dpos $w
+ wm title $w "Change Editor"
+ wm iconname $w "Entries"
+ message $w.msg -font -Adobe-times-medium-r-normal--*-180* -aspect 200 \
+ -text "Hey Now. Click the \"OK\" button when you've seen enough."
+ frame $w.frame -borderwidth 10
+ button $w.ok -text OK -command "destroy $w"
+ pack $w.msg $w.frame $w.ok -side top -fill both
+
+ entry $w.frame.e1 -relief sunken -textvariable editor
+ pack $w.frame.e1 -side top -pady 5 -fill x
+ bind $w.frame.e1 <Return> "destroy $w"
+}
+
+# Procedure: loadfile
+proc loadfile { name} {
+if ![file exists $name] then {
+ .frame6.frame.text2 delete 0.0 end
+ .frame6.frame.text2 insert 0.0 "Couldn't find:\t$name\n"
+ return
+}
+
+global editor
+if [info exists editor] then {
+ if ![string match "" $editor] then {
+ catch "exec $editor $name&" tmp
+ if [info exists tmp] then {
+ .frame6.frame.text2 delete 0.0 end
+ .frame6.frame.text2 insert 0.0 "Editor returned $tmp\n"
+ }
+ }
+}
+.frame6.frame.text2 delete 0.0 end
+set fd [open $name r]
+while { [gets $fd line]>=0 } {
+.frame6.frame.text2 insert end "$line\n"
+.frame6.frame.text2 mark set insert 0.0
+}
+close $fd
+unset fd
+}
+
+
+
+# application parsing procedure
+proc XFLocalParseAppDefs {xfAppDefFile} {
+ global xfAppDefaults
+
+ # basically from: Michael Moore
+ if {[file exists $xfAppDefFile] &&
+ [file readable $xfAppDefFile] &&
+ "[file type $xfAppDefFile]" == "link"} {
+ catch "file type $xfAppDefFile" xfType
+ while {"$xfType" == "link"} {
+ if {[catch "file readlink $xfAppDefFile" xfAppDefFile]} {
+ return
+ }
+ catch "file type $xfAppDefFile" xfType
+ }
+ }
+ if {!("$xfAppDefFile" != "" &&
+ [file exists $xfAppDefFile] &&
+ [file readable $xfAppDefFile] &&
+ "[file type $xfAppDefFile]" == "file")} {
+ return
+ }
+ if {![catch "open $xfAppDefFile r" xfResult]} {
+ set xfAppFileContents [read $xfResult]
+ close $xfResult
+ foreach line [split $xfAppFileContents "\n"] {
+ # backup indicates how far to backup. It applies to the
+ # situation where a resource name ends in . and when it
+ # ends in *. In the second case you want to keep the *
+ # in the widget name for pattern matching, but you want
+ # to get rid of the . if it is the end of the name.
+ set backup -2
+ set line [string trim $line]
+ if {[string index $line 0] == "#" || "$line" == ""} {
+ # skip comments and empty lines
+ continue
+ }
+ set list [split $line ":"]
+ set resource [string trim [lindex $list 0]]
+ set i [string last "." $resource]
+ set j [string last "*" $resource]
+ if {$j > $i} {
+ set i $j
+ set backup -1
+ }
+ incr i
+ set name [string range $resource $i end]
+ incr i $backup
+ set widname [string range $resource 0 $i]
+ set value [string trim [lindex $list 1]]
+ if {"$widname" != "" && "$widname" != "*"} {
+ # insert the widget and resourcename to the application
+ # defaults list.
+ if {![info exists xfAppDefaults]} {
+ set xfAppDefaults ""
+ }
+ lappend xfAppDefaults [list $widname [string tolower $name] $value]
+ }
+ }
+ }
+}
+
+# application loading procedure
+proc XFLocalLoadAppDefs {{xfClasses ""} {xfPriority "startupFile"} {xfAppDefFile ""}} {
+ global env
+
+ if {"$xfAppDefFile" == ""} {
+ set xfFileList ""
+ if {[info exists env(XUSERFILESEARCHPATH)]} {
+ append xfFileList [split $env(XUSERFILESEARCHPATH) :]
+ }
+ if {[info exists env(XAPPLRESDIR)]} {
+ append xfFileList [split $env(XAPPLRESDIR) :]
+ }
+ if {[info exists env(XFILESEARCHPATH)]} {
+ append xfFileList [split $env(XFILESEARCHPATH) :]
+ }
+ append xfFileList " /usr/lib/X11/app-defaults"
+ append xfFileList " /usr/X11/lib/X11/app-defaults"
+
+ foreach xfCounter1 $xfClasses {
+ foreach xfCounter2 $xfFileList {
+ set xfPathName $xfCounter2
+ if {[regsub -all "%N" "$xfPathName" "$xfCounter1" xfResult]} {
+ set xfPathName $xfResult
+ }
+ if {[regsub -all "%T" "$xfPathName" "app-defaults" xfResult]} {
+ set xfPathName $xfResult
+ }
+ if {[regsub -all "%S" "$xfPathName" "" xfResult]} {
+ set xfPathName $xfResult
+ }
+ if {[regsub -all "%C" "$xfPathName" "" xfResult]} {
+ set xfPathName $xfResult
+ }
+ if {[file exists $xfPathName] &&
+ [file readable $xfPathName] &&
+ ("[file type $xfPathName]" == "file" ||
+ "[file type $xfPathName]" == "link")} {
+ catch "option readfile $xfPathName $xfPriority"
+ if {"[info commands XFParseAppDefs]" != ""} {
+ XFParseAppDefs $xfPathName
+ } {
+ if {"[info commands XFLocalParseAppDefs]" != ""} {
+ XFLocalParseAppDefs $xfPathName
+ }
+ }
+ } {
+ if {[file exists $xfCounter2/$xfCounter1] &&
+ [file readable $xfCounter2/$xfCounter1] &&
+ ("[file type $xfCounter2/$xfCounter1]" == "file" ||
+ "[file type $xfCounter2/$xfCounter1]" == "link")} {
+ catch "option readfile $xfCounter2/$xfCounter1 $xfPriority"
+ if {"[info commands XFParseAppDefs]" != ""} {
+ XFParseAppDefs $xfCounter2/$xfCounter1
+ } {
+ if {"[info commands XFLocalParseAppDefs]" != ""} {
+ XFLocalParseAppDefs $xfCounter2/$xfCounter1
+ }
+ }
+ }
+ }
+ }
+ }
+ } {
+ # load a specific application defaults file
+ if {[file exists $xfAppDefFile] &&
+ [file readable $xfAppDefFile] &&
+ ("[file type $xfAppDefFile]" == "file" ||
+ "[file type $xfAppDefFile]" == "link")} {
+ catch "option readfile $xfAppDefFile $xfPriority"
+ if {"[info commands XFParseAppDefs]" != ""} {
+ XFParseAppDefs $xfAppDefFile
+ } {
+ if {"[info commands XFLocalParseAppDefs]" != ""} {
+ XFLocalParseAppDefs $xfAppDefFile
+ }
+ }
+ }
+ }
+}
+
+# application setting procedure
+proc XFLocalSetAppDefs {{xfWidgetPath "."}} {
+ global xfAppDefaults
+
+ if {![info exists xfAppDefaults]} {
+ return
+ }
+ foreach xfCounter $xfAppDefaults {
+ if {"$xfCounter" == ""} {
+ break
+ }
+ set widname [lindex $xfCounter 0]
+ if {[string match $widname ${xfWidgetPath}] ||
+ [string match "${xfWidgetPath}*" $widname]} {
+ set name [string tolower [lindex $xfCounter 1]]
+ set value [lindex $xfCounter 2]
+ # Now lets see how many tcl commands match the name
+ # pattern specified.
+ set widlist [info command $widname]
+ if {"$widlist" != ""} {
+ foreach widget $widlist {
+ # make sure this command is a widget.
+ if {![catch "winfo id $widget"] &&
+ [string match "${xfWidgetPath}*" $widget]} {
+ catch "$widget configure -$name $value"
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+# startup source
+proc StartupSrc {args} {
+global testbase
+global hostlist
+global targlist
+global host
+
+set host [exec config.guess]
+set target $host
+}
+
+
+# end source
+proc EndSrc {} {
+.frame6.frame.text2 delete 0.0 end
+}
+
+# startup source
+StartupSrc
+
+# initialize global variables
+global {editor}
+set {editor} {}
+global {fsBox}
+set {fsBox(activeBackground)} {}
+set {fsBox(activeForeground)} {}
+set {fsBox(all)} {0}
+set {fsBox(background)} {}
+set {fsBox(button)} {0}
+set {fsBox(extensions)} {0}
+set {fsBox(font)} {}
+set {fsBox(foreground)} {}
+set {fsBox(internalPath)} {/offsite/rob/DejaGnu/devo/dejagnu}
+set {fsBox(name)} {}
+set {fsBox(path)} {/offsite/rob/DejaGnu/devo/dejagnu}
+set {fsBox(pattern)} {*}
+set {fsBox(scrollActiveForeground)} {}
+set {fsBox(scrollBackground)} {}
+set {fsBox(scrollForeground)} {}
+set {fsBox(scrollSide)} {left}
+set {fsBox(showPixmap)} {0}
+global {host}
+set {host} {sparc-sun-sunos4.1.3}
+global {result}
+set {result} {can't read "editor": no such variable}
+global {target}
+set {target} {sparc-sun-sunos4.1.3}
+global {testbase}
+set {testbase} {/lisa/test/rob}
+
+# please don't modify the following
+# variables. They are needed by xf.
+global {autoLoadList}
+set {autoLoadList(testit)} {0}
+global {internalAliasList}
+set {internalAliasList} {}
+global {moduleList}
+set {moduleList(testit)} {}
+global {preloadList}
+set {preloadList(xfInternal)} {}
+global {symbolicName}
+set {symbolicName(binutils)} {.frame0.menubutton7}
+set {symbolicName(dialogbox)} {.top2}
+set {symbolicName(editor)} {.top2.entry4}
+set {symbolicName(g++)} {.frame0.menubutton4}
+set {symbolicName(gas)} {.frame0.menubutton6}
+set {symbolicName(gdb)} {.frame0.menubutton5}
+set {symbolicName(host)} {.frame0.menubutton3.m}
+set {symbolicName(hostlist)} {.frame0.menubutton3}
+set {symbolicName(logs)} {.frame0.menubutton10}
+set {symbolicName(misc)} {.frame0.menubutton1}
+set {symbolicName(ok)} {.top2.button7}
+set {symbolicName(results)} {.frame0.menubutton9}
+set {symbolicName(root)} {.}
+set {symbolicName(sum)} {.frame0.menubutton0}
+set {symbolicName(targlist)} {.frame0.menubutton2}
+global {xfWmSetPosition}
+set {xfWmSetPosition} {}
+global {xfWmSetSize}
+set {xfWmSetSize} {}
+global {xfAppDefToplevels}
+set {xfAppDefToplevels} {}
+
+# display/remove toplevel windows.
+ShowWindow.
+
+# load default bindings.
+if {[info exists env(XF_BIND_FILE)] &&
+ "[info procs XFShowHelp]" == ""} {
+ source $env(XF_BIND_FILE)
+}
+
+# parse and apply application defaults.
+XFLocalLoadAppDefs Testit
+XFLocalSetAppDefs
+
+# end source
+EndSrc
+
+# eof
+#
+
diff --git a/dejagnu/doc/.cvsignore b/dejagnu/doc/.cvsignore
new file mode 100644
index 00000000000..7abff1dbead
--- /dev/null
+++ b/dejagnu/doc/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+config.status
diff --git a/dejagnu/doc/Makefile.am b/dejagnu/doc/Makefile.am
new file mode 100644
index 00000000000..9521a405147
--- /dev/null
+++ b/dejagnu/doc/Makefile.am
@@ -0,0 +1,47 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+info_TEXINFOS = dejagnu.texi
+
+TARGETS = overview.rtf overview.html overview.dvi overview.ps
+
+docs: $(TARGETS)
+
+%.ps: %.dvi
+ dvips -o $@ $<
+
+%.pdf: %.sgml
+ db2pdf $<
+
+%.dvi: %.sgml
+ db2dvi $<
+
+%.rtf: %.sgml
+ db2rtf -o $@ $<
+
+%.gif: %.fig
+ convert -transparency white $< $@ # .fig -> .gif
+
+%.epsi: %.eps
+ ps2epsi $< # .eps -> .epsi
+
+%.eps: %.fig
+ fig2dev -L ps -m 0.7 -p dummy $< > $@ # .fig -> .eps/portrait
+
+%.html: %.sgml
+ db2html $<
+
+# now for some extra dependencies that the automatic rules will not
+# catch:
+
+overview.pdf overview.ps overview.dvi overview.rtf overview.html: overview.sgml ref.sgml user.sgml
+
+clean:
+ rm -f $(TARGETS)
+
+# install-data-local: overview.pdf overview.html
+# $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/html
+# $(INSTALL_DATA) overview/*.html $(DESTDIR)$(pkgdatadir)/html
+# $(INSTALL_DATA) overview.ps $(DESTDIR)$(pkgdatadir)/dejagnu.ps
+# $(INSTALL_DATA) overview.pdf $(DESTDIR)$(pkgdatadir)/dejagnu.pdf
diff --git a/dejagnu/doc/Makefile.in b/dejagnu/doc/Makefile.in
new file mode 100644
index 00000000000..d00ec6c3a7c
--- /dev/null
+++ b/dejagnu/doc/Makefile.in
@@ -0,0 +1,338 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 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.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+BOARDS = @BOARDS@
+CC = @CC@
+CONFIG = @CONFIG@
+EXEEXT = @EXEEXT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+AUTOMAKE_OPTIONS = cygnus
+
+info_TEXINFOS = dejagnu.texi
+
+TARGETS = overview.rtf overview.html overview.dvi overview.ps
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_CLEAN_FILES =
+TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then echo $(top_srcdir)/../texinfo/util/texi2dvi; else echo texi2dvi; fi`
+TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex
+INFO_DEPS = dejagnu.info
+DVIS = dejagnu.dvi
+TEXINFOS = dejagnu.texi
+DIST_COMMON = README Makefile.am Makefile.in configure configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .dvi .info .ps .texi .texinfo .txi
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus doc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+dejagnu.info: dejagnu.texi
+dejagnu.dvi: dejagnu.texi
+
+
+DVIPS = dvips
+
+.texi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.txi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
+ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
+ done; \
+ else : ; fi
+
+uninstall-info:
+ $(PRE_UNINSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ test -z "$ii" \
+ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ done
+ @$(NORMAL_UNINSTALL)
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -f dejagnu.aux dejagnu.cp dejagnu.cps dejagnu.dvi dejagnu.fn \
+ dejagnu.fns dejagnu.ky dejagnu.kys dejagnu.ps dejagnu.log \
+ dejagnu.pg dejagnu.toc dejagnu.tp dejagnu.tps dejagnu.vr \
+ dejagnu.vrs dejagnu.op dejagnu.tr dejagnu.cv dejagnu.cn
+
+clean-aminfo:
+
+distclean-aminfo:
+
+maintainer-clean-aminfo:
+ for i in $(INFO_DEPS); do \
+ rm -f $$i; \
+ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
+ rm -f $$i-[0-9]*; \
+ fi; \
+ done
+clean-info: mostlyclean-aminfo
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = doc
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+info-am: $(INFO_DEPS)
+info: info-am
+dvi-am: $(DVIS)
+dvi: dvi-am
+check-am:
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-info-am:
+install-info: install-info-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-aminfo clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-aminfo distclean-generic clean-am
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-aminfo maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: install-info-am uninstall-info mostlyclean-aminfo \
+distclean-aminfo clean-aminfo maintainer-clean-aminfo tags distdir \
+info-am info dvi-am dvi check check-am installcheck-am installcheck \
+install-info-am install-info install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+docs: $(TARGETS)
+
+%.ps: %.dvi
+ dvips -o $@ $<
+
+%.pdf: %.sgml
+ db2pdf $<
+
+%.dvi: %.sgml
+ db2dvi $<
+
+%.rtf: %.sgml
+ db2rtf -o $@ $<
+
+%.gif: %.fig
+ convert -transparency white $< $@ # .fig -> .gif
+
+%.epsi: %.eps
+ ps2epsi $< # .eps -> .epsi
+
+%.eps: %.fig
+ fig2dev -L ps -m 0.7 -p dummy $< > $@ # .fig -> .eps/portrait
+
+%.html: %.sgml
+ db2html $<
+
+# now for some extra dependencies that the automatic rules will not
+# catch:
+
+overview.pdf overview.ps overview.dvi overview.rtf overview.html: overview.sgml ref.sgml user.sgml
+
+clean:
+ rm -f $(TARGETS)
+
+# install-data-local: overview.pdf overview.html
+# $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/html
+# $(INSTALL_DATA) overview/*.html $(DESTDIR)$(pkgdatadir)/html
+# $(INSTALL_DATA) overview.ps $(DESTDIR)$(pkgdatadir)/dejagnu.ps
+# $(INSTALL_DATA) overview.pdf $(DESTDIR)$(pkgdatadir)/dejagnu.pdf
+
+# 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/dejagnu/doc/README b/dejagnu/doc/README
new file mode 100644
index 00000000000..fc8ae45b91e
--- /dev/null
+++ b/dejagnu/doc/README
@@ -0,0 +1,2 @@
+One can obtain the Free DocBook Tools for Linux and NT at
+http://nis-www.lanl.gov/~rosalia/mydocs/docbook-intro.html
diff --git a/dejagnu/doc/configure b/dejagnu/doc/configure
new file mode 100755
index 00000000000..638b3bf40a3
--- /dev/null
+++ b/dejagnu/doc/configure
@@ -0,0 +1,860 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=dejagnu.texi
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# 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"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:554: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/dejagnu/doc/configure.in b/dejagnu/doc/configure.in
new file mode 100644
index 00000000000..2575d44bbfc
--- /dev/null
+++ b/dejagnu/doc/configure.in
@@ -0,0 +1,5 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.5)
+AC_INIT(dejagnu.texi)
+AC_PROG_INSTALL
+AC_OUTPUT(Makefile)
diff --git a/dejagnu/doc/dejagnu.texi b/dejagnu/doc/dejagnu.texi
new file mode 100644
index 00000000000..68c4008ed37
--- /dev/null
+++ b/dejagnu/doc/dejagnu.texi
@@ -0,0 +1,3572 @@
+o\input texinfo @c -*- Texinfo -*-
+@finalout
+@setfilename dejagnu.info
+@c
+@c This file documents the GNU Testing Framework ``DejaGnu''
+@c
+@c Copyright (C) 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+@c
+@c This text may be freely distributed under the terms of the GNU
+@c General Public License.
+@c
+
+@c FIXME---MAIN TODO LIST!
+@c
+@c * Revisit organization.
+@c
+@c * discuss Tcl/expect basics---enough to get started (see seminar notes).
+@c Maybe this would permit abbreviating appendices.
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* DejaGnu: (dejagnu). The GNU testing framework.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@syncodeindex ky cp
+@syncodeindex fn cp
+
+@setchapternewpage odd
+@settitle DejaGnu Testing Framework
+@titlepage
+@title The DejaGnu Testing Framework
+@subtitle for DejaGnu Version 1.3
+@sp 1
+@subtitle Jan 1996
+@author Rob Savoye
+@page
+
+@tex
+{\parskip=0pt \hfill Cygnus Support}
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@noindent
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end titlepage
+
+@ifinfo
+Copyright @copyright{} 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries a copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+
+@node Top
+@top DejaGnu
+
+DejaGnu is a framework for running test suites on software tools.
+
+This file describes version 1.3 of DejaGnu.
+
+@menu
+* Overview:: What is DejaGnu?
+* What is New:: What is new in this release.
+* Invoking runtest:: Using `runtest', the main test driver
+* Customizing:: Setting `runtest' defaults
+* Internals:: The DejaGnu implementation
+* Tests:: How to write a test case
+* Extending:: New tools, new targets, and new hosts
+* Installation:: Configuring and Installing DejaGnu
+* Index:: Index
+@end menu
+@end ifinfo
+
+@iftex
+@raggedbottom
+@end iftex
+
+@node Overview
+@chapter What is DejaGnu?
+@cindex overview
+
+DejaGnu is a framework for testing other programs. Its purpose is to
+provide a single front end for all tests. Beyond this, DejaGnu offers
+several advantages for testing:
+
+@enumerate
+@item
+The flexibility and consistency of the DejaGnu framework make it easy
+to write tests for any program.
+
+@item
+DejaGnu provides a layer of abstraction which allows you to write tests
+that are portable to any host or target where a program must be tested.
+ For instance, a test for GDB can run (from any Unix based host) on any
+target architecture that DejaGnu supports. Currently DejaGnu runs tests
+on several single board computers, whose operating software ranges from
+just a boot monitor to a full-fledged, Unix-like realtime OS.
+
+@item
+All tests have the same output format. This makes it easy to integrate
+testing into other software development processes. DejaGnu's output is
+designed to be parsed by other filtering script, and it is also human
+readable.
+@end enumerate
+
+DejaGnu is written in @code{expect}, which in turn uses @dfn{Tcl}---Tool
+command language.
+
+@cindex @code{expect} script names
+@kindex .exp
+@cindex suffix, @code{expect} scripts
+Running tests requires two things: the testing framework, and the test
+suites themselves. Tests are usually written in @code{expect} using
+Tcl, but you can also use a Tcl script to run a test suite that is not
+based on @code{expect}. (@code{expect} script filenames conventionally
+use @samp{.exp} as a suffix; for example, the main implementation of the
+DejaGnu test driver is in the file @file{runtest.exp}.)
+
+
+@menu
+* Running Tests:: A first look at running DejaGnu tests
+* Sample Test:: What does a DejaGnu test case look like?
+* Design Goals:: Goals behind DejaGnu
+* Posix:: DejaGnu conforms to POSIX 1003.3
+* Future Directions:: Where is DejaGnu going?
+* Tcl and Expect:: Reading more about Tcl and Expect
+@end menu
+
+@node What is New
+@chapter What is new in this release ?
+@cindex What is New
+
+This release has a number of substantial changes over version 1.2. The
+most visible change is that the version of expect and Tcl included in
+the release are up-to-date with the current stable net releases. Other
+changes are:
+
+@enumerate
+@item
+@c FIXME: add a link to the config section
+The config sub-system in DejaGnu has been completely redesigned. It now
+supports testing on remote hosts as well as remote targets.
+
+@item
+More builtin support for building target binaries with the correct
+linker flags. Currently this only works with GCC, preferably with a
+target support by @code{libgloss}.
+
+@item
+Lots of little bug fixes from a year of heavy use here at Cygnus
+Support.
+
+@item
+DejaGnu now uses @code{autoconf} for configuration.
+
+@item
+New test cases for DejaGnu have been added for the new features, plus
+the "--tool" option bug in the 1.2 testsuite has been fixed.
+
+@item
+The @code{--tool} option is now optional.
+
+@item
+@code{runtest} when searching for test drivers ignores all directories
+named SCCS, RCS, and CVS.
+
+@item
+There is now a generic keyword based test harness that uses comments in
+source code to control how each test case gets built and run.
+
+@item
+There is now some support for running a testsuite with multiple passes
+and multiple targets.
+
+@end enumerate
+
+@node Running Tests
+@section Running existing tests
+@cindex existing tests, running
+@cindex running tests
+@cindex tests, running
+
+@kindex make check
+To run tests from an existing collection, first use @code{configure} as
+usual to set up the source directory containing the tests. Then try
+running
+
+@example
+make check
+@end example
+
+@cindex @code{check} makefile target
+If the @code{check} target exists, it usually saves you some
+trouble---for instance, it can set up any auxiliary programs or other
+files needed by the tests.
+
+@cindex auxiliary files, building
+Once you have run @samp{make check} to build any auxiliary files, you
+might want to call the test driver @code{runtest} directly to repeat the
+tests. You may also have to call @code{runtest} directly for test
+collections with no @code{check} target in the @file{Makefile}.
+
+@c force page break to avoid losing footnote to another page
+@page
+@cindex @code{runtest}, most common options
+@cindex options for @code{runtest}, common
+Typically, you must use two command-line options: @samp{--tool}, to
+specify which set of tests to run@footnote{@samp{--tool} selects a
+particular suite of tests, @emph{not} the name of the executable program
+to run. @xref{Config Values,,Configuration dependent values}, for
+information on the variables that you can use to specify the names of
+programs to run.}, and @samp{--srcdir}, to specify where to find test
+directories.
+
+For example, if the directory @file{gdb/testsuite} contains a collection
+of DejaGnu tests for @sc{gdb}, you can run them like this:
+
+@example
+eg$ cd gdb/testsuite
+eg$ runtest --tool gdb
+@exdent @emph{Test output follows, ending with:}
+
+ === gdb Summary ===
+
+# of expected passes 508
+# of expected failures 103
+/usr/latest/bin/gdb version 4.14.4 -nx
+@end example
+
+You can use the option @samp{--srcdir} to point to some other directory
+containing a collection of tests:
+
+@smallexample
+eg$ runtest --tool gdb --srcdir /devo/gdb/testsuite
+@end smallexample
+
+@cindex native configuration
+@cindex cross configuration
+These examples assume a @dfn{native} configuration, where the same
+computer runs both @code{runtest} and the tests themselves. When you
+have a @dfn{cross} configuration, the tests run on a different computer,
+controlled by the host running @code{runtest}. In this situation, you
+need the option @samp{--name} to specify the network address for the
+other computer:
+
+@smallexample
+eg$ runtest --tool gdb --name vx9.munist.com
+@end smallexample
+
+If you always use the same option values, you can record them in a file
+called @file{site.exp}, rather than typing them each time. @xref{Config
+Values,,Setting defaults for @code{runtest} options}.
+
+By default, @code{runtest} prints only the names of the tests it runs,
+output from any tests that have unexpected results, and a summary
+showing how many tests passed and how many failed. To display output
+from all tests (whether or not they behave as expected), use the
+@samp{--all} option. For more verbose output about processes being run,
+communication, and so on, use @samp{--verbose}. To see even more output,
+use multiple @samp{--verbose} options. @xref{Invoking runtest,,Using
+@code{runtest}}, for a more detailed explanation of each @code{runtest}
+option.
+
+Test output goes into two files in your current directory: summary
+output in @file{@var{tool}.sum}, and detailed output in
+@file{@var{tool}.log}. (@var{tool} refers to the collection of tests;
+for example, after a run with @samp{--tool gdb}, look for output files
+@file{gdb.sum} and @file{gdb.log}.) @xref{Output Files,,The files
+DejaGnu writes}.
+
+@node Sample Test
+@section What does a DejaGnu test look like?
+
+@cindex example
+Each DejaGnu test is an @code{expect} script; the tests vary widely in
+complexity, depending on the nature of the tool and the feature tested.
+
+@kindex gdb.t00/echo.exp
+@kindex echo.exp
+Here is a very simple @sc{gdb} test---one of the simplest tests shipped
+with DejaGnu (extracted from @file{gdb.t00/echo.exp}):@footnote{More
+recent @sc{gdb} tests use the @samp{gdb_test} procedure.
+An equivalent test using that procedure is @samp{ gdb_test "echo Hello
+world!" "Hello world!" }}
+@c FIXME! include xref in footnote, when gdb_test documented in some manual.
+@c @xref{}.
+@c Extra spaces in @samp above avoid running end ' against " inside.
+
+@cartouche
+@smallexample
+# send a string to the GDB stdin:
+send "echo Hello world!\n"
+
+# inspect the GDB stdout for the correct reply,
+# and determine whether the test passes or fails:
+expect @{
+ -re "Hello world.*$prompt $" @{ pass "Echo test" @}
+ -re "$prompt $" @{ fail "Echo test" @}
+ timeout @{ fail "(timeout) Echo test" @}
+ @}
+@end smallexample
+@end cartouche
+
+Though brief, this example is a complete test. It illustrates some of
+the main features of DejaGnu test scripts:
+
+@itemize @bullet
+@item
+The test case does not start the tested program (@sc{gdb} in this case);
+all test scripts for interactive tools can assume the corresponding tool
+is running.
+
+@item
+Comments start with @samp{#}.
+
+@item
+The main commands you use to control a tested program are @code{send}
+(to give it commands) and @code{expect} (to analyze its responses).
+
+@item
+The @code{expect} command uses a list of pairs; a pattern (regular
+expression if @samp{-re} specified), followed by an action to run if the
+pattern matches output from the program. Only the action for the
+@emph{first} matching pattern will execute.
+
+@item
+Test cases use the commands @code{pass} and @code{fail} to record the
+test outcome.
+@end itemize
+
+@node Design Goals
+@section Design goals
+@cindex design goals
+
+DejaGnu grew out of the internal needs of Cygnus Support. Cygnus
+maintains and enhances a variety of free programs in many different
+environments, and we needed a testing tool that:
+
+@itemize @bullet
+@item
+is useful to developers while fixing bugs;
+
+@item
+automates running many tests during a software release process;
+
+@item
+is portable among a variety of host computers;
+
+@item
+supports cross-development testing;
+
+@item
+permits testing interactive programs, like @sc{gdb}; and
+
+@item
+permits testing batch oriented programs, like @sc{gcc}.
+@end itemize
+
+Some of the requirements proved challenging. For example, interactive
+programs do not lend themselves very well to automated testing. But all
+the requirements are important: for instance, it is imperative to make
+sure that @sc{gdb} works as well when cross-debugging as it does in a
+native configuration.
+
+Probably the greatest challenge was testing in a cross-development
+environment (which can be a real nightmare). Most cross-development
+environments are customized by each developer. Even when buying
+packaged boards from vendors there are many differences. The
+communication interfaces vary from a serial line to ethernet. DejaGnu
+was designed with a modular communication setup, so that each kind of
+communication can be added as required, and supported thereafter. Once
+a communication procedure is coded, any test can use it. Currently
+DejaGnu can use @code{rsh}, @code{rlogin}, @code{telnet}, @code{tip},
+@code{kermit}, and @code{mondfe} for remote communications.
+
+@cindex name ``DejaGnu''
+@cindex DejaGnu, the name
+@cindex Menapace, Julia
+Julia Menapace first coined the term ``Deja Gnu'' to describe an earlier
+testing framework at Cygnus Support. When we replaced it with the
+Expect-based framework, it was like DejaGnu all over again@dots{}
+
+@node Posix
+@section A POSIX conforming test framework
+
+@cindex POSIX conformance
+@cindex standard conformance: POSIX 1003.3
+DejaGnu conforms to the @sc{posix} standard for test frameworks.
+
+@cindex TET
+@sc{posix} standard 1003.3 defines what a testing framework needs to
+provide, in order to permit the creation of @sc{posix} conformance
+test suites. This standard is primarily oriented to running @sc{posix}
+conformance tests, but its requirements also support testing of features
+not related to @sc{posix} conformance. @sc{posix} 1003.3 does not
+specify a particular testing framework, but at this time there is only
+one other @sc{posix} conforming test framework:
+@sc{tet}.@footnote{@sc{tet} was created by Unisoft for a consortium
+comprised of X/Open, Unix International, and the Open Software
+Foundation.}
+
+The @sc{posix} documentation refers to @dfn{assertions}. An assertion
+is a description of behavior. For example, if a standard says ``The sun
+shall shine'', a corresponding assertion might be ``The sun is
+shining.'' A test based on this assertion would pass or fail depending
+on whether it is daytime or nighttime. It is important to note that the
+standard being tested is never 1003.3; the standard being tested is some
+other standard, for which the assertions were written.
+
+As there is no test suite to test @emph{testing frameworks} for
+@sc{posix} 1003.3 conformance, verifying conformance to this standard is
+done by repeatedly reading the standard and experimenting. One of the
+main things 1003.3 does specify is the set of allowed output messages,
+and their definitions. Four messages are supported for a required
+feature of @sc{posix} conforming systems, and a fifth for a conditional
+feature. DejaGnu supports the use of all five output messages; in this
+sense a test suite that uses exactly these messages can be considered
+@sc{posix} conforming. These definitions specify the output of a test
+case:
+
+@ftable @code
+@cindex success, POSIX definition
+@item PASS
+A test has succeeded. That is, it demonstrated that the assertion is true.
+
+@cindex XFAIL, avoiding for POSIX
+@item XFAIL
+@sc{posix} 1003.3 does not incorporate the notion of expected failures,
+so @code{PASS}, instead of @code{XPASS}, must also be returned for test
+cases which were expected to fail and did not. This means that
+@code{PASS} is in some sense more ambiguous than if @code{XPASS} is also
+used. For information on @code{XPASS} and @code{XFAIL}, see
+@ref{Invoking runtest,,Using @code{runtest}}.
+
+@item FAIL
+@cindex failure, POSIX definition
+A test @emph{has} produced the bug it was intended to capture. That is,
+it has demonstrated that the assertion is false. The @code{FAIL}
+message is based on the test case only. Other messages are used to
+indicate a failure of the framework.
+
+As with @code{PASS}, @sc{posix} tests must return @code{FAIL} rather
+than @code{XFAIL} even if a failure was expected.
+
+@item UNRESOLVED
+@cindex ambiguity, required for POSIX
+A test produced indeterminate results. Usually, this means the test
+executed in an unexpected fashion; this outcome requires that a human
+being go over results, to determine if the test should have passed or
+failed. This message is also used for any test that requires human
+intervention because it is beyond the abilities of the testing
+framework. Any unresolved test should resolved to @code{PASS} or
+@code{FAIL} before a test run can be considered finished.
+
+Note that for @sc{posix}, each assertion must produce a test result
+code. If the test isn't actually run, it must produce @code{UNRESOLVED}
+rather than just leaving that test out of the output. This means that
+you have to be careful when writing tests, to not carelessly use tcl
+statements like @code{return}---if you alter the flow of control of the
+tcl code you must insure that every test still produces some result code.
+
+Here are some of the ways a test may wind up @code{UNRESOLVED}:
+
+@itemize @bullet
+@item
+A test's execution is interrupted.
+
+@item
+A test does not produce a clear result. This is usually because there
+was an @code{ERROR} from DejaGnu while processing the test, or because there
+were three or more @code{WARNING} messages. Any @code{WARNING} or
+@code{ERROR} messages can invalidate the output of the test. This
+usually requires a human being to examine the output to
+determine what really happened---and to improve the test case.
+
+@item
+A test depends on a previous test, which fails.
+
+@item
+The test was set up incorrectly.
+@end itemize
+
+@item UNTESTED
+A test was not run. This is a placeholder, used when there is no
+real test case yet.
+@end ftable
+
+@noindent
+The only remaining output message left is intended to test features that
+are specified by the applicable @sc{posix} standard as conditional:
+
+@ftable @code
+@item UNSUPPORTED
+There is no support for the tested case. This may mean that a
+conditional feature of an operating system, or of a compiler, is not
+implemented. DejaGnu also uses this message when a testing environment
+(often a ``bare board'' target) lacks basic support for compiling or
+running the test case. For example, a test for the system subroutine
+@code{gethostname} would never work on a target board running only a
+boot monitor.
+@end ftable
+
+DejaGnu uses the same output procedures to produce these messages for
+all test suites, and these procedures are already known to conform to
+@sc{posix} 1003.3. For a DejaGnu test suite to conform to @sc{posix}
+1003.3, you must avoid the @code{setup_xfail} procedure as described in
+the @code{PASS} section above, and you must be careful to return
+@code{UNRESOLVED} where appropriate, as described in the
+@code{UNRESOLVED} section above.
+
+@node Future Directions
+@section Future directions
+@cindex future directions
+
+In the near future, there are two parallel directions for DejaGnu
+development. The first is to add support for more hosts and targets.
+
+The second would permit testing programs with a more complex interface,
+whether text based or GUI based. Two components already exist: a Tcl
+based X window toolkit, and a terminal package for @code{expect}. Both
+of these could be merged into DejaGnu in a way that permits testing
+programs that run in each environment.
+
+Meanwhile, we hope DejaGnu enables the creation of test suites for
+conformance to @sc{ansi} C and C++, to @sc{posix}, and to other
+standards. We encourage you to make any test suites you create freely
+available, under the same terms as DejaGnu itself.
+
+@node Tcl and Expect
+@section Tcl and Expect
+@cindex tool command language
+@cindex tcl
+@cindex Ousterhout, John K.
+Tcl was introduced in a paper by John K. Ousterhout at the 1990 Winter
+Usenix conference, @cite{Tcl: An Embeddable Command Language}. That
+paper is included in PostScript form in the @file{doc} subdirectory of
+the Tcl distribution. The version of Tcl included in DejaGnu at this time is
+Tcl 7.4p3.
+
+@cindex @code{expect} scripting language
+@cindex Libes, Don
+Don Libes introduced @code{expect} in his paper @cite{expect: Curing
+Those Uncontrollable Fits of Interaction} at the 1990 Summer Usenix
+conference. The paper is included in PostScript form in the
+@code{expect} distribution (as are several other papers about
+@code{expect}). The version of expect included in DejaGnu at this time
+is expect 5.18.0.
+
+@node Invoking runtest
+@chapter Using @code{runtest}
+@cindex invoking
+@cindex running
+@cindex command line options
+@cindex options
+
+@cindex @code{runtest} description
+@cindex DejaGnu test driver
+@code{runtest} is the executable test driver for DejaGnu. You can
+specify two kinds of things on the @code{runtest} command line: command
+line options, and Tcl variables for the test scripts. The options are
+listed alphabetically below.
+
+@cindex exit code from @code{runtest}
+@cindex @code{runtest} exit code
+@code{runtest} returns an exit code of @code{1} if any test
+has an unexpected result; otherwise (if all tests pass or fail as
+expected) it returns @code{0} as the exit code.
+
+@code{runtest} flags the outcome of each test as one of these cases.
+(@xref{Posix,,A POSIX conforming test framework}, for a discussion of
+how @sc{posix} specifies the meanings of these cases.)
+
+@table @code
+@item PASS
+@kindex PASS
+@cindex successful test
+@cindex test, successful
+The most desirable outcome: the test succeeded, and was expected to
+succeed.
+
+@item XPASS
+@kindex XPASS
+@cindex successful test, unexpected
+@cindex unexpected success
+A pleasant kind of failure: a test was expected to fail, but succeeded.
+This may indicate progress; inspect the test case to determine whether
+you should amend it to stop expecting failure.
+
+@item FAIL
+@kindex FAIL
+@cindex failing test, unexpected
+@cindex test, failing
+A test failed, although it was expected to succeed. This may indicate
+regress; inspect the test case and the failing software to locate the bug.
+
+@item XFAIL
+@kindex XFAIL
+@cindex expected failure
+@cindex failing test, expected
+A test failed, but it was expected to fail. This result indicates no
+change in a known bug. If a test fails because the operating system
+where the test runs lacks some facility required by the test, the
+outcome is @code{UNSUPPORTED} instead.
+
+@item UNRESOLVED
+@kindex UNRESOLVED
+@cindex test, unresolved outcome
+Output from a test requires manual inspection; the test suite could not
+automatically determine the outcome. For example, your tests can report
+this outcome is when a test does not complete as expected.
+
+@item UNTESTED
+@kindex UNTESTED
+@cindex untested properties
+A test case is not yet complete, and in particular cannot yet produce a
+@code{PASS} or @code{FAIL}. You can also use this outcome in dummy
+``tests'' that note explicitly the absence of a real test case
+for a particular property.
+
+@item UNSUPPORTED
+@kindex UNSUPPORTED
+@cindex unsupported test
+@cindex test, unsupported
+A test depends on a conditionally available feature that does not exist
+(in the configured testing environment). For example, you can use this
+outcome to report on a test case that does not work on a particular
+target because its operating system support does not include a required
+subroutine.
+@end table
+
+@code{runtest} may also display the following messages:
+
+@table @code
+@item ERROR
+@kindex ERROR
+@cindex problem, detected by test case
+@cindex test case cannot run
+Indicates a major problem (detected by the test case itself) in running
+the test. This is usually an unrecoverable error, such as a missing file
+or loss of communication to the target. (@sc{posix} test suites should
+not emit this message; use @code{UNSUPPORTED}, @code{UNTESTED}, or
+@code{UNRESOLVED} instead, as appropriate.)
+
+@item WARNING
+@kindex WARNING
+@cindex test case warnings
+Indicates a possible problem in running the test. Usually warnings
+correspond to recoverable errors, or display an important message about
+the following tests.
+
+@item NOTE
+@kindex NOTE
+@cindex test case messages
+An informational message about the test case.
+@end table
+
+This is the full set of command line options that @code{runtest}
+recognizes. Arguments may be abbreviated to the shortest unique string.
+
+@cindex @code{runtest} option list
+@cindex option list, @code{runtest}
+@smallexample
+runtest --tool @var{tool} [ @var{testsuite}.exp @dots{} ]
+[ @var{testsuite}.exp="testfile1 @dots{}" ]
+[ @var{tclvar}=@var{value}@dots{} ]
+[ --all ] [ --baud @var{baud-rate} ] [ --connect @var{type} ]
+[ --debug ] [ --help ] [ --host @var{string} ]
+[ --mail "@var{name} @dots{}" ] [ --name @var{string} ]
+[ --name @var{name} ] [ --outdir @var{path} ]
+[ --objdir @var{path} ] [ --reboot ]
+[ --srcdir @var{path} ] [ --strace @var{n} ]
+[ --target @var{string} --build @var{string} ]
+[ -v | --verbose ] [ -V | --version ] [ --D@var{n} ]
+@end smallexample
+
+@table @code
+@item --tool @var{tool}
+@cindex selecting tests for a tool
+@cindex @code{--tool} (@code{runtest} option)
+@var{tool} specifies what set of tests to run, and what initialization
+module to use. @var{tool} is used @emph{only} for these two purposes:
+it is @emph{not} used to name the executable program to test.
+Executable tool names (and paths) are recorded in @file{site.exp}
+(@pxref{Config Values,,Configuration dependent values}), and you can
+override them by specifying Tcl variables on the command line.
+
+For example, including @samp{--tool gcc} on the @code{runtest} command
+line runs tests from all test subdirectories whose names match
+@file{gcc.*}, and uses one of the initialization modules named
+@file{config/*-gcc.exp}. To specify the name of the compiler (perhaps
+as an alternative path to what @code{runtest} would use by default), use
+@samp{GCC=@var{binname}} on the @code{runtest} command line.
+
+@item @var{testsuite}.exp @dots{}
+@cindex selecting a range of tests
+@cindex tests, running specifically
+@cindex naming tests to run
+Specify the names of testsuites to run.
+By default, @code{runtest} runs all tests for the tool, but you can
+restrict it to particular testsuites by giving the names of the @samp{.exp}
+@code{expect} scripts that control them.
+
+@var{testsuite}.exp may not include path information; use plain filenames.
+
+@item @var{testfile}.exp="testfile1 @dots{}"
+@cindex selecting a range of tests
+@cindex tests, running specifically
+@cindex naming tests to run
+Specify a subset of tests in a suite to run.
+For compiler or assembler tests, which often use a single @samp{.exp}
+script covering many different source files, this option allows you to
+further restrict the tests by listing particular source files to compile.
+Some tools even support wildcards here. The wildcards supported depend
+upon the tool, but typically they are @code{?}, @code{*}, and @code{[chars]}.
+
+@item @var{tclvar}=@var{value}
+@kindex @var{tclvar}=@var{value}
+@cindex Tcl variables, defining for @code{runtest}
+@cindex command line Tcl variable definition
+@cindex @code{runtest}, variable defns on cmdline
+You can define Tcl variables for use by your test scripts in the same
+style used with @code{make} for environment variables. For example,
+@samp{runtest GDB=gdb.old} defines a variable called @samp{GDB}; when
+your scripts refer to @samp{$GDB} in this run, they use the value
+@samp{gdb.old}.
+
+The default Tcl variables used for most tools are defined in the main
+DejaGnu @code{Makefile}; their values are captured in the
+@file{site.exp} file. @xref{Config Values,,Configuration dependent
+values}.
+
+@item --all
+@cindex @code{--all} (@code{runtest} option)
+@cindex test output, displaying all
+Display all test output. By default, @code{runtest} shows only the
+output of tests that produce unexpected results; that is, tests with
+status @samp{FAIL} (unexpected failure), @samp{XPASS} (unexpected
+success), or @samp{ERROR} (a severe error in the test case itself).
+Specify @samp{--all} to see output for tests with status @samp{PASS}
+(success, as expected) @samp{XFAIL} (failure, as expected), or
+@samp{WARNING} (minor error in the test case itself).
+
+@item --baud @var{baud-rate}
+@itemx -b @var{baud-rate}
+@cindex baud rate, specifying
+@cindex bps, specifying
+@cindex @code{--baud} (@code{runtest} option)
+@cindex @code{-b} (@code{runtest} option)
+Set the default baud rate to something other than 9600. (Some serial
+interface programs, like @code{tip}, use a separate initialization file
+instead of this value.)
+
+@item --connect @var{type}
+@cindex connecting to target
+@cindex @code{--connect} (@code{runtest} option)
+@cindex remote testbed, connecting to
+@cindex @code{rlogin}, remote testing via
+@cindex @code{telnet}, remote testing via
+@cindex @code{rsh}, remote testing via
+@cindex @code{tip}, remote testing via
+@cindex @code{kermit}, remote testing via
+@cindex @code{mondfe}, remote testing via
+@cindex remote testing via @code{rlogin}
+@cindex remote testing via @code{telnet}
+@cindex remote testing via @code{rsh}
+@cindex remote testing via @code{tip}
+@cindex remote testing via @code{kermit}
+@cindex remote testing via @code{mondfe}
+Connect to a target testing environment as specified by @var{type}, if
+the target is not the computer running @code{runtest}. For example, use
+@samp{--connect} to change the program used to connect to a ``bare
+board'' boot monitor. The choices for @var{type} in the DejaGnu 1.0
+distribution are @samp{rlogin}, @samp{telnet}, @samp{rsh}, @samp{tip},
+@samp{kermit}, and @samp{mondfe}.
+
+@noindent
+The default for this option depends on the configuration (@pxref{Cross
+Targets,,Remote targets supported}). The default is chosen to be the
+most convenient communication method available, but often other
+alternatives work as well; you may find it useful to try alternative
+connect methods if you suspect a communication problem with your testing
+target.
+
+@item --debug
+@cindex @code{--debug} (@code{runtest} option)
+@cindex debug log for test cases
+@cindex test cases, debug log
+@cindex @code{dbg.log} file
+Turns on the @code{expect} internal debugging output. Debugging output
+is displayed as part of the @code{runtest} output, and logged to a file
+called @file{dbg.log}. The extra debugging output does @emph{not}
+appear on standard output, unless the verbose level is greater than 2
+(for instance, to see debug output immediately, specify @samp{--debug -v
+-v}). The debugging output shows all attempts at matching the test
+output of the tool with the scripted patterns describing expected
+output. The output generated with @samp{--strace} also goes into
+@file{dbg.log}.
+
+@item --help
+@itemx -he
+@cindex @code{--help} (@code{runtest} option)
+@cindex help with @code{runtest}
+@cindex @code{runtest}, listing options
+Prints out a short summary of the @code{runtest} options, then exits
+(even if you also specify other options).
+
+@item --host @var{string}
+@cindex @code{--host} (@code{runtest} option)
+@cindex specifying the host config name
+@cindex host config name, changing
+@var{string} is a full configuration ``triple'' name as used by
+@code{configure}. Use this option to override the default string
+recorded by your configuration's choice of host. This choice does not
+change how anything is actually configured unless --build is also
+specified; it affects @emph{only} DejaGnu procedures that compare the
+host string with particular values. The procedures @code{ishost},
+@code{istarget}, @code{isnative}, and @code{setup_xfail} are affected by
+@samp{--host}. In this usage, @code{host} refers to the machine that the
+tests are to be run on, which may not be the same as the @code{build}
+machine. If @code{--build} is also specified, then @code{--host} refers
+to the machine that the tests wil, be run on, not the machine DejaGnu is
+run on.
+
+@item --build @var{string}
+@cindex @code{--build} (@code{runtest} option)
+@cindex specifying the build config name
+@cindex build config name, changing
+@var{string} is a full configuration ``triple'' name as used by
+@code{configure}. This is the type of machine DejaGnu and the tools to
+be tested are built on. For a normal cross this is the same as the host,
+but for a canadian cross, they are seperate.
+
+@item --name @var{name}
+@cindex specifying target name
+@cindex target machine name
+@cindex @code{--name} (@code{runtest} option)
+@var{name} is a name for the particular testing target machine (for
+cross testing). If the testing target has IP network support (for
+example, @code{RPC} or @code{NFS}), this is the network name for the
+target itself. (@var{name} is @emph{not the configuration string} you
+specify as a target with @code{configure}; the @samp{--name} option
+names a particular target, rather than describing a class of targets.)
+For targets that connect in other ways, the meaning of the @var{name}
+string depends on the connection method. @xref{Cross Targets,,Remote
+targets supported}.
+
+@item --name @var{string}
+@cindex remote test machine name
+@cindex name for remote test machine
+Specify a network name of testing target or its host. The particular
+names that are meaningful with @samp{--name} will depend on your site
+configuration, and on the connection protocol: for example, @code{tip}
+connections require names from a serial line configuration file (usually
+called @file{/etc/remote}), while @code{telnet} connections use IP
+hostnames.
+
+@item --objdir @var{path}
+@cindex @code{--objdir} (@code{runtest} option)
+@cindex object directory
+@cindex test programs, auxiliary
+@cindex auxiliary test programs
+Use @var{path} as the top directory containing any auxiliary compiled
+test code. This defaults to @file{.}. Use this option to locate
+pre-compiled test code. You can normally prepare any auxiliary files
+needed with @code{make}.
+
+@item --outdir @var{path}
+@cindex output directory
+@cindex @code{--outdir} (@code{runtest} option)
+@cindex log files, where to write
+Write output logs in directory @var{path}. The default is @samp{.}, the
+directory where you start @code{runtest}. This option affects only the
+summary and the detailed log files @file{@var{tool}.sum} and
+@file{@var{tool}.log}. The DejaGnu debug log @file{dbg.log} always
+appears (when requested) in the local directory.
+
+@item --reboot
+@cindex rebooting remote targets
+@cindex @code{--reboot} (@code{runtest} option)
+Reboot the target board when @code{runtest} initializes.
+Usually, when running tests on a separate target board, it is safer to
+reboot the target to be certain of its state. However, when developing
+test scripts, rebooting takes a lot of time.
+
+@item --srcdir @var{path}
+@cindex source directory
+@cindex @code{--srcdir} (@code{runtest} option)
+Use @var{path} as the top directory for test scripts to run.
+@code{runtest} looks in this directory for any subdirectory whose name
+begins with the toolname (specified with @samp{--tool}). For instance,
+with @samp{--tool gdb}, @code{runtest} uses tests in subdirectories
+@file{gdb.*} (with the usual shell-like filename expansion). If you do
+not use @samp{--srcdir}, @code{runtest} looks for test directories under
+the current working directory.
+
+@item --strace @var{n}
+@cindex @code{--strace} (@code{runtest} option)
+@cindex tracing Tcl commands
+@cindex @code{expect} internal tracing
+Turn on internal tracing for @code{expect}, to @var{n} levels deep. By
+adjusting the level, you can control the extent to which your output
+expands multi-level Tcl statements. This allows you to ignore some
+levels of @code{case} or @code{if} statements. Each procedure call or
+control structure counts as one ``level''.
+
+The output is recorded in the same file, @file{dbg.log}, used for output
+from @samp{--debug}.
+
+@item --target @var{string}
+@cindex @code{--target} (@code{runtest} option)
+@cindex specifying the target configuration
+@cindex target configuration, specifying
+Use this option to override the default setting (running native tests).
+@var{string} is a full configuration ``triple''
+name@footnote{Configuration triples have the form
+@samp{@var{cpu}-@var{vendor}-@var{os}}.} as used by @code{configure}.
+This option changes the configuration @code{runtest} uses for the
+default tool names, and other setup information. @xref{Using
+configure,,Using @code{configure}, configure.info, Cygnus configure},
+for details about @code{configure} names.
+
+@item --verbose
+@itemx -v
+@cindex @code{--verbose} (@code{runtest} option)
+@cindex @code{-v} (@code{runtest} option)
+@cindex turning on output
+@cindex output, additional
+Turns on more output. Repeating this option increases the amount of
+output displayed. Level one (@samp{-v}) is simply test output. Level
+two (@samp{-v -v}) shows messages on options, configuration, and process
+control. Verbose messages appear in the detailed (@file{*.log}) log
+file, but not in the summary (@file{*.sum}) log file.
+
+@item --version
+@itemx -V
+@cindex @code{-V} (@code{runtest} option)
+@cindex @code{--version} (@code{runtest} option)
+@cindex version numbers
+Prints out the version numbers of DejaGnu, @code{expect} and Tcl, and
+exits without running any tests.
+
+@item -D0
+@itemx -D1
+@cindex starting the tcl debugger
+@cindex tcl debugger
+@c FIXME!!! we should say a *lot* more about this debugger
+Start the internal Tcl debugger. The Tcl debugger supports breakpoints,
+single stepping, and other common debugging activities. (See @cite{A
+Debugger for Tcl Applications} by Don Libes. @footnote{Distributed in
+PostScript form with @code{expect} as the file@*
+@file{expect/tcl-debug.ps}.})
+
+If you specify @samp{-D1}, the @code{expect} shell stops at a breakpoint
+as soon as DejaGnu invokes it.
+
+If you specify @samp{-D0}, DejaGnu starts as usual, but you can enter
+the debugger by sending an interrupt (e.g. by typing @key{C-c}).
+@end table
+
+@node Customizing
+@chapter Setting @code{runtest} defaults
+
+@kindex site.exp
+@cindex variables of DejaGnu, defaults
+The site configuration file, @file{site.exp}, captures
+configuration-dependent values and propagates them to the DejaGnu test
+environment using Tcl variables. This ties the DejaGnu test scripts
+into the @code{configure} and @code{make} programs.
+
+@cindex @file{site.exp}, multiple
+@cindex overriding @file{site.exp}
+DejaGnu supports more than one @file{site.exp} file. The multiple
+instances of @file{site.exp} are loaded in a fixed order built into
+DejaGnu (the more local last). The first file loaded is the optional
+@code{~/.dejagnurc}, then the local files, and finally the global file.
+
+@enumerate
+@item
+There is am optional ``master'' @file{site.exp}, capturing configuration values
+that apply to DejaGnu across the board, in each configuration-specific
+subdirectory of the DejaGnu library directory. @code{runtest} loads
+these values first. @xref{Installation,,Configuring and Installing
+DejaGnu}. The master @file{site.exp} contains the default values for
+all targets and hosts supported by DejaGnu. This master file is
+identified by setting the environment variable @code{DEJAGNU} to the
+name of the file. This is also refered to as the ``global'' config file.
+
+@item
+Any directory containing a configured test suite also has a
+@file{site.exp}, capturing configuration values specific to the tool
+under test. Since @code{runtest} loads these values last, the
+individual test configuration can either rely on and use, or override,
+any of the global values from the ``master'' @file{site.exp}.
+
+You can usually generate or update the testsuite @file{site.exp} by
+typing @samp{make site.exp} in the test suite directory, after the test
+suite is configured.
+
+@item
+You can also have a file in your home directory called
+@code{.dejagnurc}. This gets loaded first before the other config
+files. Usually this is used for personal stuff, like setting
+@code{all_flag} so all the output gets printed, or verbosity levels.
+@end enumerate
+
+You can further override the default values in a user-editable section
+of any @file{site.exp}, or by setting variables on the @code{runtest}
+command line.
+
+@menu
+* Config Values:: Variables used in the configuration file.
+* Master Config File:: The master configuration file.
+* Local Config File:: The local configuration file.
+* Personal Config File:: The personal configuration file.
+@end menu
+
+@node Config Values, Master Config File, , Customizing
+@subsection Config Variables
+@cindex configuration dependent defaults
+@cindex setting defaults for DejaGnu variables
+
+@c NOTE: default values are given via @code{"fubar"} rather than the
+@c more conventional @samp{fubar} to permit a consistent and clear
+@c notation for the empty string (@code{""}), which will work exactly as
+@c typed.
+
+DejaGnu uses a named array in Tcl to hold all the info for each
+machine. In the case of a canadian cross, this means host information as
+well as target information. The named array is called
+@code{target_info}, and it has two indices. The following fields are
+part of the array.
+
+@table @code
+@item name
+The name of the target. (mostly for error messages) This
+should also be the string used for this target's array.
+It should also be the same as the linker script so we
+can find them dynamically. This should be the same as the argument used
+for @code{push_target@{@}}.
+
+@item ldflags
+This is the linker flags required to produce a fully linked
+executable. For @code{libgloss} supported targets this is usually just
+the name of the linker script.
+
+@item config
+The target canonical for this target. This is used by some init files to
+make sure the target is supported.
+
+@item cflags
+The flags required to produce an object file from a source file.
+
+@item connect
+This is the connectmode for this target. This is for both IP and
+serial connections. Typically this is either @code{telnet},
+@code{rlogin}, or @code{rsh}.
+
+@item target
+This is the hostname of the target. This is for TCP/IP based connections,
+and is also used for version of tip that use /etc/remote.
+
+@item serial
+This is the serial port. This is typically /dev/tty? or com?:.
+
+@item netport
+This is the IP port. This is commonly used for telneting to target
+boards that are connected to a terminal server. In that case the IP port
+specifies the which serial port to use.
+
+@item baud
+This is the baud rate for a serial port connection.
+
+@item x10
+This is the parameters for an x10 controller. These are simple devices
+that let us power cycle or reset a target board remotely.
+
+@item fileid
+This is the fileid or spawn id of of the connection.
+
+@item prompt
+a glob style pattern to recognize the prompt.
+
+@item abbrev
+abbreviation for tool init files.
+
+@item ioport
+This is the port for I/O on dual port systems. In this configuration,
+the main serial port @code{0} is usually used for stdin and stdout,
+which the second serial port can be used for debugging.
+@end table
+
+The first index into the array is the same value as used in the
+@code{name} field. This is usually a short version of the name of the
+target board. For an example, here's the settings I use for my
+@code{Motorola's} @code{IDP} board and my @code{Motorola} 6U VME
+@code{MVME135-1} board. (both m68k targets)
+
+@cartouche
+@smallexample
+# IDP board
+set target_info(idp,name) "idp"
+set target_info(idp,ldflags) "-Tidp.ld"
+set target_info(idp,config) m68k-unknown-aout
+set target_info(idp,cflags) ""
+set target_info(idp,connect) telnet
+set target_info(idp,target) "s7"
+set target_info(idp,serial) "tstty7"
+set target_info(idp,netport) "wharfrat:1007"
+set target_info(idp,baud) "9600"
+# MVME 135 board
+set target_info(idp,name) "mvme"
+set target_info(idp,ldflags) "-Tmvme.ld"
+set target_info(idp,config) m68k-unknown-aout
+set target_info(idp,cflags) ""
+set target_info(idp,connect) telnet
+set target_info(idp,target) "s8"
+set target_info(idp,serial) "tstty8"
+set target_info(idp,netport) "wharfrat:1008"
+set target_info(idp,baud) "9600"
+@end smallexample
+@end cartouche
+
+DejaGnu can use this information to switch between multiple targets in
+one test run. This is done through the use of the @code{push_target}
+procedure, which is discussed elsewhere.
+@c FIXME: write that section and put an xref here
+
+This array can also hold information for a remote host, which is used
+when testing a candain cross. In this case, the only thing different is
+the index is just @code{host}. Here's the settings I use to run tests
+on my NT machine while running DejaGnu on a Unix machine. (in this case
+a Linux box)
+
+@cartouche
+@smallexample
+set target_info(host,name) "nt-host"
+set target_info(host,config) "386-unknown-winnt"
+set target_info(host,connect) "telnet"
+set target_info(host,target) "ripple"
+@end smallexample
+@end cartouche
+
+There is more info on how to use these variables in the sections on the
+config files. @xref{Master Config File,,Configuration Files}.
+
+@cindex option defaults
+@cindex @code{runtest} option defaults
+@cindex variables for option defaults
+@cindex defaults, option
+In the user editable second section of @file{site.exp}, you can not only
+override the configuration variables captured in the first section, but
+also specify default values for all the @code{runtest} command line
+options. Save for @samp{--debug}, @samp{--help}, and @samp{--version},
+each command line option has an associated Tcl variable. Use the Tcl
+@code{set} command to specify a new default value (as for the
+configuration variables). The following table describes the
+correspondence between command line options and variables you can set in
+@file{site.exp}. @xref{Invoking runtest,,Running the Tests}, for
+explanations of the command-line options.
+
+@kindex all_flag
+@kindex baud
+@kindex reboot
+@kindex outdir
+@kindex objdir
+@kindex runtests
+@kindex ignoretests
+@kindex srcdir
+@kindex tracelevel
+@kindex targetname
+@kindex connectmode
+@kindex tool
+@kindex target_triplet
+@kindex host_triplet
+@kindex build_triplet
+@kindex verbose
+
+@cindex command line option variables
+@cindex Tcl variables for option defaults
+@cindex default options, controlling
+@cindex options, Tcl variables for defaults
+
+@ifinfo
+@display
+runtest Tcl
+option variable description
+__________ ________ ___________________________________________
+
+--all all_flag display all test results if set
+
+--baud baud set the default baud rate to something other
+ than 9600.
+--connect connectmode @samp{rlogin}, @samp{telnet}, @samp{rsh},
+ @samp{kermit}, @samp{tip}, or @samp{mondfe}
+
+--outdir outdir directory for @file{@var{tool}.sum} and @file{@var{tool}.log}
+
+--objdir objdir directory for pre-compiled binaries
+
+--reboot reboot reboot the target if set to @code{"1"};
+ do not reboot if set to @code{"0"} (the default)
+
+--srcdir srcdir directory of test subdirectories
+
+--strace tracelevel a number: Tcl trace depth
+
+--tool tool name of tool to test; identifies init, test subdir
+
+--verbose verbose verbosity level. As option, use multiple times;
+ as variable, set a number, 0 or greater
+--target target_triplet The canonical configuration string for the target.
+--host host_triplet The canonical configuration string for the host.
+--build build_triplet The canonical configuration string for the
+ build host.
+
+@end display
+@end ifinfo
+
+@tex
+\vbox{\halign{\hfil \tt #\quad &\quad\tt #\hfil &\hbox{\vtop{{\raggedright\parindent=0pt\parskip=5pt\hsize=2.75in\rm#\strut\par}}}\hfill\cr
+\cr
+{\it runtest}&{\it Tcl}\cr
+{\it option}&{\it variable}&{\it description}\cr
+\noalign{\hrule width\hsize}\cr
+--all &all\_flag &display all test results if set\cr
+--baud &baud &set the default baud rate to something other
+ than 9600.\cr
+--connect &connectmode &@samp{rlogin}, @samp{telnet}, @samp{rsh},
+ @samp{kermit}, @samp{tip}, or @samp{mondfe}\cr
+--mail &mailing\_list&address list for mailing test output\cr
+--name &targetname &network name of testing target or its host\cr
+--outdir &outdir &directory for @file{@var{tool}.sum} and @file{@var{tool}.log}\cr
+--objdir &objdir &directory for compiled binaries\cr
+--reboot &reboot &reboot the target if set to @code{"1"};
+do not reboot if set to @code{"0"} (the default)\cr
+--srcdir &srcdir &directory of test subdirectories\cr
+--strace &tracelevel &a number: Tcl trace depth\cr
+--tool &tool &name of tool to test; identifies init, test subdir\cr
+--verbose &verbose &verbosity level. As option, use multiple times;
+ as variable, set a number, 0 or greater\cr
+--target &target\_triplet
+ &The canonical configuration string for the target.\cr
+--host &host\_triplet &The canonical configuration string for the host.\cr
+--build &build\_triplet &The canonical configuration string for the
+ build host.\cr
+}}
+@end tex
+
+@node Master Config File, Local Config File, Config Values, Customizing
+@subsection Master Config File
+@cindex master @file{site.exp}
+@cindex @file{site.exp} for all of DejaGnu
+The master config file is where all the target specific config variables
+get set for a whole site get set. The idea is that for a centralized
+testing lab where people have to share a target between multiple
+developers. There are settings for both remote targets and remote hosts.
+Here's an example of a Master Config File (also called the Global config
+file) for a @emph{canadian cross}. A canadian cross is when you build
+and test a cross compiler on a machine other than the one it's to be
+hosted on.
+
+Here we have the config settings for our California office. Note that
+all config values are site dependant. Here we have two sets of values
+that we use for testing m68k-aout cross compilers. As both of these
+target boards has a different debugging protocol, we test on both of
+them in sequence.
+
+@cartouche
+@smallexample
+global CFLAGS
+global CXXFLAGS
+
+case "$target_triplet" in @{
+ @{ "native" @} @{
+ set target_abbrev unix
+ @}
+ @{ "m68*-unknown-aout" @} @{
+ set target_abbrev "rom68k"
+ # IDP target # IDP board with rom68k monitor
+ set target_info(idp,name) "idp"
+ set target_info(idp,ldflags) "-Tidp.ld"
+ set target_info(idp,config) m68k-unknown-aout
+ set target_info(idp,cflags) ""
+ set target_info(idp,connect) telnet
+ set target_info(idp,target) "s7"
+ set target_info(idp,serial) "tstty12"
+ set target_info(idp,netport) "truckin:1007"
+ set target_info(idp,baud) "9600"
+ # MVME target # Motorola MVME 135 with BUG monitor
+ set target_info(mvme,name) "mvme"
+ set target_info(mvme,ldflags) "-Tmvme.ld"
+ set target_info(mvme,config) m68k-unknown-aout
+ set target_info(mvme,cflags) ""
+ set target_info(mvme,connect) telnet
+ set target_info(mvme,target) "s4"
+ set target_info(mvme,serial) "tstty8"
+ set target_info(mvme,netport) "truckin:1004"
+ set target_info(mvme,baud) "9600"
+ @}
+@}
+@end smallexample
+@end cartouche
+
+ In this case, we have support for several remote hosts for
+our m68k-aout cross compiler. Typically the remote Unix hosts run
+DejaGnu locally, but we also use them for debugging the testsuites when
+we find problems in running on remote hosts. Expect won't run on NT, so
+DejaGnu is run on the local build machine, and it'll connect to the NT
+host and run all the tests for this cross compiler on that host.
+
+@smallexample
+@cartouche
+case "$host_triplet" in @{
+ "native" @{
+ @}
+ "i?86-*-linux*" @{ # Linux host
+ set target_info(host,name) "linux-host"
+ set target_info(host,config) $host_triplet
+ set target_info(host,connect) rlogin
+ set target_info(host,target) chinadoll
+ @}
+ "i?86-*-winnt # NT host
+ set target_info(host,name) "nt-host"
+ set target_info(host,config) i386-unknown-winnt
+ set target_info(host,connect) telnet
+ set target_info(host,target) ripple
+ @}
+ "hppa*-hp-hpux*" @{ # HP-UX host
+ set target_info(host,name) "hpux-host"
+ set target_info(host,config) $host_triplet
+ set target_info(host,connect) rlogin
+ set target_info(host,target) slipknot
+ @}
+ "sparc-sun-sunos*" @{ # SunOS (sun4)
+ set target_info(host,name) "sunos-host"
+ set target_info(host,config) $host_triplet
+ set target_info(host,connect) rlogin
+ set target_info(host,target) darkstar
+ @}
+@}
+@end cartouche
+@end smallexample
+
+@node Local Config File, Personal Config File, Master Config File, Customizing
+@subsection Local Config File
+@cindex local @file{site.exp}
+@cindex @file{site.exp} for each tool
+It is usually more convenient to keep these ``manual overrides'' in the
+@file{site.exp} local to each test directory, rather than in the
+``master'' @file{site.exp} in the DejaGnu library.
+
+All local @file{site.exp} usually files have two sections, separated by
+comment text. The first section is the part that is generated by
+@code{make}. It is essentially a collection of Tcl variable definitions
+based on @file{Makefile} environment variables. Since they are generated
+by @code{make}, they contain the values as specified by
+@code{configure}. (You can also customize these values by using the
+@samp{--site} option to @code{configure}.) In particular, this section
+contains the @file{Makefile} variables for host and target configuration
+data. Do not edit this first section; if you do, your changes are replaced
+next time you run @code{make}.
+
+The first section starts with:
+
+@cartouche
+@smallexample
+## these variables are automatically generated by make ##
+# Do not edit here. If you wish to override these values
+# add them to the last section
+@end smallexample
+@end cartouche
+
+In the second section, you can override any default values (locally to
+DejaGnu) for all the variables. The
+second section can also contain your preferred defaults for all the
+command line options to @code{runtest}. This allows you to easily
+customize @code{runtest} for your preferences in each configured
+test-suite tree, so that you need not type options repeatedly on the
+command line. (The second section may also be empty, if you do not wish
+to override any defaults.)
+
+The first section ends with this line:
+
+@cartouche
+@smallexample
+## All variables above are generated by configure. Do Not Edit ##
+@end smallexample
+@end cartouche
+
+You can make any changes under this line. If you wish to redefine a
+variable in the top section, then just put a duplicate value in this
+second section. Usually the values defined in this config file are
+related to the configuration of the test run. This is the ideal place to
+set the variables @code{host_triplet}, @code{build_triplet},
+@code{target_triplet}. All other variables are tool dependant. ie for
+testing a compiler, the value for @var{CC} might be set to a freshly
+built binary, as opposed to one in the user's path.
+
+@node Personal Config File, , Local Config File, Customizing
+@subsection Personal Config File
+@cindex personal config @file{site.exp}
+@cindex @file{site.exp} for each person
+The personal config file is used to customize @code{runtest's} behaviour
+for each person. It's typically used to set the user prefered setting
+for verbosity, and any experimental Tcl procedures. My personal
+@file{~/.dejagnurc} file looks like:
+
+@cartouche
+@smallexample
+set all_flag 1
+set RLOGIN /usr/ucb/rlogin
+set RSH /usr/ucb/rsh
+@end smallexample
+@end cartouche
+
+Here I set @code{all_flag} so I see all the test cases that PASS along
+with the ones that FAIL. I also set @var{RLOGIN} and @code{RSH} to the
+BSD version. I have @code{kerberos} installed, and when I rlogin to a
+target board, it usually isn't supported. So I use the non secure
+versions of these programs rather than the default that's in my path.
+
+@node Internals
+@chapter The DejaGnu Implementation
+@cindex operating principles
+@cindex internal details
+
+DejaGnu is entirely written in @code{expect}, which uses Tcl as a
+command language. @code{expect} serves as a very programmable shell;
+you can run any program, as with the usual Unix command shells---but
+once the program is started, your @code{expect} script has fully
+programmable control of its input and output. This does not just apply
+to the programs under test; @code{expect} can also run any auxiliary
+program, such as @code{diff} or @code{sh}, with full control over its
+input and output.
+
+DejaGnu itself is merely a framework for the set of test suites
+distributed separately for each @sc{gnu} tool. Future releases of
+@sc{gnu} tools will include even more tests, developed throughout the
+free software community.
+
+@kindex runtest.exp
+@code{runtest} is the glue to tie together and manage the test scripts.
+The @code{runtest} program is actually a simple Bourne shell script that
+locates a copy of the @code{expect} shell and then starts the main Tcl
+code, @code{runtest.exp}. @code{runtest.exp} itself has these essential
+functions:
+
+@enumerate
+@item
+Parse the command line options, load the library files, and load the
+default configuration files.
+
+@item
+Locating the individual test scripts. @code{runtest.exp} locates the tests
+by exploiting a straightforward naming convention based on the string
+you specify with the @samp{--tool} option.
+
+@item
+Providing an extended test environment, by defining additional Tcl
+procedures beyond those already in @code{expect}.
+
+@item
+Locating target-dependent functions, to standardize the test environment
+across a wide variety of test platforms.
+@end enumerate
+
+@menu
+* Names:: Conventions for using tool names
+* Init Module:: Initialization module
+* DejaGnu Builtins:: DejaGnu provides these Tcl procedures
+* Target Dependent:: Procedures supplied by the init module
+* Cross Targets:: Remote targets supported
+* Input Files:: The files DejaGnu depends on
+* Output Files:: The files DejaGnu produces
+@end menu
+
+@node Names
+@section Conventions for using tool names
+
+@cindex @code{--tool} and naming conventions
+@cindex tool names and naming conventions
+@cindex naming conventions
+DejaGnu uses @samp{$tool}, the name of the tool under test, to tie
+together the testing configuration in a straightforward but flexible
+way. If there is only one testsuite for a particular application, then
+@samp{$tool} is optional.
+
+@samp{$tool} is @emph{not} used to invoke the tool, since sites that run
+multiple configurations of a particular tool often call each
+configuration by a different name. @code{runtest} uses the
+configuration-dependent variables captured in @file{site.exp} to
+determine how to call each tool.
+
+@cindex directory names and @code{--tool}
+@cindex test directories, naming
+@code{runtest} uses tool names to find directories containing tests.
+@code{runtest} scans the source directory (specified with
+@code{--srcdir}) for all directories whose names start with the tool
+name. It is a common practice to put a period after the tool part of the
+name. For instance, directories that start with
+@samp{g++.} contain @sc{g++} tests. To add a new test, just put it in
+any directory (create an entirely new directory, if you wish) whose name
+follows this convention.
+
+@cindex @code{exp} filename suffix
+@cindex test filename
+@cindex filename for test files
+A test is any file in an appropriately named subdirectory whose name
+ends in @samp{.exp} (the conventional way of naming @code{expect}
+scripts). These simple naming conventions make it as simple as possible
+to install new tests: all you must do is put the test in the right
+directory.
+
+@cindex order of tests
+@cindex tests, running order
+@code{runtest} sorts the tests in each subdirectory by name (using the
+Tcl @code{lsort} command) and runs them in the resulting order.
+
+@node Init Module
+@section Initialization module
+@cindex tool initialization
+@cindex setting up targets
+
+@c FIXME! should this node be merged with "Target dependent"?
+
+@cindex init file, purpose
+@cindex starting interactive tools
+@cindex initialization
+The initialization module (or ``init file'') has two purposes: to
+provide tool and target dependent procedures, and to start up an
+interactive tool to the point where it is ready to operate. The latter
+includes establishing communications with the target. All the tests for
+interactive programs assume that the tool is already running and
+communicating. Initialization modules for non-interactive programs may
+only need to supply the support functions.
+
+@cindex init file name
+@cindex name, initialization module
+Each test suite directory must contain (in its @file{config}
+subdirectory) a separate initialization module for each target. The
+appropriate init file is can be named several ways. The prefered name is
+the @emph{os} part of the canonical configuration name with @code{.exp}
+as the suffix. An example would be that for an @code{m68k-coff} system,
+the @code{target_os} part would be @code{coff}. The next way is for
+system where there are short filenames, or a shortcut is desired to
+refer to the OS name for that target. This is uses the value of
+@code{$target_abbrev} rather than the @code{target_os}.
+
+The final file looked for is simply @file{default.exp}. If there is only
+one operating system to support, then this file can be used. It's main
+purpose is to offer some support for new operating systems, or for
+unsupported cross targets. The last file looked for is
+@file{unknown.exp}. This is usually limited to error handling for
+unsupported targets. It's whole contents is typically.
+
+@cartouche
+@smallexample
+perror "Sorry, there is no support for this target"
+exit 1
+@end smallexample
+@end cartouche
+
+At the beginning of the init file, you must first determine the proper
+executable name of the tool to execute, since the actual name of the
+tool to be tested my vary from system to system. Here's an example
+for the @sc{GNU} C compiler.
+
+@cartouche
+@smallexample
+global AR
+# look for the archiver ar
+if ![info exists AR] @{
+ set AR [findfile $base_dir/../../binutils/ar $base_dir/../../binutils/ar [tr
+ansform ar]]
+ verbose "AR defaulting to $AR" 2
+@}
+@}
+
+global CFLAGS
+if ![info exists CFLAGS] then @{
+ set CFLAGS ""
+@}
+@end smallexample
+@end cartouche
+
+It is always a good idea to first check the variable, and only set it if
+it has not yet been defined. Often the proper value of @code{AR} is set
+on the command line that invokes @file{runtest}.
+
+@kindex findfile
+The @code{findfile} procedure takes as it's first argument a file name
+to look for. The second argument is returned if the file is found, and
+the third argument is returned if the file is not found. @code{base_dir}
+is set internally by DejaGnu to the top level directory of the object
+tree.
+
+@kindex transform
+The @code{transform} procedure takes as its argument the native name of
+a tool (such as @samp{gcc} for the compiler), and returns the name as
+configured for that tool in the current installation. (For example, a
+cross-compiling version of @sc{gnu} CC that generates MIPS code may be
+installed with a name like @code{mips-idt-ecoff-gcc}.)
+
+In a test running native, writing the Tcl code for initialization is
+usually quite simple. For cross configurations, however, more elaborate
+instructions are usually needed to describe how to talk to a remote
+target.
+
+Each initialization module defines up to four procedures with standard
+names and purposes. The names of these procedures begin with
+@samp{$tool}, the string that identifies tests for a particular tool:
+@code{$tool_start}, @code{$tool_load}, @code{$tool_exit}, and
+@code{$tool_version}. For example, the start procedure for @sc{gdb} is
+called @code{gdb_start}. (Since start procedures are used differently
+for batch and interactive tools, however, @code{runtest} itself never
+calls the start procedure. Init files for interactive tools are
+expected to end by running the start procedure.)
+
+@cindex utilities, loading from init file
+@cindex defaults, setting in init file
+The initialization module is also a good place to call @code{load_lib}
+to get any collections of utility procedures meant for a family of test
+cases, and to set up default values for any additional Tcl variables
+needed for a specific set of tests.
+
+@xref{Target Dependent,,Target dependent procedures}, for full
+descriptions of these procedures.
+
+@node DejaGnu Builtins
+@section DejaGnu procedures
+@cindex built in procedures, DejaGnu
+
+DejaGnu provides these Tcl procedures for use in test scripts.
+You can also use any standard @code{expect} or Tcl function. These
+procedures are stored in libraries, which DejaGnu loads at
+runtime. Here's explanation of the library procedures that get loaded at
+runtime. All other librarys are optional, and need to be loaded by the
+testsuite.
+
+@menu
+* framework.exp:: Core Internal Procedures.
+* remote.exp:: Procedures for remote communication.
+* utils.exp:: Utility procedures.
+* target.exp:: Cross target procedures.
+* debugger.exp:: Procedures for debugging your Tcl code.
+@end menu
+
+@node framework.exp, remote.exp, ,DejaGnu Builtins
+@subsection Core Internal Procedures
+@cindex Core Internal Procedures
+
+@xref{Posix,,A POSIX conforming test framework}, for more detailed
+explanations of the test outcomes (@samp{FAIL}, @samp{PASS},
+@samp{UNTESTED}, @samp{UNRESOLVED}, @samp{UNSUPPORTED}).
+
+@ftable @code
+@item perror "@var{string} @var{number}"
+@cindex test case, ERROR in
+@kindex ERROR
+Declares a severe error in the testing framework itself.
+@code{perror} writes in the log files a message beginning with
+@samp{ERROR}, appending the argument @var{string}. If the optional
+@var{number} is supplied, then this is used to set the internal count of
+errors to that value.
+
+As a side effect, @code{perror} also changes the effect of the next
+@code{pass} or @code{fail} command: the test outcome becomes
+@samp{UNRESOLVED}, since an automatic @samp{PASS} or @samp{FAIL} cannot
+be trusted after a severe error in the test framework. If the optional
+numeric value is @samp{0}, then there are no further side effects to
+calling this function, and the following test outcome doesn't become
+@samp{UNRESOLVED}. This can be used for errors with no known side
+effects.
+
+@item warning "@var{string} @var{number}"
+@cindex test case, WARNING in
+@kindex WARNING
+Declares detection of a minor error in the test case itself.
+@code{warning} writes in the log files a message beginning with
+@samp{WARNING}, appending the argument @var{string}. Use @code{warning}
+rather than @code{error} for cases (such as communication failure
+to be followed by a retry) where the test case can recover from the
+error. If the optional @var{number} is supplied, then this is used to
+set the internal count of warnings to that value.
+
+As a side effect, @code{warning_threshold} or more calls to
+@code{warning} in a single test case also changes the effect of the next
+@code{pass} or @code{fail} command: the test outcome becomes
+@samp{UNRESOLVED} since an automatic @samp{PASS} or @samp{FAIL} may not
+be trustworthy after many warnings. If the optional numeric value is
+@samp{0}, then there are no further side effects to calling this
+function, and the following test outcome doesn't become
+@samp{UNRESOLVED}. This can be used for errors with no known side
+effects.
+
+@item note "@var{string}"
+@cindex test case, informational messages
+@kindex NOTE
+Appends an informational message to the log file.
+@code{note} writes in the log files a message beginning with
+@samp{NOTE}, appending the argument @var{string}. Use @code{note}
+sparingly. @code{verbose} should be used for most such messages,
+but in cases where a message is needed in the log file regardless of
+the verbosity level use @code{note}.
+
+@item pass "@var{string}"
+@cindex test case, declaring success
+Declares a test to have passed. @code{pass} writes in the
+log files a message beginning with @samp{PASS} (or @code{XPASS}, if
+failure was expected), appending the argument @var{string}.
+
+@item fail "@var{string}"
+@cindex test case, declaring failure
+Declares a test to have failed. @code{fail} writes in the
+log files a message beginning with @samp{FAIL} (or @code{XFAIL}, if
+failure was expected), appending the argument @var{string}.
+
+@item unresolved "@var{string}"
+@cindex test case, declaring ambiguity
+Declares a test to have an unresolved outcome. @code{unresolved} writes
+in the log file a message beginning with @samp{UNRESOLVED}, appending
+the argument @var{string}. This usually means the test did not execute
+as expected, and a human being must go over results to determine if it
+passed or failed (and to improve the test case).
+
+@item untested "@var{string}"
+@cindex test case, declaring no test
+Declares a test was not run. @code{untested} writes in the log file a
+message beginning with @samp{UNTESTED}, appending the argument
+@var{string}. For example, you might use this in a dummy test whose
+only role is to record that a test does not yet exist for some feature.
+
+@item unsupported "@var{string}"
+@cindex test case, declaring no support
+Declares that a test case depends on some facility that does not exist
+in the testing environment. @code{unsupported} writes in the log file a
+message beginning with @samp{UNSUPPORTED}, appending the argument
+@var{string}.
+
+@item get_warning_threshold
+@cindex test case, WARNING threshold
+Returns the current value of @code{warning_threshold}.
+The default value is 3.
+
+@item set_warning_threshold @var{threshold}
+@cindex test case, WARNING threshold
+Sets the value of @code{warning_threshold}.
+A value of @code{0} disables it: calls to @code{warning} will not turn
+a @samp{PASS} or @samp{FAIL} into an @samp{UNRESOLVED}.
+
+@item transform "@var{toolname}"
+@cindex transform tool name
+@cindex installed tool name
+@cindex tool name, as installed
+@cindex name transformations
+Generates a string for the name of a tool as it was configured and
+installed, given its native name (as the argument @var{toolname}).
+This makes the assumption that all tools are installed using the same
+naming conventions: it extrapolates from the invocation name for
+@file{runtest}. For example, if you call @code{runtest} as
+@file{m68k-vxworks-runtest}, the result of @w{@samp{ transform "gcc" }}
+is @samp{m68k-vxworks-gcc}.
+
+@item ishost "@var{host}"
+@cindex host configuration test
+Tests for a particular @emph{host} environment. If the currently
+configured host matches the argument string, the result is @code{1};
+otherwise the result is @code{0}. @var{host} must be a full three-part
+@code{configure} host name; in particular, you may not use the shorter
+nicknames supported by @code{configure} (but you can use wildcard
+characters, using shell syntax, to specify sets of names).
+
+@item istarget "@var{target}"
+@cindex target configuration test
+Tests for a particular @emph{target} environment. If the currently
+configured target matches the argument string, the result is @code{1};
+otherwise the result is @code{0}. @var{target} must be a full
+three-part @code{configure} target name; in particular, you may not use
+the shorter nicknames supported by @code{configure} (but you can use
+wildcard characters, using shell syntax, to specify sets of names). If it is
+passed a @code{NULL} string, then it returns the name of the build
+canonical configuration.
+
+@item isbuild "@var{host}"
+@cindex build host configuration test
+Tests for a particular @emph{build host} environment. If the currently
+configured host matches the argument string, the result is @code{1};
+otherwise the result is @code{0}. @var{host} must be a full three-part
+@code{configure} host name; in particular, you may not use the shorter
+nicknames supported by @code{configure} (but you can use wildcard
+characters, using shell syntax, to specify sets of names). If it is
+passed a @code{NULL} string, then it returns the name of the build
+canonical configuration.
+
+item is3way "@var{host}"
+@cindex canadian cross configuration test
+Tests for a canadian cross. This is when the tests will be run on a
+remotly hosted cross compiler. If it is a canadian cross, then the
+result is @code{1}; otherwise the result is @code{0}.
+
+@item isnative
+@cindex native configuration test
+Tests whether the current configuration has the same host and target.
+When it runs in a @emph{native} configuration this procedure returns a
+@code{1}; otherwise it returns a @code{0}.
+
+@item load_lib "@var{library-file}"
+@cindex load library file
+Loads the file @var{library-file} by searching a fixed path built into
+@code{runtest}. If DejaGnu has been installed, it looks in a path
+starting with the installed library directory. If you are running
+DejaGnu directly from a source directory, without first running
+@samp{make install}, this path defaults to the current directory. In
+either case, it then looks in the current directory for a directory
+called @code{lib}. If there are duplicate definitions, the last one
+loaded takes precedence over the earlier ones.
+
+@item setup_xfail "@var{config} @r{[}@var{bugid}@r{]}"
+@c two spaces above to make it absolutely clear there's whitespace---a
+@c crude sort of italic correction!
+@cindex test case, expecting failure
+@cindex failure, expected
+@cindex expected failure
+Declares that the test is expected to fail on a particular set of
+configurations. The @var{config} argument must be a list of full
+three-part @code{configure} target name; in particular, you may not use
+the shorter nicknames supported by @code{configure} (but you can use the
+common shell wildcard characters to specify sets of names). The
+@var{bugid} argument is optional, and used only in the logging file
+output; use it as a link to a bug-tracking system such as @sc{gnats}
+(@pxref{Overview,, Overview, gnats.info, Tracking Bugs With GNATS}).
+
+@cindex @code{XFAIL}, producing
+@cindex @code{XPASS}, producing
+Once you use @code{setup_xfail}, the @code{fail} and @code{pass}
+procedures produce the messages @samp{XFAIL} and @samp{XPASS}
+respectively, allowing you to distinguish expected failures (and
+unexpected success!) from other test outcomes.
+
+@emph{Warning:} you must clear the expected failure after using
+@code{setup_xfail} in a test case. Any call to @code{pass} or
+@code{fail} clears the expected failure implicitly; if the test has some
+other outcome, e.g. an error, you can call @code{clear_xfail} to clear
+the expected failure explicitly. Otherwise, the expected-failure
+declaration applies to whatever test runs next, leading to surprising
+results.
+
+@item check_conditional_xfail @var{message} @var{targets} @var{includes} @var{excludes}
+@cindex test case, expecting a conditional failure
+@cindex failure, conditional expected
+@cindex conditional expected failure
+
+This procedure adds a condition xfail, based on compiler options used to
+create a test case executable. If an include options is found in the
+compiler flags, and it's the right architecture, it'll trigger an
+XFAIL. Otherwise it'll produce an ordinary FAIL. You can also specify
+flags to exclude. This makes a result be a FAIL, even if the included
+options are found. To set the conditional, set the variable
+@var{compiler_conditional_xfail_data} to the fields "[message string] [targets
+list] [includes list] [excludes list]" (descriptions below). This is the
+checked at pass/fail decision time, so there is no need to call the
+procedure yourself, unless you wish to know if it gets triggered. After
+a pass/fail, the variable is reset, so it doesn't effect other tests.
+
+The parameters are:
+
+@table @code
+@item message
+is the message to print with the normal test result
+
+@item targets
+is a string with the targets to activate this conditional on.
+
+@item includes
+is a list of sets of options to search for in the compiler options to
+activate this conditional. If any set of the options matches, then this
+conditional is true.
+
+@item excludes
+is a list of sets of options to search for in the compiler options to
+activate this conditional. If any set of the options matches,
+(regardless of whether any of the include sets match) then this
+conditional is de-activated.
+@end table
+
+returns:
+
+@table @code
+@item 1
+if the conditional is true
+@item 0
+if the conditional is false
+@end table
+
+An example of setting the variable would be:
+
+@cartouche
+@smallexample
+set compiler_conditional_xfail_data @{@ \
+ "I sure wish I knew why this was hosed" \
+ "sparc*-sun*-* *-pc-*-*" \
+ @{@"-Wall -v" "-O3"@}@ \
+ @{@"-O1" "-Map" @}@ \
+ @}@
+@end smallexample
+@end cartouche
+
+ What this does is it matches only for these two targets if "-Wall -v" or
+"-O3" is set, but neither "-O1" or "-Map" is set.
+
+ For a set to match, the options specified are searched for independantly of
+each other, so a "-Wall -v" matches either "-Wall -v" or "-v -Wall". A space
+seperates the options in the string. Glob-style regular expressions are also
+permitted.
+
+@item clear_xfail @var{config}
+@cindex cancelling expected failure
+@cindex expected failure, cancelling
+Cancel an expected failure (previously declared with @code{setup_xfail})
+for a particular set of configurations. The @var{config} argument is a
+list of configuration target names. It is only necessary to call
+@code{clear_xfail} if a test case ends without calling either
+@code{pass} or @code{fail}, after calling @code{setup_xfail}.
+
+@item verbose @r{[}-log@r{]} @r{[}-n@r{]} @r{[}--@r{]} "@var{string}" @var{number}
+@cindex @code{verbose} builtin function
+Test cases can use this function to issue helpful messages depending on
+the number of @samp{--verbose} options on the @code{runtest} command
+line. It prints @var{string} if the value of the variable
+@code{verbose} is higher than or equal to the optional @var{number}. The
+default value for @var{number} is 1. Use the optional @samp{-log} argument
+to cause @var{string} to always be added to the log file, even if it won't
+be printed. Use the optional @samp{-n} argument to print @var{string}
+without a trailing newline. Use the optional @samp{--} argument if
+@var{string} begins with "-".
+
+@end ftable
+
+@noindent
+@node remote.exp, utils.exp, framework.exp, DejaGnu Builtins
+@subsection Remote Communication Procedures
+
+@kindex remote.exp
+@kindex lib/remote.exp
+@cindex remote connection procedures
+@cindex communications procedures
+@file{lib/remote.exp} defines these functions, for establishing and
+managing communications:
+
+@emph{Procedures to establish a connection:} Each of these procedures
+tries to establish the connection up to three times before returning.
+Warnings (if retries will continue) or errors (if the attempt is
+abandoned) report on communication failures. The result for any of
+these procedures is either @code{-1}, when the connection cannot be
+established, or the spawn ID returned by the @code{expect} command
+@code{spawn}.
+
+It use the value of the @code{connect} field in the @code{target_info}
+array (was @code{connectmode} as the type of connection to make. Current
+supported connection types are tip, kermit, telnet, rsh, rlogin, and
+netdata. If the @code{--reboot} option was used on the runtest command
+line, then the target is rebooted before the connection is made.
+
+@ftable @code
+
+@item remote_open @var{type}
+@cindex Opening a remote connection
+@emph{Remote Connection Procedure.} This is passed @emph{host} or
+@emph{target}. Host or target refers to whether it is a connection to a
+remote target, or a remote host. This opens the connection to the
+desired target or host using the default values in the configuration
+system. It returns that @code{spawn_id} of the process that manages the
+connection. This value can be used in @code{expect} or @code{exp_send}
+statements, or passed to other procedures that need the connection
+process's id. This also sets the @code{fileid} field in the
+@code{target_info} array.
+
+
+@item remote_close @var{shellid}
+@cindex Closing a remote connection
+@emph{shellid} is value returned by a call to @code{remote_open}. This
+closes the connection to the target so resources can be used by
+others. This parameter can be left off if the @code{fileid} field in the
+@code{target_info} array is set.
+
+@item telnet @var{hostname} @var{port}
+@itemx rlogin @var{hostname}
+@itemx rsh @var{hostname}
+@cindex IP network procedures
+@cindex network (IP) procedures
+@emph{IP network procedures.} @var{hostname} refers to the IP address or
+name (for example, an entry in @file{/etc/hosts}) for this target. The
+procedure names reflect the Unix utility used to establish a
+connection. The optional @var{port} is used to specify the IP port
+number. The value of the @code{netport} field in the @code{target_info}
+array is used. (was @code{$netport}) This value has two parts, the
+hostname and the port number, seperated by a @emph{:}. If @code{host} or
+@code{target} is used in the @code{hostname} field, than the config
+array is used for all information.
+
+@item tip @var{port}
+@cindex serial line connection, @code{tip}
+@emph{Serial line procedure.} Connect using the Unix utility @code{tip}.
+@var{port} must be a name from the @code{tip} configuration file
+@file{/etc/remote}. Often, this is called @samp{hardwire}, or something
+like @samp{ttya}. This file holds all the configuration data for
+the serial port. The value of the @code{serial} field in the
+@code{target_info} array is used. (was @code{$serialport}) If
+@code{host} or @code{target} is used in the @code{port} field, than
+the config array is used for all information.
+
+@item kermit @var{port} @var{bps}
+@cindex serial line connection, @code{kermit}
+@emph{Serial line procedure.} Connect using the program @code{kermit}.
+@var{port} is the device name, e.g. @file{/dev/ttyb}. @var{bps} is
+the line speed to use (in bits per second) for the connection. The value
+of the @code{serial} field in the @code{target_info} array is used. (was
+@code{$serialport}) If @code{host} or @code{target} is used in the
+@code{port} field, than the config array is used for all information.
+
+@end ftable
+
+@noindent
+@emph{Procedures to manage a connection:}
+
+@ftable @code
+@item tip_download @var{spawnid} @var{file}
+@cindex download, @code{tip}
+@cindex serial download, @code{tip}
+Download @file{@var{file}} to the process @var{spawnid} (the value
+returned when the connection was established), using the @code{~put}
+command under @code{tip}. Most often used for single board computers
+that require downloading programs in @sc{ascii} S-records. Returns
+@code{1} if an error occurs, @code{0} otherwise.
+
+@item exit_remote_shell @var{spawnid}
+@cindex terminating remote connection
+@cindex remote connection, ending
+Exits a remote process started by any of the connection procedures.
+@var{spawnid} is the result of the connection procedure that started the
+remote process.
+
+@item download @var{file} @r{[} @var{spawnid} @r{]}
+@cindex download a file
+After you establish a connection to a target, you can download programs
+using this command. @code{download} reads in @var{file} (object code in
+S-record format) and writes it to the device controlling this
+@var{spawnid}. (From the point of view of the target, the S-record file
+comes in via standard input.)
+
+If you have more than one target active, you can use the optional argument
+@var{spawnid} to specify an alternative target (the default is the most
+recently established @var{spawnid}.)
+@end ftable
+
+@noindent
+@node utils.exp, target.exp, remote.exp, DejaGnu Builtins
+@subsection Utility Procedures
+
+@kindex utils.exp
+@kindex lib/utils.exp
+@file{lib/utils.exp} defines these utility procedures:
+
+@ftable @code
+@item getdirs @var{dir}
+@itemx getdirs @var{dir} @var{pattern}
+@cindex directories matching a pattern
+@cindex pattern match, directory
+Returns a list of all the directories in the single directory @var{dir}
+that match @var{pattern}. If you do not specify @var{pattern},
+@code{getdirs} assumes @samp{*}. You may use the common shell wildcard
+characters in @var{pattern}. If no directories match the pattern, then a
+@code{NULL} string is returned.
+
+@item find @var{dir} @var{pattern}
+@cindex files matching a pattern
+@cindex pattern match, filenames
+Search for files whose names match @var{pattern} (using shell wildcard
+characters for filename expansion). Search subdirectories recursively,
+starting at @var{dir}. The result is the list of files whose names
+match; if no files match, the result is empty. Filenames in the result
+include all intervening subdirectory names. If no files match the
+pattern, then a @code{NULL} string is returned.
+
+@item which @var{binary}
+@cindex path lookup
+Searches the execution path for an executable file @var{binary}, like
+the the BSD @code{which} utility. This procedure uses the shell
+environment variable @samp{PATH}. It returns @code{0} if the binary is
+not in the path, or if there is no @samp{PATH} environment variable. If
+@var{binary} is in the path, it returns the full path to @var{binary}.
+
+@item grep @var{filename} @var{regexp}
+@item grep @var{filename} @var{regexp} line
+@cindex regular expression, file contents
+@cindex searching file contents
+Search the file called @var{filename} (a fully specified path) for lines
+that contain a match for regular expression @var{regexp}. The result is
+a list of all the lines that match. If no lines match, the result is an
+empty string. Specify @var{regexp} using the standard regular
+expression style used by the Unix utility program @code{grep}.
+
+Use the optional third argument @samp{line} to start lines in the result
+with the line number in @var{filename}. (This argument is simply an
+option flag; type it just as shown---@samp{line}.)
+
+@item diff @var{filename} @var{filename}
+@cindex finding file differences
+@cindex comparing files
+Compares the two files and returns a 1 if they match, or a 0 if they
+don't. If @code{verbose} is set, then it'll print the differences to the
+screen.
+
+@item slay @var{name}
+@cindex slaying processes
+This look in the process table for @var{name} and send it a unix
+@code{SIGINT}, killing the process.
+
+@item absolute @var{path}
+@cindex converting relative paths to absolute
+This procedure takes the relative @var{path}, and converts it to an
+absolute path.
+
+@item psource @var{filename}
+@cindex sourcing Tcl files
+This sources the file @var{filename}, and traps all errors. It also
+ignores all extraneous output. If there was an error it returns a 1,
+otherwise it returns a 0.
+
+@item prune @var{list} @var{pattern}
+@cindex list, pruning
+Remove elements of the Tcl list @var{list}. Elements are fields
+delimited by spaces. The result is a copy of @var{list}, without any
+elements that match @var{pattern}. You can use the common shell
+wildcard characters to specify @var{pattern}.
+
+@item setenv @var{var} @var{val}
+@cindex setting environment variables
+Sets the variable @var{var} to the value @var{val}.
+
+@item unsetenv @var{var}
+@cindex unsetting environment variables
+Unsets the environment variable @var{var}
+
+@item getenv @var{var}
+@cindex getting environment variables
+returns the value of @var{var} in the environment if it exists,
+otherwise it returns @code{NULL}.
+
+@item runtest_file_p @var{runtests} @var{testcase}
+@cindex selecting a range of tests
+@cindex tests, running specifically
+Search @var{runtests} for @var{testcase} and return 1 if found, 0 if not.
+@var{runtests} is a list of two elements. The first is the pathname of
+the testsuite expect script running. The second is a copy of what was
+on the right side of the @code{=} if @samp{foo.exp="@dots{}"} was specified,
+or an empty string if no such argument is present.
+This is used by tools like compilers where each testcase is a file.
+
+@item prune_system_crud @var{system} @var{text}
+@cindex pruning system output, examining program output
+For system @var{system}, delete text the host or target operating system might
+issue that will interfere with pattern matching of program output in
+@var{text}. An example is the message that is printed if a shared library
+is out of date.
+
+@end ftable
+
+@noindent
+@node target.exp, debugger.exp, utils.exp, DejaGnu Builtins
+@subsection Cross target procedure
+
+@kindex target.exp
+@kindex lib/target.exp
+@file{lib/target.exp} defines these utility procedures:
+
+@ftable @code
+
+@item push_target @emph{name}
+@cindex set current target
+This makes the target named @emph{name} be the current target
+connection. The value of @emph{name} is an index into the
+@code{target_info} array and is set in the global config file.
+
+@item pop_target
+@cindex unset current target
+This unsets the current target connection.
+
+@item list_targets
+@cindex lists supported targets
+This lists all the supported targets for this architecture.
+
+@item push_host @emph{name}
+@cindex set current host
+This makes the host named @emph{name} be the current remote host
+connection. The value of @emph{name} is an index into the
+@code{target_info} array and is set in the global config file.
+
+@item pop_host
+@cindex unset current host
+This unsets the current host connection.
+
+@c @item compile @emph{file}
+@cindex compile a file
+This invokes the compiler as set by @code{CC} to compile the file
+@emph{file}. The default options for many cross compilation targets are
+@emph{guessed} by DejaGnu, and these options can be added to by passing
+in more parameters as arguments to @code{compile}. Optionally, this will
+also use the value of the @code{cflags} field in the target config
+array. If the host is not the same as the build machines, then then
+compiler is run on the remote host using @code{execute_anywhere}.
+
+@c @item archive @emph{file}
+@cindex archive object files
+This produces an archive file. Any parameters passed to @code{archive}
+are used in addition to the default flags. Optionally, this will
+also use the value of the @code{arflags} field in the target config
+array. If the host is not the same as the build machines, then then
+archiver is run on the remote host using @code{execute_anywhere}.
+
+@c @item ranlib @emph{file}
+@cindex ranlib a file
+This generates an index for the archive file for systems that aren't
+POSIX yet. Any parameters passed to @code{ranlib} are used in for the
+flags.
+
+@item execute_anywhere @emph{cmdline}
+@cindex executing commands remotely
+This executes the @emph{cmdline} on the proper host. This should be used
+as a replacement for the Tcl command @code{exec} as this version
+utilizes the target config info to execute this command on the build
+machine or a remote host. All config information for the remote host
+must be setup to have this command work. If this is a canadian cross,
+(where we test a cross compiler that runs on a different host then where
+DejaGnu is running) then a connection is made to the remote host and
+the command is executed there. It returns either @emph{REMOTERROR} (for
+an error) or the output produced when the command was executed. This is
+used for running the tool to be tested, not a test case.
+
+@end ftable
+
+@node debugger.exp, , target.exp, DejaGnu Builtins
+@subsection Debugging Procedures
+
+@kindex debugger.exp
+@kindex lib/debugger.exp
+@file{lib/debugger.exp} defines these utility procedures:
+
+@ftable @code
+
+@item dumpvars @emph{expr}
+@cindex Print global variable values
+This takes a csh style regular expression (glob rules) and prints the
+values of the global variable names that match. It is abbreviated as
+@code{dv}
+
+@item dumplocals @emph{expr}
+@cindex Print local variable value
+This takes a csh style regular expression (glob rules) and prints the
+values of the local variable names that match. It is abbreviated as
+@code{dl}.
+
+@item dumprocs @emph{expr}
+@cindex Print procedure bodies
+This takes a csh style regular expression (glob rules) and prints the
+body of all procs that match. It is abbreviated as @code{dp}
+
+@item dumpwatch @emph{expr}
+@cindex Print watchpoints
+This takes a csh style regular expression (glob rules) and prints all
+the watchpoints. It is abbreviated as @code{dw}.
+
+@c FIXME: finish these when the code is fixed.
+@c @item watcharray @emph{element} @emph{type}
+@c @cindex Set a watchpoint on an array
+@c This sets an watchpoint of the @emph{element-type} on the
+@c @item watchvar v null type
+@c @cindex Set a watchpoint on a variable
+
+@item watchunset @emph{var}
+@cindex Watch when a variable is unset
+This breaks program execution when the variable @emph{var} is unset. It
+is abbreviated as @code{wu}.
+
+@item watchwrite @emph{var}
+@cindex Watch when a variable is written
+This breaks program execution when the variable @emph{var} is
+written. It is abbreviated as @code{ww}.
+
+@item watchread @emph{var}
+@cindex Watch when a variable is read
+This breaks program execution when the variable @emph{var} is read. It
+is abbreviated as @code{wr}.
+
+@item watchdel @emph{watch}
+@cindex Delete a watchpoint.
+This deletes a the watchpoint for @emph{watch}. It is abbreviated as
+@code{wd}.
+
+@item print @emph{var}
+@cindex Printing variable values
+This prints the value of the variable @emph{var}. It is abbreviated as
+@code{p}.
+
+@item quit
+@cindex Quiting DejaGnu
+This makes runtest exit. It is abbreviated as @code{q}.
+
+@item bt
+@cindex Print a backtrace
+This prints a backtrace of the executed Tcl commands.
+
+@end ftable
+
+@node Target Dependent
+@section Target dependent procedures
+@cindex target dependent procedures
+
+@c FIXME? These may be renamed to just "start", "load", "exit", and
+@c "version" eventually.
+
+Each combination of target and tool requires some target-dependent
+procedures. The names of these procedures have a common form: the tool
+name, followed by an underbar @samp{_}, and finally a suffix describing
+the procedure's purpose. For example, a procedure to extract the
+version from @sc{gdb} is called @samp{gdb_version}. @xref{Init Module,,
+Initialization Module}, for a discussion of how DejaGnu arranges to find
+the right procedures for each target.
+
+@code{runtest} itself calls only two of these procedures,
+@code{@var{tool}_exit} and @code{@var{tool}_version}; these procedures use
+no arguments.
+
+The other two procedures, @code{@var{tool}_start} and
+@code{@var{tool}_load}, are only called by the test suites themselves
+(or by testsuite-specific initialization code); they may take arguments
+or not, depending on the conventions used within each test suite.
+
+@ftable @code
+@item @var{tool}_start
+@cindex start procedure, tested tools
+Starts a particular tool. For an interactive tool,
+@code{@var{tool}_start} starts and initializes the tool, leaving the
+tool up and running for the test cases; an example is @code{gdb_start},
+the start function for @sc{gdb}. For a batch oriented tool,
+@code{@var{tool}_start} is optional; the recommended convention is to
+let @code{@var{tool}_start} run the tool, leaving the output in a
+variable called @code{comp_output}. Test scripts can then analyze
+@samp{$comp_output} to determine the test results. An example of this
+second kind of start function is @code{gcc_start}, the start function
+for @sc{gcc}.
+
+@code{runtest} itself @emph{does not call} @code{@var{tool}_start}. The
+initialization module @file{@var{tool}_init.exp} must call
+@code{@var{tool}_start} for interactive tools; for batch-oriented tools,
+each individual test script calls @code{@var{tool}_start} (or makes
+other arrangements to run the tool).
+
+@item @var{tool}_load
+@cindex load procedure, tested tools
+Loads something into a tool. For an interactive tool, this conditions
+the tool for a particular test case; for example, @code{gdb_load} loads
+a new executable file into the debugger. For batch oriented tools,
+@code{@var{tool}_load} may do nothing---though, for example, the
+@sc{gcc} support uses @code{gcc_load} to load and run a binary on the
+target environment. Conventionally, @code{@var{tool}_load} leaves the
+output of any program it runs in a variable called @samp{exec_output}.
+Writing @code{@var{tool}_load} can be the most complex part of extending
+DejaGnu to a new tool or a new target, if it requires much communication
+coding or file downloading.
+
+Test scripts call @code{@var{tool}_load}.
+
+@item @var{tool}_exit
+@cindex exit procedure, tested tools
+Cleans up (if necessary) before @code{runtest} exits. For interactive
+tools, this usually ends the interactive session. You can also use
+@code{@var{tool}_exit} to remove any temporary files left over from the
+tests.
+
+@code{runtest} calls @code{@var{tool}_exit}.
+
+@item @var{tool}_version
+@cindex version procedure, tested tools
+Prints the version label and number for @var{tool}. This is called by
+the DejaGnu procedure that prints the final summary report. The output
+should consist of the full path name used for the tested tool, and its
+version number.
+
+@code{runtest} calls @code{@var{tool}_version}.
+@end ftable
+
+The usual convention for return codes from any of these procedures
+(although it is not required by @code{runtest}) is to return @code{0} if
+the procedure succeeded, @code{1} if it failed, and @code{-1} if there
+was a communication error.
+
+@node Cross Targets
+@section Remote targets supported
+
+@cindex targets
+@cindex remote testing
+The DejaGnu distribution includes support for the following remote
+targets. You can set the target name and the connect mode in the
+@file{site.exp} file (using the Tcl variables @samp{targetname} and
+@samp{connectmode}, respectively), or on the @code{runtest} command line
+(using @samp{--name} and @samp{--connect}).
+
+@table @strong
+@item @sc{amd} 29000, with UDI protocol
+Configure DejaGnu for target @samp{a29k-amd-udi}. (Cygnus
+@code{configure} also recognizes the abbreviation @samp{udi29k}.) Then,
+to run tests, use the @code{runtest} target name to specify whether you
+want to use a simulator, or a particular hardware board. The particular
+string to use with @samp{--name} will depend on your UDI setup file,
+@file{udi_soc} (if @file{udi_soc} is not in your working directory, the
+environment variable @samp{UDICONF} should contain a path to this file).
+For example, if your UDI setup file includes these lines:
+@end table
+@c table "ends" *only* to allow wider example below
+
+@cartouche
+@smallexample
+iss AF_UNIX * isstip -r /home/gnu/29k/src/osboot/sim/osboot
+mon AF_UNIX * montip -t serial -baud 9600 -com /dev/ttyb
+@end smallexample
+@end cartouche
+
+@table @strong
+@item @w{ }
+@c fake out table/item into continuing w/same margin as before
+You can use @samp{--name iss} to run tests on the simulator, and
+@samp{--name mon} to run tests on the 29K hardware. See the
+manufacturer's manuals for more information on UDI and @file{udi_soc}.
+@c FIXME! Is there a better ref than "the manufacturer's manuals"?
+
+@kindex mondfe
+The default connect protocol is @samp{mondfe} with either back end.
+@code{mondfe} is the only shell DejaGnu supports for UDI targets.
+@code{mondfe} is an @sc{amd} specific monitor program freely available
+from @sc{amd}.
+
+@emph{Warning:} This target requires @sc{gdb} version 4.7.2 (or
+greater). Earlier versions of @sc{gdb} do not fully support the
+@code{load} command on this target, so DejaGnu has no way to load
+executable files from the debugger.
+
+@item Motorola 680x0 boards, a.out or @sc{coff} object format
+Configure DejaGnu for any remote target matching @samp{m68k-*}.
+
+@emph{Warning:} Most @samp{m68k-*} configurations run all tests only for
+native testing (when the target is the same as the host). When you
+specify most of these targets for a cross configuration, you will only be
+able to use tests that run completely within the host (for example,
+tests of the binary utilities such as the archiver; or compiler tests
+that only generate code rather than running it).
+
+To run a.out or @sc{coff} binaries on a remote M68K, you must configure
+DejaGnu for a particular target board. @samp{m68k-abug} is an example.
+(In general for an embedded environment, because it does not have absolute
+addresses, a.out is not a good choice for output format in any case; most
+often S-records or Hex-32 are used instead.)
+
+@item Motorola 68K MVME 135 board running ABug boot monitor
+Configure for @samp{m68k-abug-aout} or @samp{m68k-abug-coff} (as a
+target). This boot monitor can only download S-records; therefore, the
+DejaGnu tests for this environment require a linker command script to
+convert either output format to S-records, setting the default addresses
+for @code{.text}, @code{.bss}, and @code{.data}.
+
+With this configuration, the default for @samp{--connect} is @samp{tip}.
+@samp{tip} is the only communications protocol supported for connecting
+to @samp{m68k-abug-*} targets. @samp{tip} uses an @sc{ascii} downloader
+(the @code{~put} command) to load S-records into the target board. The
+@samp{--name} string must be a machine name that @code{tip}
+understands (for example, on some @code{tip} implementations it must be
+an entry from the initialization file for @code{tip}; this file is
+sometimes called @file{/etc/remote}).
+
+See your system documentation for information on how to create new
+entries in @file{/etc/remote}. (Some @sc{unix} systems are distributed
+with at least one default entry with a name resembling @samp{hardwire};
+if your system has one, you can edit it, or make a modified copy with a
+new name.) When you have a working @file{/etc/remote} entry
+@var{abugtarget}, you should be able to type @samp{tip
+@var{abugtarget}}, and get the prompt @samp{135ABUG>} from the board.
+Use the same @var{abugtarget} string with @samp{runtest --name}.
+
+@item Motorola IDP board running the rom68k boot monitor
+@c FIXME 1: this doesn't really say anything! OK, so functionality is
+@c the same. Is object code the same (srecords)? Do we configure with
+@c the same triplets? What is the default for --connect? Is
+@c any comms method other than tip supported? What prompt to expect
+@c when tip connected?
+@c FIXME 2: should @code{BUG} below be @code{ABUG}?
+This is the same in functionality as the MVME board running the
+@code{BUG} boot monitor. Only the monitor commands and the addresses are
+different.
+
+@item VxWorks (Motorola 68K or Intel 960)
+Configure DejaGnu for either @samp{m68k-wrs-vxworks} (abbreviated
+@samp{vxworks68}) or @samp{i960-wrs-vxworks} (abbreviated
+@samp{vxworks960}). Since both targets support IP addressing, specify
+the network address (for example, a host name from @file{/etc/hosts})
+with @samp{--name}.
+
+The default connect protocol is @samp{rlogin}, but you can use any of
+@samp{--connect rlogin}, @samp{--connect telnet}, or @samp{--connect
+rsh}.
+
+Test scripts need no special code to load programs into these targets;
+since VxWorks supports NFS, all you must do is ensure test programs are
+on an exported filesystem.
+
+@cindex VxWorks, link with @samp{-r}
+When you compile for VxWorks, use the linker @samp{-r} option to make
+the linker output relocatable---at least if you want to use library
+routines. Many standard C routines are included in VxWorks; often no
+additional libraries are needed. See your VxWorks system documentation
+for additional details.
+@end table
+
+@node Input Files
+@section The files DejaGnu reads
+@cindex input files
+
+The @code{runtest} program used to invoke DejaGnu is a short shell
+script generated by @code{make} during the configuration process. Its
+main task is to read the main test framework driver, @file{runtest.exp}.
+
+@file{runtest.exp}, in turn, reads @code{expect} code from certain other
+files, in this order:
+
+@enumerate
+@item
+Each of the @file{site.exp} local definition files available.
+@xref{Customizing,,Setting @code{runtest} defaults}, for details.
+
+@item
+@file{lib/utils.exp}, a collection of utility procedures. @xref{DejaGnu
+Builtins,,DejaGnu Builtins}, for descriptions of these procedures.
+
+@item
+@file{lib/framework.exp}, a file of subroutines meant for @code{runtest}
+itself rather than for general-purpose use in both @code{runtest} and
+test suites.
+
+@item
+@file{debugger.exp}, Don Libes' Tcl Debugger. (See @cite{A Debugger for
+Tcl Applications} by Don Libes. This paper is distributed with
+@code{expect} in PostScript form as the file
+@file{expect/tcl-debug.ps}.)
+
+@item
+@file{lib/remote.exp}, a collection of subroutines meant for connecting
+to remote machines.
+
+@item
+@file{lib/target.exp}, a collection of subroutines used for the
+configuration systems in DejaGnu. These procedures typically manipulate
+or utilize the configuration system.
+
+@item
+@c FIXME! A comment in runtest.exp claims a system default is used if
+@c no tool-specific init file is not available; I couldn't see where
+@c the program flow actually does this, though---pesch 30jul1993.
+An initialization file @code{@var{tool}_init.exp}. @xref{Init
+Module,,Initialization module}, for more discussion of init files.
+@end enumerate
+
+@c This hard page break is mainly intended for smallbook formatting;
+@c some examples in this section come out better if this starts at a
+@c page boundary.
+@page
+@node Output Files
+@section The files DejaGnu writes
+@cindex output files
+
+@code{runtest} always writes two kinds of output files: summary logs and
+detailed logs. The contents of both of these are determined by your
+tests.
+
+For troubleshooting, a third kind of output file is useful: use
+@samp{--debug} to request an output file showing details of what
+@code{expect} is doing internally.
+
+@menu
+* Summary:: Files that summarize tests
+* Detail:: Files that contain complete test results
+* Debug:: Logging expect internal actions
+@end menu
+
+@node Summary
+@subsection Summary log
+@cindex summary log
+
+@code{runtest} always produces a summary output file
+@file{@var{tool}.sum}. This summary shows the names of all test files
+run; for each test file, one line of output from each @code{pass}
+command (showing status @samp{PASS} or @samp{XPASS}) or @code{fail}
+command (status @samp{FAIL} or @samp{XFAIL}); trailing summary
+statistics that count passing and failing tests (expected and
+unexpected); and the full pathname and version number of the tool
+tested. (All possible outcomes, and all errors, are always reflected in
+the summary output file, regardless of whether or not you specify
+@samp{--all}.)
+
+If any of your tests use the procedures @code{unresolved},
+@code{unsupported}, or @code{untested}, the summary output also
+tabulates the corresponding outcomes.
+
+For example, after @samp{runtest --tool binutils}, look for a summary
+log in @file{binutils.sum}. Normally, @code{runtest} writes this file
+in your current working directory; use the @samp{--outdir} option to
+select a different directory.
+
+@need 3500
+@noindent
+Here is a short sample summary log:
+
+@cartouche
+@smallexample
+Test Run By rob on Mon May 25 21:40:57 PDT 1992
+ === gdb tests ===
+Running ./gdb.t00/echo.exp ...
+PASS: Echo test
+Running ./gdb.all/help.exp ...
+PASS: help add-symbol-file
+PASS: help aliases
+PASS: help breakpoint "bre" abbreviation
+FAIL: help run "r" abbreviation
+Running ./gdb.t10/crossload.exp ...
+PASS: m68k-elf (elf-big) explicit format; loaded
+XFAIL: mips-ecoff (ecoff-bigmips) "ptype v_signed_char" signed
+C types
+ === gdb Summary ===
+# of expected passes 5
+# of expected failures 1
+# of unexpected failures 1
+/usr/latest/bin/gdb version 4.6.5 -q
+@end smallexample
+@end cartouche
+
+@node Detail
+@subsection Detailed log
+@cindex detailed log
+
+@code{runtest} also saves a detailed log file @file{@var{tool}.log},
+showing any output generated by tests as well as the summary output.
+For example, after @samp{runtest --tool binutils}, look for a detailed
+log in @file{binutils.log}. Normally, @code{runtest} writes this file
+in your current working directory; use the @samp{--outdir} option to
+select a different directory.
+
+@need 4000
+@noindent
+Here is a brief example showing a detailed log for @sc{g++} tests:
+
+@cartouche
+@smallexample
+Test Run By rob on Mon May 25 21:40:43 PDT 1992
+
+ === g++ tests ===
+
+--- Running ./g++.other/t01-1.exp ---
+ PASS: operate delete
+
+--- Running ./g++.other/t01-2.exp ---
+ FAIL: i960 bug EOF
+p0000646.C: In function `int warn_return_1 ()':
+p0000646.C:109: warning: control reaches end of non-void function
+p0000646.C: In function `int warn_return_arg (int)':
+p0000646.C:117: warning: control reaches end of non-void function
+p0000646.C: In function `int warn_return_sum (int, int)':
+p0000646.C:125: warning: control reaches end of non-void function
+p0000646.C: In function `struct foo warn_return_foo ()':
+p0000646.C:132: warning: control reaches end of non-void function
+
+--- Running ./g++.other/t01-4.exp ---
+ FAIL: abort
+900403_04.C:8: zero width for bit-field `foo'
+--- Running ./g++.other/t01-3.exp ---
+ FAIL: segment violation
+900519_12.C:9: parse error before `;'
+900519_12.C:12: Segmentation violation
+/usr/latest/bin/gcc: Internal compiler error: program cc1plus got
+fatal signal
+
+ === g++ Summary ===
+
+# of expected passes 1
+# of expected failures 3
+/usr/ps/bin/g++ version cygnus-2.0.1
+@end smallexample
+@end cartouche
+
+@node Debug
+@subsection Logging @code{expect} internal actions
+@cindex debug log
+
+With the @samp{--debug} option, you can request a log file showing the
+output from @code{expect} itself, running in debugging mode. This file
+(@file{dbg.log}, in the directory where you start @code{runtest}) shows
+each pattern @code{expect} considers in analyzing test output.
+
+This file reflects each @code{send} command, showing the string sent as
+input to the tool under test; and each @code{expect} command, showing
+each pattern it compares with the tool output.
+
+The log messages for @code{expect} begin with a message of the form
+
+@smallexample
+expect: does @{@var{tool output}@} (spawn_id @var{n}) match pattern
+@{@var{expected pattern}@}?
+@end smallexample
+
+@noindent
+For every unsuccessful match, @code{expect} issues a @samp{no} after
+this message; if other patterns are specified for the same
+@code{expect} command, they are reflected also, but without the first
+part of the message (@samp{expect@dots{}match pattern}).
+
+When @code{expect} finds a match, the log for the successful match ends
+with @samp{yes}, followed by a record of the @code{expect} variables set
+to describe a successful match. Here is an excerpt from the debugging
+log for a @sc{gdb} test:
+
+@c FIXME! Why is the second spawn_id shown 0 rather than 6?
+@cartouche
+@smallexample
+send: sent @{break gdbme.c:34\n@} to spawn id 6
+expect: does @{@} (spawn_id 6) match pattern @{Breakpoint.*at.* file
+ gdbme.c, line 34.*\(gdb\) $@}? no
+@{.*\(gdb\) $@}? no
+expect: does @{@} (spawn_id 0) match pattern @{<return>@}? no
+@{\(y or n\) @}? no
+@{buffer_full@}? no
+@{virtual@}? no
+@{memory@}? no
+@{exhausted@}? no
+@{Undefined@}? no
+@{command@}? no
+break gdbme.c:34
+Breakpoint 8 at 0x23d8: file gdbme.c, line 34.
+(gdb) expect: does @{break gdbme.c:34\r\nBreakpoint 8 at 0x23d8:
+file gdbme.c, line 34.\r\n(gdb) @} (spawn_id 6) match pattern
+@{Breakpoint.*at.* file gdbme.c, line 34.*\(gdb\) $@}? yes
+expect: set expect_out(0,start) @{18@}
+expect: set expect_out(0,end) @{71@}
+expect: set expect_out(0,string) @{Breakpoint 8 at 0x23d8: file
+gdbme.c, line 34.\r\n(gdb) @}
+expect: set expect_out(spawn_id) @{6@}
+expect: set expect_out(buffer) @{break gdbme.c:34\r\nBreakpoint 8
+at 0x23d8: file gdbme.c, line 34.\r\n(gdb) @}
+ PASS: 70 0 breakpoint line number in file
+@end smallexample
+@end cartouche
+
+@noindent
+This example exhibits three properties of @code{expect} and DejaGnu that
+might be surprising at first glance:
+
+@itemize @bullet
+@item
+Empty output for the first attempted match. The first set of attempted
+matches shown ran against the output @samp{@{@}}---that is, no output.
+@code{expect} begins attempting to match the patterns supplied
+immediately; often, the first pass is against incomplete output (or
+completely before all output, as in this case).
+
+@item
+Interspersed tool output. The beginning of the log entry for the second
+attempted match may be hard to spot: this is because the prompt
+@samp{(gdb) } appears on the same line, just before the @samp{expect:}
+that marks the beginning of the log entry.
+
+@item
+Fail-safe patterns. Many of the patterns tested are fail-safe patterns
+provided by @sc{gdb} testing utilities, to reduce possible
+indeterminacy. It is useful to anticipate potential variations
+caused by extreme system conditions (@sc{gdb} might issue the message
+@samp{virtual memory exhausted} in rare circumstances), or by changes in
+the tested program (@samp{Undefined command} is the likeliest outcome if
+the name of a tested command changes).
+
+The pattern @samp{@{<return>@}} is a particularly interesting fail-safe
+to notice; it checks for an unexpected @key{RET} prompt. This may
+happen, for example, if the tested tool can filter output through a
+pager.
+
+These fail-safe patterns (like the debugging log itself) are primarily
+useful while developing test scripts. Use the @code{error} procedure to
+make the actions for fail-safe patterns produce messages starting with
+@samp{ERROR} on the @code{runtest} standard output, and in the detailed
+log file.
+@end itemize
+
+@node Tests
+@chapter How To Write a Test Cases
+@cindex writing a test case
+@cindex test case, writing
+
+@menu
+* Writing:: Writing a test case
+* Debugging:: Debugging a test case
+* Adding:: Adding a test case to a test suite
+* Hints:: Hints on writing a test case
+* Variables:: Special variables used by test cases
+@end menu
+
+@node Writing
+@section Writing a test case
+
+The easiest way to prepare a new test case is to base it on an existing
+one for a similar situation. There are two major categories of tests:
+batch or interactive. Batch oriented tests are usually easier to write.
+
+The @sc{gcc} tests are a good example of batch oriented tests. All
+@sc{gcc} tests consist primarily of a call to a single common procedure,
+since all the tests either have no output, or only have a few warning
+messages when successfully compiled. Any non-warning output is a test
+failure. All the C code needed is kept in the test directory. The test
+driver, written in @code{expect}, need only get a listing of all the C
+files in the directory, and compile them all using a generic procedure.
+This procedure and a few others supporting for these tests are kept in
+the library module @file{lib/c-torture.exp} in the @sc{gcc} test suite.
+Most tests of this kind use very few @code{expect} features, and are
+coded almost purely in Tcl.
+
+@noindent
+Writing the complete suite of C tests, then, consisted of these steps:
+
+@enumerate
+@item
+@cindex Granlund, Torbjorn
+@cindex C torture test
+Copying all the C code into the test directory. These tests were based on
+the C-torture test created by Torbjorn Granlund (on behalf of the Free
+Software Foundation) for @sc{gcc} development.
+
+@item
+Writing (and debugging) the generic @code{expect} procedures for
+compilation.
+
+@item
+Writing the simple test driver: its main task is to search the directory
+(using the Tcl procedure @code{glob} for filename expansion with
+wildcards) and call a Tcl procedure with each filename. It also checks
+for a few errors from the testing procedure.
+@end enumerate
+
+Testing interactive programs is intrinsically more complex. Tests for most
+interactive programs require some trial and error before they are complete.
+
+However, some interactive programs can be tested in a simple fashion
+reminiscent of batch tests. For example, prior to the creation of
+DejaGnu, the @sc{gdb} distribution already included a wide-ranging
+testing procedure. This procedure was very robust, and had already
+undergone much more debugging and error checking than many recent
+DejaGnu test cases. Accordingly, the best approach was simply to
+encapsulate the existing @sc{gdb} tests, for reporting purposes.
+Thereafter, new @sc{gdb} tests built up a family of @code{expect}
+procedures specialized for @sc{gdb} testing.
+
+@file{gdb.t10/crossload.exp} is a good example of an interactive test.
+@c FIXME! Check what *kind* of example it is---work-intensive, or generic...
+
+@node Debugging
+@section Debugging a test case
+@cindex debugging a test case
+@cindex test case, debugging
+
+@noindent
+These are the kinds of debugging information available from DejaGnu:
+
+@enumerate
+@item
+Output controlled by test scripts themselves, explicitly allowed for by
+the test author. This kind of debugging output appears in the detailed
+output recorded in the @file{@var{tool}.log} file. To do the same for
+new tests, use the @code{verbose} procedure (which in turn uses the
+variable also called @code{verbose}) to control how much output to
+generate. This will make it easier for other people running the test to
+debug it if necessary. Whenever possible, if @samp{$verbose} is
+@code{0}, there should be no output other than the output from
+@code{pass}, @code{fail}, @code{error}, and @code{warning}. Then, to
+whatever extent is appropriate for the particular test, allow
+successively higher values of @samp{$verbose} to generate more
+information. Be kind to other programmers who use your tests: provide
+for a lot of debugging information.
+
+@item
+Output from the internal debugging functions of Tcl and @code{expect}.
+There is a command line options for each; both forms of debugging output
+are recorded in the file @code{dbg.log} in the current directory.
+
+Use @samp{--debug} for information from the @code{expect} level; it
+generates displays of the @code{expect} attempts to match the tool
+output with the patterns specified (@pxref{Debug,,Debug Log}). This
+output can be very helpful while developing test scripts, since it shows
+precisely the characters received. Iterating between the latest attempt
+at a new test script and the corresponding @file{dbg.log} can allow you
+to create the final patterns by ``cut and paste''. This is sometimes
+the best way to write a test case.
+
+Use @samp{--strace} to see more detail at the Tcl level; this shows how Tcl
+procedure definitions expand, as they execute. The associated number
+controls the depth of definitions expanded; see the discussion of
+@samp{--strace} in @ref{Invoking runtest,,Running the Tests}.
+
+@item
+Finally, if the value of @samp{verbose} is 3 or greater, @code{runtest}
+turns on the @code{expect} command @code{log_user}. This command prints
+all @code{expect} actions to the @code{expect} standard output, to the
+detailed log file, and (if @samp{--debug} is on) to @file{dbg.log}.
+@end enumerate
+
+@node Adding
+@section Adding a test case to a test suite
+@cindex adding a test case
+
+There are two slightly different ways to add a test case. One is to add
+the test case to an existing directory. The other is to create a new
+directory to hold your test. The existing test directories represent
+several styles of testing, all of which are slightly different; examine
+the directories for the tool of interest to see which (if any) is most
+suitable.
+
+Adding a @sc{gcc} test can be very simple: just add the C code to any
+directory beginning with @samp{gcc.} and it runs on the next
+@samp{runtest --tool gcc}.
+
+To add a test to @sc{gdb}, first add any source code you will need to
+the test directory. Then you can either create a new @code{expect} file,
+or add your test to an existing one (any file with a @samp{.exp}
+suffix). Creating a new @samp{.exp} file is probably a better idea if
+the test is significantly different from existing tests. Adding it as a
+separate file also makes upgrading easier. If the C code has to be
+already compiled before the test will run, then you'll have to add it to
+the @file{Makefile.in} file for that test directory, then run
+@code{configure} and @code{make}.
+
+Adding a test by creating a new directory is very similar:
+
+@enumerate
+@item
+Create the new directory. All subdirectory names begin with the name of
+the tool to test; e.g. @sc{g++} tests might be in a directory called
+@file{g++.other}. There can be multiple test directories that start with
+the same tool name (such as @samp{g++}).
+
+@item
+Add the new directory name to the @samp{configdirs} definition in the
+@file{configure.in} file for the test suite directory. This way when
+@code{make} and @code{configure} next run, they include the new directory.
+
+@item
+Add the new test case to the directory, as above.
+
+@item
+To add support in the new directory for configure and make, you must
+also create a @code{Makefile.in} and a @code{configure.in}. @xref{What
+Configure Does,,What Configure Does, configure.info, Cygnus Configure}.
+@end enumerate
+
+@c FIXME! Expand this sentence to at least a section, maybe a chapter...
+@c The @file{admin} directory contains templates for a few common forms
+@c of test.
+
+@node Hints
+@section Hints on writing a test case
+@cindex hints on test case writing
+
+There may be useful existing procedures already written for your test in
+the @file{lib} directory of the DejaGnu distribution. @xref{DejaGnu
+Builtins,,DejaGnu Builtins}.
+
+It is safest to write patterns that match @emph{all} the output
+generated by the tested program; this is called @dfn{closure}. If a
+pattern does not match the entire output, any output that remains will
+be examined by the @emph{next} @code{expect} command. In this
+situation, the precise boundary that determines which @code{expect}
+command sees what is very sensitive to timing between the @code{expect}
+task and the task running the tested tool. As a result, the test may
+sometimes appear to work, but is likely to have unpredictable results.
+(This problem is particularly likely for interactive tools, but can also
+affect batch tools---especially for tests that take a long time to finish.)
+The best way to ensure closure is to use the @samp{-re} option for the
+@code{expect} command to write the pattern as a full regular
+expressions; then you can match the end of output using a @samp{$}. It
+is also a good idea to write patterns that match all available output by
+using @samp{.*\} after the text of interest; this will also match any
+intervening blank lines. Sometimes an alternative is to match end of
+line using @samp{\r} or @samp{\n}, but this is usually too dependent on
+terminal settings.
+@c FIXME!! explain what "end of output" means for interactive task.
+@c (Timeout or EOF, right?)
+
+Always escape punctuation, such as @samp{(} or @samp{"}, in your
+patterns; for example, write @samp{\(}. If you forget to escape
+punctuation, you will usually see an error message like @samp{extra
+characters after close-quote}.
+
+If you have trouble understanding why a pattern does not match the
+program output, try using the @samp{--debug} option to @code{runtest},
+and examine the debug log carefully. @xref{Debug,,Debug Log}.
+
+Be careful not to neglect output generated by setup rather than by the
+interesting parts of a test case. For example, while testing @sc{gdb},
+I issue a send @samp{set height 0\n} command. The purpose is simply to
+make sure @sc{gdb} never calls a paging program. The @samp{set height}
+command in @sc{gdb} does not generate any output; but running @emph{any}
+command makes @sc{gdb} issue a new @samp{(gdb) } prompt. If there were
+no @code{expect} command to match this prompt, the output @samp{(gdb) }
+begins the text seen by the next @code{expect} command---which might
+make @emph{that} pattern fail to match.
+
+To preserve basic sanity, I also recommended that no test ever pass if
+there was any kind of problem in the test case. To take an extreme
+case, tests that pass even when the tool will not spawn are misleading.
+Ideally, a test in this sort of situation should not fail either.
+Instead, print an error message by calling one of the DejaGnu procedures
+@code{error} or @code{warning}.
+
+@node Variables
+@section Special variables used by test cases
+@cindex special variables
+
+@cindex variables for all tests
+Your test cases can use these variables, with conventional meanings (as
+well as the variables saved in @file{site.exp}
+@pxref{Customizing,,Setting @code{runtest} defaults}):
+
+@quotation
+@emph{These variables are available to all test cases.}
+@end quotation
+
+@ftable @code
+@item prms_id
+@cindex PRMS bug number
+@cindex GNATS bug number
+@cindex bug number
+The tracking system (e.g. @sc{gnats}) number identifying a corresponding
+bugreport. (@samp{0} if you do not specify it in the test script.)
+
+@item bug_id
+@cindex bug number, extra
+An optional bug id; may reflect a bug identification from another
+organization. (@samp{0} if you do not specify it.)
+
+@item subdir
+@cindex current test subdirectory
+The subdirectory for the current test case.
+@end ftable
+
+@quotation
+@emph{These variables should never be changed. They appear in most
+tests.}
+@end quotation
+
+@ftable @code
+@item expect_out(buffer)
+@cindex last command output
+The output from the last command. This is an internal variable set by
+@code{expect}.
+
+@item exec_output
+This is the output from a @code{@var{tool}_load} command. This only
+applies to tools like @sc{gcc} and @sc{gas} which produce an object
+file that must in turn be executed to complete a test.
+
+@item comp_output
+This is the output from a @code{@var{tool}_start} command. This is
+conventionally used for batch oriented programs, like @sc{gcc} and
+@sc{gas}, that may produce interesting output (warnings, errors) without
+further interaction.
+@end ftable
+
+@node Extending
+@chapter New Tools, Targets, or Hosts
+
+The most common ways to extend the DejaGnu framework are: adding a suite
+of tests for a new tool to be tested; adding support for testing on a
+new target; and porting @code{runtest} to a new host.
+
+@menu
+* Adding Tools:: How to add tests for a new tool
+* Adding Targets:: How to add a new target
+* Porting:: Porting DejaGnu to a new host
+@end menu
+
+@node Adding Tools
+@section Writing tests for a new tool
+
+In general, the best way to learn how to write (code or even prose) is
+to read something similar. This principle applies to test cases and to
+test suites. Unfortunately, well-established test suites have a way of
+developing their own conventions: as test writers become more
+experienced with DejaGnu and with Tcl, they accumulate more utilities,
+and take advantage of more and more features of @code{expect} and Tcl in
+general.
+
+Inspecting such established test suites may make the prospect of
+creating an entirely new test suite appear overwhelming. Nevertheless,
+it is quite straightforward to get a new test suite going.
+
+@cindex Lupton, Robert
+There is one test suite that is guaranteed not to grow more elaborate
+over time: both it and the tool it tests were created expressly to
+illustrate what it takes to get started with DejaGnu. The
+@file{example/} directory of the DejaGnu distribution contains both an
+interactive tool called @code{calc}, and a test suite for it. Reading
+this test suite, and experimenting with it, is a good way to supplement
+the information in this section. (Thanks to Robert Lupton for creating
+@code{calc} and its test suite---and also the first version of this
+section of the manual!)
+
+To help orient you further in this task, here is an outline of the steps
+to begin building a test suite for a program @var{example}.
+
+@enumerate
+@item
+Create or select a directory to contain your new collection of tests.
+Change to that directory (shown here as @code{testsuite}):
+
+@example
+eg$ cd testsuite/
+@end example
+
+@item
+Create a @file{configure.in} file in this directory, to control
+configuration-dependent choices for your tests. So far as DejaGnu is
+concerned, the important thing is to set a value for the variable
+@code{target_abbrev}; this value is the link to the init file you will
+write soon. (For simplicity, we assume the environment is Unix, and use
+@samp{unix} as the value.)
+
+What else is needed in @file{configure.in} depends on the requirements
+of your tool, your intended test environments, and which
+@code{configure} system you use. This example is a minimal
+@code{configure.in} for use with Cygnus Configure. (For an alternative
+based on the FSF @code{autoconf} system, see the @code{calc} example
+distributed with DejaGnu.) Replace @var{example} with the name of your
+program:
+
+@cartouche
+@smallexample
+# This file is a shell script fragment
+# for use with Cygnus configure.
+
+srctrigger="@var{example}.0"
+srcname="The DejaGnu @var{example} tests"
+
+# per-host:
+
+# per-target:
+
+# everything defaults to unix for a target
+target_abbrev=unix
+
+# post-target:
+
+@end smallexample
+@end cartouche
+
+@item
+Create @file{Makefile.in}, the source file used by @code{configure} to
+build your @file{Makefile}. Its leading section should as usual contain
+the values that @code{configure} may override:
+
+@cartouche
+@smallexample
+srcdir = .
+prefix = /usr/local
+
+exec_prefix = $(prefix)
+bindir = $(exec_prefix)/bin
+libdir = $(exec_prefix)/lib
+tooldir = $(libdir)/$(target_alias)
+
+datadir = $(exec_prefix)/lib/dejagnu
+
+RUNTEST = runtest
+RUNTESTFLAGS =
+FLAGS_TO_PASS =
+
+#### host, target, site specific Makefile frags come in here.
+@end smallexample
+@end cartouche
+
+This should be followed by the standard targets at your site. To begin
+with, they need not do anything---for example, these definitions will
+do:
+
+@cartouche
+@smallexample
+
+all:
+
+info:
+
+install-info:
+
+install:
+uninstall:
+
+clean:
+ -rm -f *~ core *.info*
+
+@end smallexample
+@end cartouche
+
+It is also a good idea to make sure your @file{Makefile} can rebuild
+itself if @file{Makefile.in} changes, with a target like this (which
+works for either Cygnus or FSF Configure):
+
+@cartouche
+@smallexample
+Makefile : $(srcdir)/Makefile.in $(host_makefile_frag) \
+ $(target_makefile_frag)
+ $(SHELL) ./config.status
+@end smallexample
+@end cartouche
+
+You also need to include two targets important to DejaGnu: @code{check},
+to run the tests, and @code{site.exp}, to set up the Tcl copies of
+configuration-dependent values. The @code{check} target must run
+@samp{runtest --tool @var{example}}:
+
+@cartouche
+@smallexample
+check: site.exp all
+ $(RUNTEST) $(RUNTESTFLAGS) $(FLAGS_TO_PASS) \
+ --tool @var{example} --srcdir $(srcdir)
+@end smallexample
+@end cartouche
+
+The @code{site.exp} target should usually set up (among other things!) a
+Tcl variable for the name of your program:
+
+@cartouche
+@smallexample
+site.exp: ./config.status Makefile
+ @@echo "Making a new config file..."
+ -@@rm -f ./tmp?
+ @@touch site.exp
+
+ -@@mv site.exp site.bak
+ @@echo "## these variables are automatically\
+ generated by make ##" > ./tmp0
+ @@echo "# Do not edit here. If you wish to\
+ override these values" >> ./tmp0
+ @@echo "# add them to the last section" >> ./tmp0
+ @@echo "set host_os $@{host_os@}" >> ./tmp0
+ @@echo "set host_alias $@{host_alias@}" >> ./tmp0
+ @@echo "set host_cpu $@{host_cpu@}" >> ./tmp0
+ @@echo "set host_vendor $@{host_vendor@}" >> ./tmp0
+ @@echo "set target_os $@{target_os@}" >> ./tmp0
+ @@echo "set target_alias $@{target_alias@}" >> ./tmp0
+ @@echo "set target_cpu $@{target_cpu@}" >> ./tmp0
+ @@echo "set target_vendor $@{target_vendor@}" >> ./tmp0
+ @@echo "set host_triplet $@{host_canonical@}" >> ./tmp0
+ @@echo "set target_triplet $@{target_canonical@}">>./tmp0
+ @@echo "set tool binutils" >> ./tmp0
+ @@echo "set srcdir $@{srcdir@}" >> ./tmp0
+ @@echo "set objdir `pwd`" >> ./tmp0
+ @@echo "set @var{examplename} @var{example}" >> ./tmp0
+ @@echo "## All variables above are generated by\
+ configure. Do Not Edit ##" >> ./tmp0
+ @@cat ./tmp0 > site.exp
+ @@sed < site.bak \
+ -e '1,/^## All variables above are.*##/ d' \
+ >> site.exp
+ -@@rm -f ./tmp?
+@end smallexample
+@end cartouche
+
+@item
+Create a directory (in @file{testsuite/}) called @file{config/}:
+
+@example
+eg$ mkdir config
+@end example
+
+@item
+Make an init file in this directory; its name must start with the
+@code{target_abbrev} value, so call it @file{config/unix.exp}.
+This is the file that contains the target-dependent procedures;
+fortunately, most of them do not have to do very much in order for
+@code{runtest} to run.
+
+If @var{example} is not interactive, you can get away with this minimal
+@file{unix.exp} to begin with:
+
+@cartouche
+@smallexample
+proc foo_exit @{@} @{@}
+proc foo_version @{@} @{@}
+@end smallexample
+@end cartouche
+
+If @var{example} is interactive, however, you might as well define a
+start routine @emph{and invoke it} by using an init file like this:
+
+@cartouche
+@smallexample
+proc foo_exit @{@} @{@}
+proc foo_version @{@} @{@}
+
+proc foo_start @{@} @{
+ global @var{examplename}
+ spawn $@var{examplename}
+ expect @{
+ -re "" @{@}
+ @}
+@}
+foo_start
+@end smallexample
+@end cartouche
+
+@item
+Create a directory whose name begins with your tool's name, to contain
+tests:
+
+@example
+eg$ mkdir @var{example}.0
+@end example
+
+@item
+Create a sample test file in @file{@var{example}.0}. Its name must end
+with @samp{.exp}; you can use @samp{first-try.exp} To begin with, just
+write there a line of Tcl code to issue a message:
+
+@cartouche
+@smallexample
+send_user "Testing: one, two...\n"
+@end smallexample
+@end cartouche
+
+@item
+Back in the @file{testsuite/} (top level) directory, run
+
+@example
+eg$ configure
+@end example
+
+(You may have to specify more of a path, if a suitable @code{configure}
+is not available in your execution path.)
+
+@item
+You are now ready to triumphantly type @samp{make check} or
+@samp{runtest --tool @var{example}}. You should see something like this:
+
+@cartouche
+@smallexample
+Test Run By rhl on Fri Jan 29 16:25:44 EST 1993
+
+ === @var{example} tests ===
+
+Running ./@var{example}.0/first-try.exp ...
+Testing: one, two...
+
+ === @var{example} Summary ===
+
+@end smallexample
+@end cartouche
+
+There is no output in the summary, because so far the example does not
+call any of the procedures that establish a test outcome.
+
+@item
+Begin writing some real tests. For an interactive tool, you should
+probably write a real exit routine in fairly short order; in any case,
+you should also write a real version routine soon.
+@end enumerate
+
+@node Adding Targets
+@section Adding a target
+@cindex adding a target
+
+DejaGnu has some additional requirements for target support, beyond the
+general-purpose provisions of Cygnus @code{configure}. @code{runtest}
+must actively communicate with the target, rather than simply generating
+or managing code for the target architecture. Therefore, each tool
+requires an initialization module for each target. For new targets, you
+must supply a few Tcl procedures to adapt DejaGnu to the target. This
+permits DejaGnu itself to remain target independent. @xref{Init
+Module,,Initialization module}, for a discussion of the naming
+conventions that enable DejaGnu to locate and use init files.
+
+Usually the best way to write a new initialization module is to edit an
+existing initialization module; some trial and error will be required.
+If necessary, you can use the @samp{--debug} option to see what
+is really going on.
+
+When you code an initialization module, be generous in printing
+information controlled by the @code{verbose} procedure (@pxref{DejaGnu
+Builtins, DejaGnu procedures}).
+
+Most of the work is in getting the communications right. Communications
+code (for several situations involving IP networks or serial lines) is
+available in a DejaGnu library file, @file{lib/remote.exp}.
+@xref{DejaGnu Builtins,,DejaGnu Builtins}.
+
+@c FIXME! Say something about Tcl debugger here.
+If you suspect a communication problem, try running the connection
+interactively from @code{expect}. (There are three ways of running
+@code{expect} as an interactive interpreter. You can run @code{expect}
+with no arguments, and control it completely interactively; or you can
+use @samp{expect -i} together with other command-line options and
+arguments; or you can run the command @code{interpreter} from any
+@code{expect} procedure. Use @code{return} to get back to the calling
+procedure (if any), or @code{return -tcl} to make the calling procedure
+itself return to its caller; use @code{exit} or end-of-file to leave
+@code{expect} altogether.) Run the program whose name is recorded in
+@samp{$connectmode}, with the arguments in @samp{$targetname}, to
+establish a connection. You should at least be able to get a prompt
+from any target that is physically connected.
+
+@node Porting
+@section Porting to a new host
+@cindex porting to a new host
+
+The task of porting DejaGnu is basically that of porting Tcl and
+@code{expect}. Tcl and @code{expect}, as distributed with DejaGnu, both
+use @code{autoconf}; they should port automatically to most Unix
+systems.
+
+Once Tcl and @code{expect} are ported, DejaGnu should run. Most system
+dependencies are taken care of by using @code{expect} as the main
+command shell.
+
+@node Installation
+@appendix Installing DejaGnu
+
+@cindex host, explained
+@cindex target, explained
+@cindex DejaGnu configuration
+@cindex configuring DejaGnu
+Once you have the DejaGnu source unpacked and available, you must first
+configure the software to specify where it is to run (and the associated
+defaults); then you can proceed to installing it.
+
+@menu
+* Configuring DejaGnu::
+* Installing DejaGnu::
+@end menu
+
+@node Configuring DejaGnu
+@section Configuring the DejaGnu test driver
+
+It is usually best to configure in a directory separate
+from the source tree, specifying where to find the source with the
+optional @samp{--srcdir} option to @code{configure}. DejaGnu uses the
+GNU @code{autoconf} to configure itself. For more info on using
+autoconf, read the GNU autoconf manual. To configure, execute the
+@file{configure} program, no other options are required. For an example,
+to configure in a seperate tree for objects, execute the configure
+script from the source tree like this:
+
+@smallexample
+../dejagnu-1.3/configure
+@end smallexample
+
+DejaGnu doesn't care at config time if it's for testing a native system
+or a cross system. That is determined at runtime by using the config
+files.
+
+@cindex @code{prefix}, configure options
+@cindex @code{exec_prefix}, configure options.
+You may also want to use the @code{configure} option @samp{--prefix} to
+specify where you want DejaGnu and its supporting code installed. By
+default, installation is in subdirectories of @file{/usr/local}, but you
+can select any alternate directory @var{altdir} by including
+@samp{--prefix=@var{altdir}} on the @code{configure} command line.
+(This value is captured in the Makefile variables @code{prefix}
+and @code{exec_prefix}.)
+
+@cindex auxiliary programs
+@cindex test suite distributions
+@cindex @code{make} builds part of tests
+Save for a small number of example tests, the DejaGnu distribution
+itself does not include any test suites; these are available separately.
+Test suites for the @sc{gnu} compiler (testing both GCC and G++) and for
+the @sc{gnu} binary utilities are distributed in parallel with the
+DejaGnu distribution (but packaged as separate files). The test suite
+for the @sc{gnu} debugger is distributed in parallel with each release
+of GDB itself, starting with GDB 4.9. After configuring the top-level
+DejaGnu directory, unpack and configure the test directories for the
+tools you want to test; then, in each test directory, run @code{make} to
+build auxiliary programs required by some of the tests.
+
+@node Installing DejaGnu
+@section Installing DejaGnu
+
+@cindex installing DejaGnu
+To install DejaGnu in your filesystem (either in @file{/usr/local}, or
+as specified by your @samp{--prefix} option to @code{configure}), execute
+
+@example
+eg$ make install
+@end example
+
+@noindent
+@samp{make install} does these things for DejaGnu:
+
+@enumerate
+@item
+Look in the path specified for executables (@file{$exec_prefix}) for
+directories called @file{lib} and @file{bin}. If these directories do
+not exist, @samp{make install} creates them.
+
+@item
+Create another directory in the @file{lib} directory, called
+@file{dejagnu}.
+
+@item
+Copy the @code{runtest} shell script into @file{$exec_prefix/bin}.
+
+@item
+Copy all the library files (used to support the framework) into
+@file{$exec_prefix/lib/dejagnu}.
+
+@item
+Copy @file{runtest.exp} into @file{$exec_prefix/lib/dejagnu}. This is
+the main Tcl code implementing DejaGnu.
+
+@end enumerate
+
+Each test suite collection comes with simple installation instructions
+in a @file{README} file; in general, the test suites are designed to be
+unpacked in the source directory for the corresponding tool, and extract
+into a directory called @file{testsuite}.
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@contents
+
+@bye
diff --git a/dejagnu/doc/overview.sgml b/dejagnu/doc/overview.sgml
new file mode 100644
index 00000000000..58bce0c8129
--- /dev/null
+++ b/dejagnu/doc/overview.sgml
@@ -0,0 +1,439 @@
+<!DOCTYPE book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
+
+<!-- Begin Document Specific Declarations -->
+
+<?Fm: Validation Off>
+
+<!ENTITY version "0.5">
+<!ENTITY dj "DejaGnu">
+
+<!ENTITY dejagnu-copyright "
+ <YEAR>1998</YEAR>
+ <HOLDER>Free Software Foundation, Inc.</HOLDER>">
+
+<!ENTITY dejagnu-code-copyright "
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+This file documents the GNU Testing Framework ``DejaGnu''
+
+Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+This text may be freely distributed under the terms of the GNU
+General Public License.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+">
+
+<!ENTITY dejagnu-copyright "
+Copyright 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+">
+
+<!-- The reference material -->
+<!entity ref SYSTEM "ref.sgml">
+
+<!-- The user manual -->
+<!entity user SYSTEM "user.sgml">
+
+<!-- End Document Specific Declarations -->
+]>
+
+<book>
+ <bookinfo>
+ <title>&dj;</title>
+ <subtitle>The GNU Testing Framework</subtitle>
+ <date>1998 Nov 24</date>
+ <edition> &version</edition>
+ <releaseinfo> for circulation within Cygnus</releaseinfo>
+ <authorgroup>
+ <author>
+ <firstname>Rob Savoye</firstname>
+ <affiliation>
+ <orgname>Free Software Foundation</orgname></affiliation>
+ <!-- <authorblurb>
+ <title>Rob Savoye</title>
+ <para>
+ His home page is at <ulink>
+ URL="http://www.welcomehome.org/rob.html">this
+ location</ulink>
+ </para>
+ </authorblurb>
+ -->
+ </author>
+ </authorgroup>
+ <address>
+ <email>rob@welcomehome.org</email>
+ </address>
+ <!-- &cygnus-street-address; -->
+ <copyright>&dejagnu-copyright;</copyright>
+ <!-- <legalnotice>
+ <para> -->
+ <!-- [FIXME: must put legal notice here] -->
+ <!-- </para> -->
+ <!-- &cygnus-legal-notice; -->
+ <!-- </legalnotice> -->
+ <revhistory>
+ <revision>
+ <revnumber> 0.1</revnumber>
+ <date>1998-11</date>
+ <authorinitials>rob@welcomehome.org</authorinitials>
+ <revremark>Initial version after conversion to DocBook.</revremark>
+ </revision>
+ </revhistory>
+
+ </bookinfo>
+
+ <toc></toc>
+
+ <preface id=preface>
+ <title>Abstract</title>
+
+ <para>This document attempts to describe the functionality of
+ DejaGnu, the GNU Testing Framework. DejaGnu is entirely written in
+ <productname>Expect</productname>, which uses
+ <productname>Tcl</productname> as a command
+ language. <productname>Expect</productname> serves as a very
+ programmable shell; you can run any program, as with the usual
+ Unix command shells---but once the program is started, your
+ test script has fully programmable control of
+ its input and output. This does not just apply to the programs
+ under test; <command>expect</command> can also run any auxiliary
+ program, such as <command>diff</command> or <command>sh</command>,
+ with full control over its input and output.</para>
+
+ <para>DejaGnu itself is merely a framework for creation of a test
+ suites. Test suites are distributed separately for each GNU
+ tool.</para>
+
+ </preface>
+
+ <chapter id=overview xreflabel=Overview>
+ <title>Overview</title>
+
+ <sect1 id=whatis xreflabel="What is &dj; ?">
+ <title>What is &dj; ?</title>
+
+ <para><productname>DejaGnu</productname> is a framework for
+ testing other programs. Its purpose is to provide a single
+ front end for all tests. Think of it as a custom library of
+ Tcl procedures crafted to support writing a test harness. A
+ <emphasis>Test Harness</emphasis> is the testing
+ infrastructure that is created to support a specific program
+ or tool. Each program can have multiple test suites, all
+ supported by a single test harness. DejaGnu is written in
+ <productname>Expect</productname>, which in turn uses
+ <productname>Tcl</productname> -- Tool command
+ language. There is more information on Tcl at the <ulink
+ URL="http://www.scriptics.com">Scriptics</ulink> web site, and the
+ Expect web site is at <ulink
+ URL="http://expect.nist.gov">NIST</ulink>.</para>
+
+ <para>DejaGnu offers several advantages for testing:</para>
+
+ <itemizedlist mark="bullet" spacing="compact">
+
+ <listitem><para>The flexibility and consistency of the DejaGnu
+ framework make it easy to write tests for any program, with
+ either batch oriented, or interactive programs.</para>
+ </listitem>
+
+ <listitem><para>DejaGnu provides a layer of abstraction which
+ allows you to write tests that are portable to any host or
+ target where a program must be tested. For instance, a test
+ for <command>GDB</command> can run (from any Unix
+ based host) on any target architecture that DejaGnu
+ supports. Currently DejaGnu runs tests on many single board
+ computers, whose operating software ranges from just a boot
+ monitor to a full-fledged, Unix-like realtime OS.</para>
+ </listitem>
+
+ <listitem><para>All tests have the same output format. This
+ makes it easy to integrate testing into other software
+ development processes. DejaGnu's output is designed to be
+ parsed by other filtering script, and it is also human
+ readable.</para>
+ </listitem>
+
+ <listitem><para>Using Tcl and expect, it's easy to create wrappers
+ for existing test suites. By incorporating existing tests under
+ DejaGnu, it's easier to have a single set of report analyse
+ programs..</para>
+
+ </listitem>
+ </itemizedlist>
+
+ <para>Running tests requires two things: the testing framework, and
+ the test suites themselves. Tests are usually written in
+ <productname>Expect</productname> using Tcl, but you can also use a
+ Tcl script to run a test suite that is not based on
+ <productname>Expect</productname>.
+ (<productname>expect</productname> script filenames conventionally
+ use <emphasis>.exp</emphasis> as a suffix; for example, the main
+ implementation of the DejaGnu test driver is in the file
+ <productname>runtest.exp</productname>.)</para>
+
+ <para>Julia Menapace first coined the term ``Deja Gnu'' to describe an
+ earlier testing framework at Cygnus Support she had written for
+ <command>GDB</command>. When we replaced it with the Expect-based
+ framework, it was like DejaGnu all over again... But more importantly, it
+ was also named after my daughter,<ulink
+ URL="mailto:deja@welcomehome.org">Deja Snow Savoye</ulink> (now 9
+ years old in Dec of 1998), who was a toddler during DejaGnu's
+ creation.</para>
+
+ </sect1>
+
+ <sect1 id=new xreflabel="Release Notes">
+ <title>What's New In This Release</title>
+
+ <para>This release has a number of substantial changes over version
+ 1.3. The most visible change is that the version of Expect and Tcl
+ included in the release are up-to-date with the current stable net
+ releases. The biggest change is years of modifications to the
+ target configuration system, used for cross testing. While this
+ greatly improved cross testing, is has made that subsystem very
+ complicated. The goal is to have this entirely rewritten using
+ <productname>iTcl</productname> by the next release. Other changes
+ are:</para>
+
+ <itemizedlist>
+ <listitem><para>More builtin support for building target binaries
+ with the correct linker flags. Currently this only works with
+ <productname>GCC</productname> as the cross compiler,
+ preferably with a target supported by
+ <xref linkend=libgloss>.</para></listitem>
+
+ <listitem><para>Lots of little bug fixes from years of heavy
+ use at Cygnus Solutions.</para></listitem>
+
+ <listitem><para>DejaGnu now uses
+ <productname>Automake</productname> for Makefile
+ configuration.</para></listitem>
+
+ <listitem><para>Updated documentation, now in SGML
+ (using the <ulink
+ URL="http://nis-www.lanl.gov/~rosalia/mydocs/docbook-intro.html">free
+ GNU DocBook tools</ulink>) format.</para></listitem>
+
+ <listitem><para>NT support. There is beta level support for NT
+ that is still a work in progress. This requires the <ulink
+ URL=httpd://sourceware.cygnus.com>Cygwin</ulink> POSIX system
+ for NT.</para></listitem>
+
+ </itemizedlist>
+
+ <sect2 id=cygwin xreflabel="NT Support">
+ <title>NT Support</title>
+
+ <para>To use DejaGnu on NT, you need to first install the
+ <ulink URL="http://sourceware.cygnus.com">Cygwin</ulink>
+ release. This works as of the B20.1 release. Cygwin is a POSIX
+ system for NT. This covers both utility programs, and a libray
+ that adds POSIX system calls to NT. Among them is pseudo tty
+ support for NT that emulates the POSIX pty standard. The
+ latest Cygwin is always available from <ulink
+ URL="http://sourceware.cygnus.com">this location</ulink>. This
+ works well enough to run <emphasis>"make check"</emphasis> of
+ the GNU development tree on NT after a native build. But the
+ nature of pty's on NT is still evolving. Your mileage may
+ vary...</para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id=designgoals xreflabel="Design Goals">
+ <title>Design Goals</title>
+
+ <para>DejaGnu grew out of the internal needs of Cygnus Solutions. (then
+ Cygnus Support). Cygnus maintains and enhances a variety of free programs
+ in many different environments, and we needed a testing tool that:</para>
+
+ <itemizedlist mark="bullet">
+ <listitem><para>is useful to developers while fixing bugs.</para>
+ <listitem><para>automates running many tests during a software
+ release process.</para>
+ <listitem><para>is portable among a variety of host
+ computers.</para>
+ <listitem><para>supports cross-development testing.</para>
+ <listitem><para>permits testing interactive programs, like
+ <command>GDB</command>; and </para>
+ <listitem><para>permits testing batch oriented programs, like
+ <command>GCC</command>.</para>
+ </itemizedlist>
+
+ <para>Some of the requirements proved challenging. For example,
+ interactive programs do not lend themselves very well to automated testing.
+ But all the requirements are important: for instance, it is imperative to
+ make sure that <command>GDB</command> works as well when cross-debugging
+ as it does in a native configuration. </para>
+
+ <para>Probably the greatest challenge was testing in a cross-development
+ environment (which can be a real nightmare). Most cross-development
+ environments are customized by each developer. Even when buying packaged
+ boards from vendors there are many differences. The communication
+ interfaces vary from a serial line to ethernet. DejaGnu was designed with
+ a modular communication setup, so that each kind of communication can be
+ added as required, and supported thereafter. Once a communication
+ procedure is coded, any test can use it. Currently DejaGnu can use
+ <command>rsh</command>, <command>rlogin</command>,
+ <command>telnet</command>, <command>tip</command>,
+ <command>kermit</command>, and <command>mondfe</command> for remote
+ communications.</para>
+
+ </sect1>
+
+ <sect1 id=posix xreflabel="A POSIX Conforming Test Framework">
+ <title>A POSIX conforming test framework</title>
+
+ <para>DejaGnu conforms to the POSIX 1003.3 standard for test
+ frameworks. I was also a member of that committe.</para>
+
+ <para>The POSIX standard 1003.3 defines what a testing framework needs to
+ provide, in order to permit the creation of POSIX conformance test
+ suites. This standard is primarily oriented to running POSIX conformance
+ tests, but its requirements also support testing of features not related
+ to POSIX conformance. POSIX 1003.3 does not specify a particular testing
+ framework, but at this time there is only one other POSIX conforming test
+ framework: TET. TET was created by Unisoft for a consortium comprised of
+ X/Open, Unix International, and the Open Software Foundation.</para>
+
+ <para>The POSIX documentation refers to <firstterm>assertions</firstterm>.
+ An assertion is a description of behavior. For example, if a standard
+ says ``The sun shall shine'', a corresponding assertion might be ``The
+ sun is shining.'' A test based on this assertion would pass or fail
+ depending on whether it is daytime or nighttime. It is important to note
+ that the standard being tested is never 1003.3; the standard being tested
+ is some other standard, for which the assertions were written.</para>
+
+ <para>As there is no test suite to test testing frameworks for POSIX
+ 1003.3 conformance, verifying conformance to this standard is done by
+ repeatedly reading the standard and experimenting. One of the main
+ things 1003.3 does specify is the set of allowed output messages, and
+ their definitions. Four messages are supported for a required feature of
+ POSIX conforming systems, and a fifth for a conditional feature. DejaGnu
+ supports the use of all five output messages; in this sense a test suite
+ that uses exactly these messages can be considered POSIX conforming.
+ These definitions specify the output of a test case:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>PASS</term>
+ <listitem><para>A test has succeeded. That is, it demonstrated that
+ the assertion is true.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>XFAIL</term>
+ <listitem><para>POSIX 1003.3 does not incorporate the notion of
+ expected failures, so <emphasis>PASS</emphasis>, instead of
+ <emphasis>XPASS</emphasis>, must also be returned for test cases
+ which were expected to fail and did not. This means that
+ <emphasis>PASS</emphasis> is in some sense more ambiguous than if
+ <emphasis>XPASS</emphasis> is also used.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>FAIL</term>
+ <listitem><para>A test has produced the bug it was intended to
+ capture. That is, it has demonstrated that the assertion is false.
+ The <emphasis>FAIL</emphasis> message is based on the test case only.
+ Other messages are used to indicate a failure of the framework. As
+ with <emphasis>PASS</emphasis>, POSIX tests must return
+ <emphasis>FAIL</emphasis> rather than <emphasis>XFAIL</emphasis> even
+ if a failure was expected.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>UNRESOLVED</term>
+ <listitem><para>A test produced indeterminate results. Usually, this
+ means the test executed in an unexpected fashion; this outcome
+ requires that a human being go over results, to determine if the test
+ should have passed or failed. This message is also used for any test
+ that requires human intervention because it is beyond the abilities
+ of the testing framework. Any unresolved test should resolved to
+ <emphasis>PASS</emphasis> or <emphasis>FAIL</emphasis> before a test
+ run can be considered finished.</para>
+
+ <para>Note that for POSIX, each assertion must produce a test result
+ code. If the test isn't actually run, it must produce
+ <emphasis>UNRESOLVED</emphasis> rather than just leaving that test
+ out of the output. This means that you have to be careful when
+ writing tests, to not carelessly use tcl statements like
+ <emphasis>return</emphasis>---if you alter the flow of control of the
+ tcl code you must insure that every test still produces some result
+ code.</para>
+
+ <para>Here are some of the ways a test may wind up
+ <emphasis>UNRESOLVED</emphasis>:</para>
+
+ <itemizedlist mark=bullet>
+ <listitem><para>A test's execution is interrupted.</listitem>
+
+ <listitem><para>A test does not produce a clear result. This is
+ usually because there was an <emphasis>ERROR</emphasis> from
+ DejaGnu while processing the test, or because there were three or
+ more <emphasis>WARNING</emphasis> messages. Any
+ <emphasis>WARNING</emphasis> or <emphasis>ERROR</emphasis> messages
+ can invalidate the output of the test. This usually requires a
+ human being to examine the output to determine what really
+ happened---and to improve the test case.</para></listitem>
+
+ <listitem><para>A test depends on a previous test, which
+ fails.</para></listitem>
+
+ <listitem><para>The test was set up incorrectly.</para></listitem>
+ </itemizedlist>
+
+ <varlistentry>
+ <term>UNTESTED</term>
+ <listitem><para>A test was not run. This is a placeholder, used
+ when there is no real test case yet.</para>
+ </varlistentry>
+ </variablelist>
+
+ <para>The only remaining output message left is intended to test
+ features that are specified by the applicable POSIX standard as
+ conditional:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>UNSUPPORTED</term>
+ <listitem><para>There is no support for the tested case. This may
+ mean that a conditional feature of an operating system, or of a
+ compiler, is not implemented. DejaGnu also uses this message when
+ a testing environment (often a ``bare board'' target) lacks basic
+ support for compiling or running the test case. For example, a
+ test for the system subroutine <emphasis>gethostname</emphasis>
+ would never work on a target board running only a boot monitor.
+ </varlistentry>
+ </variablelist>
+
+ <para>DejaGnu uses the same output procedures to produce these messages
+ for all test suites, and these procedures are already known to conform
+ to POSIX 1003.3. For a DejaGnu test suite to conform to POSIX 1003.3,
+ you must avoid the <emphasis>setup</emphasis>xfail} procedure as
+ described in the <emphasis>PASS</emphasis> section above, and you must
+ be careful to return <emphasis>UNRESOLVED</emphasis> where appropriate,
+ as described in the <emphasis>UNRESOLVED</emphasis> section
+ above.</para>
+ </sect1>
+
+ </chapter>
+
+ <!-- include the user manual -->
+ &user;
+
+ <!-- include the reference manual -->
+ &ref;
+
+</book>
diff --git a/dejagnu/doc/ref.sgml b/dejagnu/doc/ref.sgml
new file mode 100644
index 00000000000..6a1a7d6328a
--- /dev/null
+++ b/dejagnu/doc/ref.sgml
@@ -0,0 +1,4242 @@
+<chapter id=reference>
+ <title>Reference</title>
+
+ <sect1 id=installation xreflabel="Installation">
+ <title>Installation</title>
+
+ <para>Once you have the DejaGnu source unpacked and available, you must
+ first configure the software to specify where it is to run (and the
+ associated defaults); then you can proceed to installing it.</para>
+
+ <sect2 id=configuring xreflabel="Configuring DejaGnu">
+ <title>Configuring DejaGnu</title>
+
+ <para>It is usually best to configure in a directory separate from the
+ source tree, specifying where to find the source with the optional
+ <emphasis>--srcdir</emphasis> option to
+ <emphasis>configure</emphasis>. DejaGnu uses the GNU
+ <emphasis>autoconf</emphasis> to configure itself. For more info on using
+ autoconf, read the GNU autoconf manual. To configure, execute the
+ <filename>configure</filename> program, no other options are
+ required. For an example, to configure in a seperate tree for objects,
+ execute the configure script from the source tree like this:</para>
+
+ <screen>
+ ../dejagnu-1.4/configure
+ </screen>
+
+ <para>DejaGnu doesn't care at config time if it's for testing a native
+ system or a cross system. That is determined at runtime by using the
+ config files.</para>
+
+ <para>You may also want to use the <command>configure</command> option
+ <emphasis>--prefix</emphasis> to specify where you want DejaGnu and its
+ supporting code installed. By default, installation is in subdirectories
+ of <filename>/usr/local</filename>, but you can select any alternate
+ directory <symbol>altdir</symbol> by including
+ <option>--prefix</option>{altdir}} on the
+ <command>configure</command> command line. (This value is captured in
+ the Makefile variables <emphasis>prefix</emphasis> and
+ <emphasis>exec</emphasis>prefix}.)</para>
+
+ <para>Save for a small number of example tests, the DejaGnu distribution
+ itself does not include any test suites; these are available
+ separately. Test suites for the GNU development tools are included in
+ those releases. After configuring the top-level DejaGnu directory, unpack
+ and configure the test directories for the tools you want to test; then,
+ in each test directory, run <emphasis>make check</emphasis> to build
+ auxiliary programs required by some of the tests, and run the test
+ suites.</para>
+
+ </sect2>
+
+ <sect2 id=installing xreflabel="Installing DejaGnu">
+ <title>Installing DejaGnu</title>
+
+ <para>To install DejaGnu in your filesystem (either in
+ <filename>/usr/local</filename>, or as specified by your
+ <emphasis>--prefix</emphasis> option to <emphasis>configure</emphasis>),
+ execute.</para>
+
+ <screen>
+ eg$ make install
+ </screen>
+
+ <para><emphasis>make install</emphasis>does thes things for
+ DejaGnu:</para>
+
+ <itemizedlist mark=bullet>
+ <listitem><para>Look in the path specified for executables
+ <symbol>$exec_prefix</symbol>) for directories called
+ <filename>lib</filename> and <filename>bin</filename>. If these
+ directories do not exist, <emphasis>make install</emphasis> creates
+ them.</para></listitem>
+
+ <listitem><para>Create another directory in the
+ <filename>share</filename> directory, called
+ <filename>dejagnu</filename>, and copy all the library files into
+ it.</listitem>
+
+ <listitem><para>Create a directory in the
+ <filename>dejagnu/share</filename> directory, called
+ <filename>config</filename>, and copy all the configuration files into
+ it.</listitem>
+
+ <listitem><para>Copy the <emphasis>runtest</emphasis> shell script into
+ <filename>$exec_prefix/bin</filename>.
+
+ <listitem><para>Copy <filename>runtest.exp</filename> into
+ <filename>$exec_prefix/lib/dejagnu</filename>. This is the main Tcl
+ code implementing DejaGnu.</para></listitem>
+
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 id=builtins xreflabel="Builtin Procedures">
+ <title>Builtin Procedures</title>
+
+ <para>DejaGnu provides these Tcl procedures.</para>
+
+ <sect2 id=coreprocs xreflabel="Core Internal Procedures">
+ <title>Core Internal Procedures</title>
+
+ <sect3 id=mailfile xreflabel="mail_file procedure">
+ <title>Mail_file Procedure</title>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>mail_file</function></funcdef>
+ <paramdef><parameter>file to subject</parameter</paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter></parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=openlogs xreflabel="open_logs procedure">
+ <title>Open_logs Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>open_logs</function></funcdef>
+ <paramdef><parameter></parameter</paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=closelogs xreflabel="close_logs procedure">
+ <title>Close_logs Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>close_logs</function></funcdef>
+ <paramdef><parameter></parameter</paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=isbuild xreflabel="isbuild procedure">
+ <title>Isbuild Procedure</title>
+
+ <para>Tests for a particular build host environment. If the
+ currently configured host matches the argument string, the result is
+ <emphasis>1</emphasis>; otherwise the result is
+ <emphasis>0</emphasis>. <emphasis>host</emphasis> must be a full
+ three-part configure host name; in particular, you may not use the
+ shorter nicknames supported by configure (but you can use wildcard
+ characters, using shell syntax, to specify sets of names). If it is
+ passed a NULL string, then it returns the name of the build canonical
+ configuration.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>isbuild</function></funcdef>
+ <paramdef><parameter>pattern</parameter</paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>pattern</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=isremote xreflabel="is_remote procedure">
+ <title>Is_remote Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>is_remote</function></funcdef>
+ <paramdef><parameter>board</parameter</paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter></parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=is3way xreflabel="is3way procedure">
+ <title>is3way Procedure</title>
+
+ <para>Tests for a canadian cross. This is when the tests will be run
+ on a remotly hosted cross compiler. If it is a canadian cross, then
+ the result is <emphasis>1</emphasis>; otherwise the result is
+ <emphasis>0</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>is3way</function></funcdef>
+ <paramdef><parameter></parameter</paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=ishost xreflabel="ishost procedure">
+ <title>Ishost Procedure</title>
+
+ <para>Tests for a particular host environment. If the currently
+ configured host matches the argument string, the result is
+ <emphasis>1</emphasis>; otherwise the result is
+ <emphasis>0</emphasis>. <emphasis>host</emphasis> must be a full
+ three-part configure host name; in particular, you may not use the
+ shorter nicknames supported by configure (but you can use wildcard
+ characters, using shell syntax, to specify sets of names).</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>ishost</function></funcdef>
+ <paramdef><parameter>pattern</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter></parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=istarget xreflabel="istarget procedure">
+ <title>Istarget Procedure</title>
+
+ <para>Tests for a particular target environment. If the currently
+ configured target matches the argument string, the result is
+ <emphasis>1</emphasis> ; otherwise the result is
+ <emphasis>0</emphasis>. target must be a full three-part configure
+ target name; in particular, you may not use the shorter nicknames
+ supported by configure (but you can use wildcard characters, using
+ shell syntax, to specify sets of names). If it is passed a
+ <emphasis>NULL</emphasis> string, then it returns the name of the
+ build canonical configuration.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>istarget</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter></parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=isnative xreflabel="isnative procedure">
+ <title>Isnative Procedure</title>
+
+ <para>Tests whether the current configuration has the same host and
+ target. When it runs in a native configuration this procedure returns
+ a <emphasis>1</emphasis>; otherwise it returns a
+ <emphasis>0</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>isnative</function></funcdef>
+ <paramdef><parameter></parameter</paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=unknown xreflabel="unknown procedure">
+ <title>Unknown Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>unknown</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=cloneoutput xreflabel="clone_output procedure">
+ <title>Clone_output Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>clone_output</function></funcdef>
+ <paramdef><parameter>message</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>message</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=resetvars xreflabel="reset_vars procedure">
+ <title>Reset_vars Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>reset_vars</function></funcdef>
+ <paramdef><parameter></parameter</paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=logandexit xreflabel="log_and_exit procedure">
+ <title>Log_and_exit Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>log_and_exit</function></funcdef>
+ <paramdef><parameter></parameter</paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=logsummary xreflabel="log_summary procedure">
+ <title>Log_summary Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>log_summary</function></funcdef>
+ <paramdef><parameter>args</parameter</paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=cleanup xreflabel="cleanup procedure">
+ <title>Cleanup Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>cleanup</function></funcdef>
+ <paramdef><parameter></parameter</paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=setupxfail xreflabel="setup_xfail procedure">
+ <title>Setup_xfail Procedure</title>
+
+ <para>Declares that the test is expected to fail on a particular set
+ of configurations. The config argument must be a list of full
+ three-part configure target name; in particular, you may not use the
+ shorter nicknames supported by configure (but you can use the common
+ shell wildcard characters to specify sets of names). The
+ <emphasis>bugid</emphasis> argument is optional, and used only in the
+ logging file output; use it as a link to a bug-tracking system such
+ as <productname>GNATS</productname>.</para>
+
+ <para>Once you use <function>setup_xfail</function>, the
+ <function>fail</function> and <function>pass</function> procedures
+ produce the messages <emphasis>XFAIL</emphasis> and
+ <emphasis>XPASS</emphasis> respectively, allowing you to distinguish
+ expected failures (and unexpected success!) from other test
+ outcomes.</para>
+
+ <warning><para>Warning you must clear the expected failure after
+ using setup_xfail in a test case. Any call to <function>pass
+ </function>or <function>fail</function>l clears the expected failure
+ implicitly; if the test has some other outcome, e.g. an error, you
+ can call <function>clear_xfail</function> to clear the expected
+ failure explicitly. Otherwise, the expected-failure declaration
+ applies to whatever test runs next, leading to surprising
+ results.</para></warning>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>setup_xfail</function></funcdef>
+ <paramdef><parameter>config</parameter>
+ <parameter>bugid</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>config</parameter></term>
+ <listitem><para>The config triplet to trigger whether this is an
+ unexpected or expect failure.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>bugid</parameter></term>
+ <listitem><para>The optional bugid, used to tie it this test case
+ to a bug tracking system.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=recordtest xreflabel="record_test procedure">
+ <title>Record_test Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>record_test</function></funcdef>
+ <paramdef><parameter>type</parameter>
+ <parameter>message</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>message</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=pass xreflabel="pass procedure">
+ <title>Pass Procedure</title>
+
+ <para>Declares a test to have passed. <function>pass</function>
+ writes in the log files a message beginning with
+ <emphasis>PASS</emphasis> (or <emphasis>XPASS</emphasis>, if failure
+ was expected), appending the argument
+ <parameter>string</parameter>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>pass</function></funcdef>
+ <paramdef><parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para>The string to use for this PASS
+ message.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=fail xreflabel="fail procedure">
+ <title>Fail Procedure</title>
+
+ <para>Declares a test to have failed. <function>fail</function>
+ writes in the log files a message beginning with
+ <emphasis>FAIL</emphasis> (or <emphasis>XFAIL</emphasis>, if failure
+ was expected), appending the argument
+ <parameter>string</parameter>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>fail</function></funcdef>
+ <paramdef><parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para>The string to use for this FAIL
+ message.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=xpass xreflabel="xpass procedure">
+ <title>Xpass Procedure</title>
+
+ <para>Declares a test to have unexpectably passed, when it was
+ expected to be a failure. <function>xpass</function>
+ writes in the log files a message beginning with
+ <emphasis>XPASS</emphasis> (or <emphasis>XFAIL</emphasis>, if failure
+ was expected), appending the argument
+ <parameter>string</parameter>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>xpass</function></funcdef>
+ <paramdef><parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para>The string to use for this output
+ state.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=xfail xreflabel="xfail procedure">
+ <title>Xfail Procedure</title>
+
+ <para>Declares a test to have expectably
+ failed. <function>xfail</function>
+ writes in the log files a message beginning with
+ <emphasis>XFAIL</emphasis> (or <emphasis>PASS</emphasis>, if success
+ was expected), appending the argument
+ <parameter>string</parameter>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>xpass</function></funcdef>
+ <paramdef><parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para>The string to use for this output
+ state.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=setwarningthreshold xreflabel="set_warning_threshold procedure">
+ <title>Set_warning_threshold Procedure</title>
+
+ <para>Sets the value of <symbol>warning_threshold</symbol>. A value
+ of <emphasis>0</emphasis> disables it: calls to
+ <function>warning</function> will not turn a
+ <emphasis>PASS</emphasis> or <emphasis>FAIL</emphasis> into an
+ <emphasis>UNRESOLVED</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>set_warning_threshold</function></funcdef>
+ <paramdef><parameter>threshold</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>threshold</parameter></term>
+ <listitem><para>This is the value of the new warning
+ threshold.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=getwarningthreshold xreflabel="get_warning_threshold procedure">
+ <title>Get_warning_threshold Procedure</title>
+
+ <para>Returns the current value of
+ <symbol>{warning_threshold</symbol>. The default value is 3. This
+ value controls how many <function>warning</function> procedures can
+ be called before becoming <emphasis>UNRESOLVED</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>get_warning_threshold</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+
+ <sect3 id=warning xreflabel="warning procedure">
+ <title>Warning Procedure</title>
+
+ <para>Declares detection of a minor error in the test case
+ itself. <function>warning</function> writes in the log files a message
+ beginning with <emphasis>WARNING</emphasis>, appending the argument
+ <parameter>string</parameter>. Use <function>warning</function> rather
+ than <function>perror</function> for cases (such as communication
+ failure to be followed by a retry) where the test case can recover from
+ the error. If the optional <parameter>number</parameter> is supplied,
+ then this is used to set the internal count of warnings to that
+ value.</para>
+
+ <para>As a side effect, <symbol>warning_threshold</symbol> or more
+ calls to warning in a single test case also changes the effect of the
+ next <function>pass</function> or <function>fail</function> command:
+ the test outcome becomes <emphasis>UNRESOLVED</emphasis> since an
+ automatic <emphasis>PASS</emphasis> or <emphasis>FAIL</emphasis> may
+ not be trustworthy after many warnings. If the optional numeric value
+ is <emphasis>0</emphasis>, then there are no further side effects to
+ calling this function, and the following test outcome doesn't become
+ <emphasis>UNRESOLVED</emphasis>. This can be used for errors with no
+ known side effects.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>warning</function></funcdef>
+ <paramdef><parameter>string</parameter>
+ <parameter>number</parameter>
+ </paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>number</parameter></term>
+ <listitem><para>The optional number to set the error counter. Thius
+ is only used to fake out the counter when using the
+ <function>xfail</function> procedure to control when it flips the
+ output over to <emphasis>UNRESOLVED</emphasis>
+ state.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <sect3 id=perror xreflabel="perror procedure">
+ <title>Perror Procedure</title>
+
+ <para>Declares a severe error in the testing framework
+ itself. <function>perror</function> writes in the log files a message
+ beginning with <emphasis>ERROR</emphasis>, appending the argument
+ <parameter>string</parameter>.</para>
+
+ <para>As a side effect, perror also changes the effect of the next
+ <function>pass</function> or <function>fail</function> command: the
+ test outcome becomes <emphasis>UNRESOLVED</emphasis>, since an
+ automatic <emphasis>PASS</emphasis> or <emphasis>FAIL</emphasis> cannot
+ be trusted after a severe error in the test framework. If the optional
+ numeric value is <emphasis>0</emphasis>, then there are no further side
+ effects to calling this function, and the following test outcome
+ doesn't become <emphasis>UNRESOLVED</emphasis>. This can be used for
+ errors with no known side effects.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>perror</function></funcdef>
+ <paramdef><parameter>string</parameter>
+ <parameter>number</parameter>
+ </paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>number</parameter></term>
+ <listitem><para>The optional number to set the error counter. Thius
+ is only used to fake out the counter when using the
+ <function>xfail</function> procedure to control when it flips the
+ output over to <emphasis>UNRESOLVED</emphasis>
+ state.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <sect3 id=note xreflabel="note procedure">
+ <title>Note Procedure</title>
+
+ <para>Appends an informational message to the log
+ file. <function>note</function> writes in the log files a message
+ beginning with <emphasis>NOTE</emphasis>, appending the argument
+ <parameter>string</parameter>. Use <function>note</function>
+ sparingly. The <function>verbose</function> should be used for most
+ such messages, but in cases where a message is needed in the log file
+ regardless of the verbosity level use <function>note</function>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>note</function></funcdef>
+ <paramdef><parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para>The string to use for this note.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=untested xreflabel="untested procedure">
+ <title>Untested Procedure</title>
+
+ <para>Declares a test was not run. <function>untested</function> writes
+ in the log file a message beginning with <emphasis>UNTESTED</emphasis>,
+ appending the argument <emphasis>string</emphasis>. For example, you
+ might use this in a dummy test whose only role is to record that a test
+ does not yet exist for some feature.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>untested</function></funcdef>
+ <paramdef><parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para>The string to use for this output
+ state.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=unresolved xreflabel="unresolved procedure">
+ <title>Unresolved Procedure</title>
+
+ <para>Declares a test to have an unresolved
+ outcome. <function>unresolved</function> writes in the log file a
+ message beginning with <emphasis>UNRESOLVED</emphasis>, appending the
+ argument <emphasis>string</emphasis>. This usually means the test did
+ not execute as expected, and a human being must go over results to
+ determine if it passed or failed (and to improve the test case).</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>unresolved</function></funcdef>
+ <paramdef><parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para>The string to use for this output
+ state.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=unsupported xreflabel="unsupported procedure">
+ <title>Unsupported Procedure</title>
+
+ <para>Declares that a test case depends on some facility that does not
+ exist in the testing environment. <function>unsupported</function>
+ writes in the log file a message beginning with
+ <emphasis>UNSUPPORTED</emphasis>, appending the argument string.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>unsupported</function></funcdef>
+ <paramdef><parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para>The string to use for this output
+ state.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=inittestcounts xreflabel="init_testcounts procedure">
+ <title>Init_testcounts Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>init_testcounts</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=incrcount xreflabel="incr_count procedure">
+ <title>Incr_count Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>incr_count</function></funcdef>
+ <paramdef><parameter>name</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=transform xreflabel="transform procedure">
+ <title>transform Procedure</title>
+
+ <para>Generates a string for the name of a tool as it was configured
+ and installed, given its native name (as the argument
+ <parameter>toolname</parameter>). This makes the assumption that all
+ tools are installed using the same naming conventions: For example,
+ for a cross compiler supporting the <emphasis>m68k-vxworks</emphasis>
+ configuration, the result of transform <command>gcc</command> is
+ <command>m68k-vxworks-gcc</command>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>transform</function></funcdef>
+ <paramdef><parameter>toolname</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>toolname</parameter></term>
+ <listitem><para>The name of the cross-development program to
+ transform.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+
+ <sect3 id=checkconditionalxfail xreflabel="check_conditional_xfail procedure">
+ <title>Check_conditional_xfail Procedure</title>
+
+ <para>This procedure adds a condition xfail, based on compiler
+ options used to create a test case executable. If an include options
+ is found in the compiler flags, and it's the right architecture,
+ it'll trigger an <emphasis>XFAIL</emphasis>. Otherwise it'll produce
+ an ordinary <emphasis>FAIL</emphasis>. You can also specify flags to
+ exclude. This makes a result be a <emphasis>FAIL</emphasis>, even if
+ the included options are found. To set the conditional, set
+ the variable <symbol>compiler_conditional_xfail_data</symbol> to the
+ fields <programlisting>"[message string] [targets list] [includes
+ list] [excludes list]"</programlisting> (descriptions below). This is
+ the checked at pass/fail decision time, so there is no need to call
+ the procedure yourself, unless you wish to know if it gets
+ triggered. After a pass/fail, the variable is reset, so it doesn't
+ effect other tests. It returns <emphasis>1</emphasis> if the
+ conditional is true, or <emphasis>0</emphasis> if the conditional is
+ false.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>check_conditional_xfail</function></funcdef>
+ <paramdef><parameter>message</parameter>
+ <parameter>targets</parameter>
+ <parameter>includes</parameter>
+ <parameter>excludes</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>message</parameter></term>
+ <listitem><para>This is the message to print with the normal test
+ result.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>targets</parameter></term>
+ <listitem><para>This is a string with the list targets to activate
+ this conditional on.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>includes</parameter></term>
+ <listitem><para>This is a list of sets of options to search for in
+ the compiler options to activate this conditional. If any set of
+ the options matches, then this conditional is
+ true.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>excludes</parameter></term>
+ <listitem><para>This is a list of sets of options to search for in
+ the compiler options to activate this conditional. If any set of
+ the options matches, (regardless of whether any of the include sets
+ match) then this conditional is de-activated.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <example>
+ <title>Specifying the conditional xfail data</title>
+
+ <programlisting>
+ set compiler_conditional_xfail_data { \
+ "I sure wish I knew why this was hosed" \
+ "sparc*-sun*-* *-pc-*-*" \
+ {"-Wall -v" "-O3"} \
+ {"-O1" "-Map"} \
+ }
+ </programlisting>
+
+ </example>
+
+ <para>What this does is it matches only for these two targets if
+ "-Wall -v" or "-O3" is set, but neither "-O1" or "-Map" is set. For
+ a set to match, the options specified are searched for independantly
+ of each other, so a "-Wall -v" matches either "-Wall -v" or "-v
+ -Wall". A space seperates the options in the string. Glob-style
+ regular expressions are also permitted.</para>
+
+ </sect3>
+
+ <sect3 id=clearxfail xreflabel="clear_xfail procedure">
+ <title>Clear_xfail Procedure</title>
+
+ <para>Cancel an expected failure (previously declared with
+ <command>setup_xfail</command>) for a particular set of
+ configurations. The <parameter>config</parameter> argument is a list
+ of configuration target names. It is only necessary to call
+ <command>clear_xfail</command> if a test case ends without calling
+ either <command>pass</command> or <command>fail</command>, after
+ calling <command>setup_xfail</command>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>clear_xfail</function></funcdef>
+ <paramdef><parameter>config</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>config</parameter></term>
+ <listitem><para>The configuration triplets to
+ clear.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=verbose xreflabel="verbose procedure">
+ <title>Verbose Procedure</title>
+
+ <para>Test cases can use this function to issue helpful messages
+ depending on the number of <option>--verbose</option> options on the
+ runtest command line. It prints string if the value of the variable
+ <symbol>verbose</symbol> is higher than or equal to the optional
+ number. The default value for number is <emphasis>1</emphasis>. Use
+ the optional <option>-log</option> argument to cause string to always
+ be added to the log file, even if it won't be printed. Use the
+ optional <option>-n</option> argument to print string without a
+ trailing newline. Use the optional <option>--</option> argument if
+ string begins with "-".</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>verbose</function></funcdef>
+ <paramdef><parameter>-log</parameter>
+ <parameter>-n</parameter>
+ <parameter>-r</parameter>
+ <parameter>string</parameter>
+ <parameter>number</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>-log</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>-n</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>--</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>number</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=loadlib xreflabel="load_lib procedure">
+ <title>Load_lib Procedure</title>
+
+ <para>Loads a DejaGnu library file by searching a fixed path built
+ into DejaGnu. If DejaGnu has been installed, it looks in a path
+ starting with the installed library directory. If you are running
+ DejaGnu directly from a source directory, without first running
+ <command>make install</command>, this path defaults to the current
+ directory. In either case, it then looks in the current directory
+ for a directory called <filename>lib</filename>. If there are
+ duplicate definitions, the last one loaded takes precedence over the
+ earlier ones.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>load_lib</function></funcdef>
+ <paramdef><parameter>filespec</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>filespec</parameter></term>
+ <listitem><para>The name of the DejaGnu library file to
+ load.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ </sect2>
+
+ <sect2 id=remoteprocs>
+ <title>Procedures For Remote Communication</title>
+
+ <para><filename>lib/remote.exp</filename> defines these
+ functions, for establishing and managing communications. Each
+ of these procedures tries to establish the connection up to
+ three times before returning. Warnings (if retries will
+ continue) or errors (if the attempt is abandoned) report on
+ communication failures. The result for any of these
+ procedures is either <emphasis>-1</emphasis>, when the
+ connection cannot be established, or the spawn ID returned by
+ the <productname>Expect</productname> command
+ <command>spawn</command>.</para>
+
+ <para>It use the value of the <symbol>connect</symbol> field
+ in the <symbol>target_info</symbol> array (was
+ <symbol>connectmode</symbol> as the type of connection to
+ make. Current supported connection types are tip, kermit,
+ telnet, rsh, rlogin, and netdata. If the <option>--reboot</option>
+ option was used on the runtest command line, then the target
+ is rebooted before the connection is made.</para>
+
+ <sect3 id=callremote xreflabel="call_remote procedure">
+ <title>Call_remote Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>call_remote</function></funcdef>
+ <paramdef><parameter>type</parameter>
+ <parameter>proc</parameter>
+ <parameter>dest</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>proc</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=checkforboardstatus xreflabel="check_for_board_status
+ procedure">
+ <title>Check_for_board_status Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>check_for_board_status</function></funcdef>
+ <paramdef><parameter>variable</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>variable</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=fileonbuild xreflabel="file_on_build procedure">
+ <title>File_on_build Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>file_on_build</function></funcdef>
+ <paramdef><parameter>op</parameter>
+ <parameter>file</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>op</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=fileonhost xreflabel="file_on_host procedure">
+ <title>File_on_host Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>file_on_host</function></funcdef>
+ <paramdef><parameter>op</parameter>
+ <parameter>file</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>op</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=localexec xreflabel="local_exec procedure">
+ <title>Local_exec Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>local_exec</function></funcdef>
+ <paramdef><parameter>commandline</parameter>
+ <parameter>inp</parameter>
+ <parameter>outp</parameter>
+ <parameter>timeout</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>inp</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>outp</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>timeout</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotebinary xreflabel="remote_binary procedure">
+ <title>Remote_binary Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_binary</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoteclose xreflabel="remote_close procedure">
+ <title>Remote_close Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_close</function></funcdef>
+ <paramdef><parameter>shellid</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>shellid</parameter></term>
+ <listitem><para>This is the value returned by a call
+ to <function>remote_open</function>. This closes the
+ connection to the target so resources can be used by
+ others. This parameter can be left off if the
+ <symbol>fileid</symbol> field in the
+ <symbol>target_info</symbol> array is set.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotedownload xreflabel="remote_download procedure">
+ <title>Remote_download Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_download</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>file</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoteexec xreflabel="remote_exec procedure">
+ <title>Remote_exec Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_exec</function></funcdef>
+ <paramdef><parameter>hostname</parameter>
+ <parameter>program</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>hostname</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>program</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoteexpect xreflabel="remote_expect procedure">
+ <title>Remote_expect Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_expect</function></funcdef>
+ <paramdef><parameter>board</parameter>
+ <parameter>timeout</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>board</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>timeout</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotefile xreflabel="remote_file procedure">
+ <title>Remote_file Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_file</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>args</parameter</paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoteld xreflabel="remote_ld procedure">
+ <title>Remote_ld Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_ld</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>prog</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>prog</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoteload xreflabel="remote_load procedure">
+ <title>Remote_load Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_load</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>prog</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>prog</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoteopen xreflabel="remote_open procedure">
+ <title>Remote_open Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_open</function></funcdef>
+ <paramdef><parameter>type</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem><para>This is passed <option>host</option> or
+ <option>target</option>. Host or target refers to
+ whether it is a connection to a remote target, or a
+ remote host. This opens the connection to the desired
+ target or host using the default values in the
+ configuration system. It returns that
+ <symbol>spawn_id</symbol> of the process that manages
+ the connection. This value can be used in
+ <productname>Expect</productname> or
+ <command>exp_send</command> statements, or passed to
+ other procedures that need the connection process's
+ id. This also sets the <symbol>fileid</symbol> field in
+ the <symbol>target_info</symbol> array.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotepopconn xreflabel="remote_pop_conn procedure">
+ <title>Remote_pop_conn Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_pop_conn</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotepushconn xreflabel="remote_push_conn procedure">
+ <title>Remote_push_conn Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_push_conn</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawbinary xreflabel="remote_raw_binary procedure">
+ <title>Remote_raw_binary Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_binary</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawclose xreflabel="remote_raw_close procedure">
+ <title>Remote_raw_close Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_close</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawfile xreflabel="remote_raw_file procedure">
+ <title>Remote_raw_file Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_file</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawld xreflabel="remote_raw_ld procedure">
+ <title>remote_raw_ld Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_ld</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>prog</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>prog</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawload xreflabel="remote_raw_load procedure">
+ <title>Remote_raw_load Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_load</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>prog</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>prog</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawopen xreflabel="remote_raw_open procedure">
+ <title>Remote_raw_open Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_open</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawsend xreflabel="remote_raw_send procedure">
+ <title>Remote_raw_send Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_send</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawspawn xreflabel="remote_raw_spawn procedure">
+ <title>Remote_raw_spawn Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_spawn</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>commandline</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>commandline</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawtransmit xreflabel="remote_raw_transmit
+ procedure">
+ <title>Remote_raw_transmit Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_transmit</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoterawwait xreflabel="remote_raw_wait procedure">
+ <title>Remote_raw_wait Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_raw_wait</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>timeout</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>timeout</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotereboot xreflabel="remote_reboot procedure">
+ <title>Remote_reboot Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_reboot</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotesend xreflabel="remote_send procedure">
+ <title>Remote_send Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_send</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotespawn xreflabel="remote_spawn procedure">
+ <title>Remote_spawn Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_spawn</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>commandline</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>commandline</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoteswapconn xreflabel="remote_swap_conn procedure">
+ <title>Remote_swap_conn Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_swap_conn</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter></parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotetransmit xreflabel="remote_transmit procedure">
+ <title>Remote_transmit Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_transmit</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remoteupload xreflabel="remote_upload procedure">
+ <title>Remote_upload Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_upload</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>srcfile</parameter>
+ <parameter>arg</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>srcfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>arg</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=remotewait xreflabel="remote_wait procedure">
+ <title>Remote_wait Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>remote_wait</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>timeout</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>timeout</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardclose xreflabel="standard_close procedure">
+ <title>Standard_close Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_close</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standarddownload xreflabel="standard_download procedure">
+ <title>Standard_download Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_download</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>file</parameter>
+ <parameter>destfile</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>destfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardexec xreflabel="standard_exec procedure">
+ <title>Standard_exec Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_exec</function></funcdef>
+ <paramdef><parameter>hostname</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>hostname</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardfile xreflabel="standard_file procedure">
+ <title>Standard_file Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_file</function></funcdef>
+ <paramdef><parameter>dest</parameter
+ <parameter>op</parameter
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter></parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardload xreflabel="standard_load procedure">
+ <title>Standard_load Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_load</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>prog</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>prog</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardreboot xreflabel="standard_reboot procedure">
+ <title>Standard_reboot Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_reboot</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardsend xreflabel="standard_send procedure">
+ <title>Standard_send Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_send</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>string</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardspawn xreflabel="standard_spawn procedure">
+ <title>Standard_spawn Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_spawn</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>commandline</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>commndline</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardtransmit xreflabel="standard_transmit procedure">
+ <title>Standard_transmit Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_transmit</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardupload xreflabel="standard_upload procedure">
+ <title>Standard_upload Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_upload</function></funcdef>
+ <paramdef><parameter>dest srcfile destfile</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>srcfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>destfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=standardwait xreflabel="standard_wait procedure">
+ <title>Standard_wait Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>standard_wait</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>timeout</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>timeout</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=unixcleanfilename xreflabel="unix_clean_filename
+ procedure">
+ <title>Unix_clean_filename Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>unix_clean_filename</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+<!-- FIXME: this doesn't seem to exist anymore
+ <sect3 id=exitremoteshell xreflabel="exit_remote_shell procedure">
+ <title>exit_remote_shell Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>exit_remote_shell</function></funcdef>
+ <paramdef><parameter>spawnid</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>spawnid</parameter></term>
+ <listitem><para>Exits a remote process started by any
+ of the connection procedures. <symbol>spawnid</symbol>
+ is the result of the connection procedure that started
+ the remote process.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+-->
+
+ </sect2>
+
+ <sect2 id=connprocs xreflabel="connprocs">
+ <title>Procedures For Using Utilities to Connect</title>
+
+ <para>telnet, rsh, tip, kermit</para>
+
+ <sect3 id=telnet xreflabel="telnet procedure">
+ <title>telnet Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>telnet</function></funcdef>
+ <paramdef><parameter>hostname</parameter>
+ <parameter>port</parameter></paramdef>
+ </funcsynopsis>
+ <funcsynopsis role="tcl">
+ <funcdef><function>rlogin</function></funcdef>
+ <paramdef><parameter>hostname</parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=rsh xreflabel="rsh procedure">
+ <title>rsh Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>rsh</function></funcdef>
+ <paramdef><parameter>hostname</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>hostname</parameter></term>
+ <listitem><para>This refers to the IP address or name
+ (for example, an entry in
+ <filename>/etc/hosts</filename>) for this target. The
+ procedure names reflect the Unix utility used to
+ establish a connection. The optional
+ <parameter>port</parameter> is used to specify the IP
+ port number. The value of the
+ <parameter>netport</parameter> field in the
+ <symbol>target_info</symbol> array is used. (was
+ <symbol>$netport</symbol>) This value has two parts,
+ the hostname and the port number, seperated by a
+ <emphasis>:</emphasis>. If host or target is used in
+ the <symbol>hostname</symbol> field, than the
+ config array is used for all information.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=tip xreflabel="tip procedure">
+ <title>Tip Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>tip</function></funcdef>
+ <paramdef><parameter>port</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>port</parameter></term>
+ <listitem><para>Connect using the Unix utility
+ <command>tip</command>. <parameter>Port</parameter>must
+ be a name from the <productname>tip</productname>
+ configuration file
+ <filename>/etc/remote</filename>. Often, this is called
+ <symbol>hardwire</symbol>, or something like
+ <symbol>ttya</symbol>. This file holds all the
+ configuration data for the serial port. The value of
+ the <symbol>serial</symbol> field in the
+ <symbol>target_info</symbol> array is used. (was
+ <symbol>$serialport</symbol>) If <option>host</option>
+ or <option>target</option> is used in the
+ <parameter>port</parameter> field, than the config
+ array is used for all information. the
+ config array is used for all information.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=kermit xreflabel="kermit procedure">
+ <title>Kermit Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>kermit</function></funcdef>
+ <paramdef><parameter>port</parameter>
+ <parameter>bps</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>port</parameter></term>
+ <listitem><para>Connect using the program
+ <command>kermit</command>. <parameter>Port</parameter>
+ is the device name,
+ e.g. <filename>/dev/ttyb</filename>.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>bps</parameter></term>
+ <listitem><para><parameter>bps</parameter> is the line
+ speed to use (in its per second) for the
+ connection. The value of the <symbol>serial</symbol>
+ field in the <symbol>target_info</symbol> array is
+ used. (was <symbol>$serialport</symbol>) If
+ <option>host</option> or <option>target</option> is
+ used in the <parameter>port</parameter> field, than the
+ config array is used for all information. the
+ config array is used for all information.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=kermitopen xreflabel="kermit_open procedure">
+ <title>kermit_open Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>kermit_open</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=kermitcommand xreflabel="kermit_command procedure">
+ <title>Kermit_command Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>kermit_command</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=kermitsend xreflabel="kermit_send procedure">
+ <title>Kermit_send Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>kermit_send</function></funcdef>
+ <paramdef><parameter>dest string args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>string</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=kermittransmit xreflabel="kermit_transmit procedure">
+ <title>Kermit_transmit Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>kermit_transmit</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>file</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=telnetopen xreflabel="telnet_open procedure">
+ <title>Telnet_open Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>telnet_open</function></funcdef>
+ <paramdef><parameter>hostname</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>hostname</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=telnetbinary xreflabel="telnet_binary procedure">
+ <title>Telnet_binary Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>telnet_binary</function></funcdef>
+ <paramdef><parameter>hostname</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>hostname</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=telnettransmit xreflabel="telnet_transmit procedure">
+ <title>Telnet_transmit Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>telnet_transmit</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>file</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=tipopen xreflabel="tip_open procedure">
+ <title>Tip_open Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>tip_open</function></funcdef>
+ <paramdef><parameter>hostname</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>hostname</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=rloginopen xreflabel="rlogin_open procedure">
+ <title>Rlogin_open Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>rlogin_open</function></funcdef>
+ <paramdef><parameter>arg</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>arg</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=rloginspawn xreflabel="rlogin_spawn procedure">
+ <title>Rlogin_spawn Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>rlogin_spawn</function></funcdef>
+ <paramdef><parameter>dest</parameter>
+ <parameter>cmdline</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>dest</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>cmdline</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=rshopen xreflabel="rsh_open procedure">
+ <title>Rsh_open Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>rsh_open</function></funcdef>
+ <paramdef><parameter>hostname</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>hostname</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=rshdownload xreflabel="rsh_download procedure">
+ <title>Rsh_download Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>rsh_download</function></funcdef>
+ <paramdef><parameter>desthost</parameter>
+ <parameter>srcfile</parameter>
+ <parameter>destfile</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>desthost</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>srcfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>destfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=rshupload xreflabel="rsh_upload procedure">
+ <title>Rsh_upload Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>rsh_upload</function></funcdef>
+ <paramdef><parameter>desthost</parameter>
+ <parameter>srcfile</parameter>
+ <parameter>destfile</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>desthost</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>srcfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>destfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=rshexec xreflabel="rsh_exec procedure">
+ <title>Rsh_exec Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>rsh_exec</function></funcdef>
+ <paramdef><parameter>boardname</parameter>
+ <parameter>cmd</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>boardname</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>cmd</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=ftpopen xreflabel="ftp_open procedure">
+ <title>Ftp_open Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>ftp_open</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=ftpupload xreflabel="ftp_upload procedure">
+ <title>Ftp_upload Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>ftp_upload</function></funcdef>
+ <paramdef><parameter>host</parameter>
+ <parameter>remotefile</parameter>
+ <parameter>localfile</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>remotefile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>localfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=ftpdownload xreflabel="ftp_download procedure">
+ <title>Ftp_download Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>ftp_download</function></funcdef>
+ <paramdef><parameter>host</parameter>
+ <parameter>localfile</parameter>
+ <parameter>remotefile</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>localfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>remotefile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=ftpclose xreflabel="ftp_close procedure">
+ <title>Ftp_close Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>ftp_close</function></funcdef>
+ <paramdef><parameter>host</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>host</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=tipdownload xreflabel="tip_download procedure">
+ <title>Tip_download Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>tip_download</function></funcdef>
+ <paramdef><parameter>spawnid</parameter>
+ <parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>spawnid</parameter></term>
+ <listitem><para>Download <option>file</option> to the
+ process <symbol>spawnid</symbol> (the value returned
+ when the connection was established), using the
+ <command>~put</command> command under
+ <productname>tip</productname>. Most often used for
+ single board computers that require downloading
+ programs in ASCII S-records. Returns
+ <emphasis>1</emphasis> if an error occurs,
+ <emphasis>0</emphasis> otherwise.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para>This is the filename to
+ downlaod.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ </sect2>
+
+ <sect2 id=targetprocs>
+ <title>Procedures For Target Boards</title>
+
+ <para></para>
+
+ <sect3 id=defaultlink xreflabel="default_link procedure">
+ <title>Default_link Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>default_link</function></funcdef>
+ <paramdef><parameter>board</parameter>
+ <parameter>objects</parameter>
+ <parameter>destfile</parameter>
+ <parameter>flags</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>board</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>objects</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>destfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>flags</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=defaulttargetassemble xreflabel="default_target_assemble
+ procedure">
+ <title>Default_target_assemble Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>default_target_assemble</function></funcdef>
+ <paramdef><parameter>source</parameter>
+ <parameter>destfile</parameter>
+ <parameter>flags</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>source</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>destfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>flags</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=defaulttargetcompile xreflabel="default_target_compile
+ procedure">
+ <title>default_target_compile Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>default_target_compile</function></funcdef>
+ <paramdef><parameter>source</parameter>
+ <parameter>destfile</parameter>
+ <parameter>type</parameter>
+ <parameter>options</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>source</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>destfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>options</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=popconfig xreflabel="pop_config procedure">
+ <title>Pop_config Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>pop_config</function></funcdef>
+ <paramdef><parameter>type</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=prunewarnings xreflabel="prune_warnings procedure">
+ <title>Prune_warnings Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>prune_warnings</function></funcdef>
+ <paramdef><parameter>text</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>text</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=pushbuild xreflabel="push_build procedure">
+ <title>Push_build Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>push_build</function></funcdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=pushconfig xreflabel="push_config procedure">
+ <title>push_config Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>push_config</function></funcdef>
+ <paramdef><parameter>type</parameter>
+ <parameter>name</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=reboottarget xreflabel="reboot_target procedure">
+ <title>Reboot_target Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>reboot_target</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=targetassemble xreflabel="target_assemble procedure">
+ <title>Target_assemble Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>target_assemble</function></funcdef>
+ <paramdef><parameter>source destfile flags</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>source</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>destfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>flags</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=targetcompile xreflabel="target_compile procedure">
+ <title>Target_compile Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>target_compile</function></funcdef>
+ <paramdef><parameter>source</parameter>
+ <parameter>destfile</parameter>
+ <parameter>type</parameter>
+ <parameter>options</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>source</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>destfile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>options</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ </sect2>
+
+ <sect2 id=targetdb xreflabel="target database library file ">
+ <title>Target Database Procedures</title>
+
+ <sect3 id=boardinfo xreflabel="board_info procedure">
+ <title>Board_info Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>board_info</function></funcdef>
+ <paramdef><parameter>machine</parameter>
+ <parameter>op</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>machine</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>op</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=hostinfo xreflabel="host_info procedure">
+ <title>Host_info Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>host_info</function></funcdef>
+ <paramdef><parameter>op</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>op</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=setboardinfo xreflabel="set_board_info procedure">
+ <title>Set_board_info Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>set_board_info</function></funcdef>
+ <paramdef><parameter>entry</parameter>
+ <parameter>value</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>entry</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>value</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=setcurrtargetinfo xreflabel="set_currtarget_info
+ procedure">
+ <title>Set_currtarget_info Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>set_currtarget_info</function></funcdef>
+ <paramdef><parameter>entry</parameter>
+ <parameter>value</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>entry</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>value</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=targetinfo xreflabel="target_info procedure">
+ <title>Target_info Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>target_info</function></funcdef>
+ <paramdef><parameter>op</parameter>
+ <parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>op</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=unsetboardinfo xreflabel="unset_board_info procedure">
+ <title>Unset_board_info Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>unset_board_info</function></funcdef>
+ <paramdef><parameter>entry</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>entry</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=unsetcurrtargetinfo xreflabel="unset_currtarget_info
+ procedure">
+ <title>Unset_currtarget_info Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>unset_currtarget_info</function></funcdef>
+ <paramdef><parameter>entry</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>entry</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=pushtarget xreflabel="push_target procedure">
+ <title>Push_target Procedure</title>
+
+ <para>This makes the target named <emphasis>name</emphasis> be the
+ current target connection. The value of <emphasis>name</emphasis> is
+ an index into the <symbol>target_info</symbol> array and is set in
+ the global config file.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>push_target</function></funcdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem><para>The name of the target to make current
+ connection.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=poptarget xreflabel="poptarget procedure">
+ <title>Pop_target Procedure</title>
+
+ <para>This unsets the current target connection.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>pop_target</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=listtargets xreflabel="list_targets procedure">
+ <title>List_targets Procedure</title>
+
+ <para>This lists all the supported targets for this
+ architecture.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>list_targets</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=pushhost xreflabel="push_host procedure">
+ <title>Push_host Procedure</title>
+
+ <para>This makes the host named <emphasis>name</emphasis> be the
+ current remote host connection. The value of
+ <emphasis>name</emphasis> is an index into the
+ <symbol>target_info</symbol> array and is set in the global config
+ file.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>push_host</function></funcdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=pophost xreflabel="pop_host procedure">
+ <title>Pop_host Procedure</title>
+
+ <para>This unsets the current host connection.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>pop_host</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=compile xreflabel="compile procedure">
+ <title>Compile Procedure</title>
+
+ <para>This invokes the compiler as set by CC to compile the
+ file <filename>file</filename>. The default options for many cross
+ compilation targets are <emphasis>guessed</emphasis> by DejaGnu, and
+ these options can be added to by passing in more parameters as
+ arguments to <command>compile</command>. Optionally, this will also
+ use the value of the <emphasis>cflags</emphasis> field in the target
+ config array. If the host is not the same as the build machines, then
+ then compiler is run on the remote host using
+ <command>execute_anywhere</command>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>compile</function></funcdef>
+ <paramdef><parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=archive xreflabel="archive procedure">
+ <title>Archive Procedure</title>
+
+ <para>This produces an archive file. Any parameters passed to
+ <command>archive</command> are used in addition to the default
+ flags. Optionally, this will also use the value of the
+ <emphasis>arflags</emphasis> field in the target config array. If the
+ host is not the same as the build machines, then then archiver is run
+ on the remote host using <command>execute_anywhere</command>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>archive</function></funcdef>
+ <paramdef><parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=ranlib xreflabel="ranlib procedure">
+ <title>Ranlib Procedure</title>
+
+ <para>This generates an index for the archive file for systems that
+ aren't POSIX yet. Any parameters passed to <command>ranlib</command>
+ are used in for the flags.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>ranlib</function></funcdef>
+ <paramdef><parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>file</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=executeanywhere xreflabel="execute_anywhere procedure">
+ <title>Execute_anywhere Procedure</title>
+
+ <para>This executes the <emphasis>cmdline</emphasis> on the proper
+ host. This should be used as a replacement for the Tcl command
+ <command>exec</command> as this version utilizes the target config
+ info to execute this command on the build machine or a remote
+ host. All config information for the remote host must be setup to
+ have this command work. If this is a canadian cross, (where we test a
+ cross compiler that runs on a different host then where DejaGnu is
+ running) then a connection is made to the remote host and the command
+ is executed there. It returns either REMOTERROR (for an error) or the
+ output produced when the command was executed. This is used for
+ running the tool to be tested, not a test case.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>execute_anywhere</function></funcdef>
+ <paramdef><parameter>cmdline</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>cmdline</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect2 id=platformprocs xreflabel="platform dependant procedures">
+ <title>Platform Dependant Procedures</title>
+
+ <para>Each combination of target and tool requires some
+ target-dependent procedures. The names of these procedures have
+ a common form: the tool name, followed by an underbar
+ <emphasis>_</emphasis>, and finally a suffix describing the
+ procedure's purpose. For example, a procedure to extract the
+ version from <productname>GDB</productname> is called
+ <symbol>gdb_version</symbol>.</para>
+
+ <para><command>runtest</command> itself calls only two of these
+ procedures, <symbol>${tool}_exit</symbol> and
+ <symbol>${tool}_version</symbol>; these procedures use no
+ arguments.</para>
+
+ <para>The other two procedures, <symbol>${tool}_start</symbol>
+ and <symbol>${tool}_load</symbol>}, are only called by the test
+ suites themselves (or by testsuite-specific initialization
+ code); they may take arguments or not, depending on the
+ conventions used within each test suite.</para>
+
+ <para>The usual convention for return codes from any of these
+ procedures (although it is not required by
+ <command>runtest</command>) is to return <emphasis>0</emphasis>
+ if the procedure succeeded, <emphasis>1</emphasis> if it failed,
+ and <emphasis>-1</emphasis> if there was a communication error.</para>
+
+ <sect3 id=toolstart xreflabel="${tool}_start procedure">
+ <title>${tool}_start Procedure</title>
+
+ <para>Starts a particular tool. For an interactive tool,
+ <function>${tool}_start</function> starts and initializes the
+ tool, leaving the tool up and running for the test cases; an
+ example is <function>gdb_start</function>, the start function
+ for GDB. For a batch oriented tool,
+ <function>${tool}_start</function> is optional; the recommended
+ convention is to let <function>${tool}_start</function> run the
+ tool, leaving the output in a variable called
+ <function>comp_output</function>. Test scripts can then analyze
+ <function>$comp_output</function> to determine the test results.
+ An example of this second kind of start function is
+ <function>gcc_start</function>, the start function for GCC.</para>
+
+ <para>DejaGnu itself does not call
+ <function>${tool}_start</function>. The initialization
+ module <function>${tool}_init.exp</function> must call
+ <function>${tool}_start</function> for interactive tools;
+ for batch-oriented tools, each individual test script calls
+ <function>${tool}_start</function> (or makes other
+ arrangements to run the tool).</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>${tool}_start</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=toolload xreflabel="${tool}_load procedure">
+ <title>${tool}_load Procedure</title>
+
+ <para>Loads something into a tool. For an interactive tool,
+ this conditions the tool for a particular test case; for
+ example, <function>gdb_load</function> loads a new
+ executable file into the debugger. For batch oriented tools,
+ <function>${tool}_load</function> may do nothing---though,
+ for example, the GCC support uses
+ <function>gcc_load</function> to load and run a binary on
+ the target environment. Conventionally,
+ <function>${tool}_load</function> leaves the output of any
+ program it runs in a variable called
+ <symbol>$exec_output</symbol>. Writing
+ <function>${tool}_load</function> can be the most complex
+ part of extending DejaGnu to a new tool or a new target, if
+ it requires much communication coding or file
+ downloading. Test scripts call
+ <function>${tool}_load</function>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>${tool}_load</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=toolexit xreflabel="${tool}_exit procedure">
+ <title>${tool}_exit Procedure</title>
+
+ <para>Cleans up (if necessary) before DejaGnu exits. For
+ interactive tools, this usually ends the interactive
+ session. You can also use <function>${tool}_exit</function>
+ to remove any temporary files left over from the
+ tests. <command>runtest</command> calls
+ <function>${tool}_exit</function>.<para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>${tool}_exit</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=toolversion xreflabel="${tool}_version procedure">
+ <title>${tool}_version Procedure</title>
+
+ <para>Prints the version label and number for
+ <symbol>${tool}</symbol>. This is called by the DejaGnu
+ procedure that prints the final summary report. The output
+ should consist of the full path name used for the tested
+ tool, and its version number.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>${tool}_version</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ </sect2>
+
+ <sect2 id=utilprocs>
+ <title>Utility Procedures</title>
+
+ <sect3 id=getdirs xreflabel="getdirs procedure">
+ <title>Getdirs Procedure</title>
+
+ <para>Returns a list of all the directories in the single
+ directory a single directory that match an optional
+ pattern. </para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>getdirs</function></funcdef>
+ <paramdef><parameter>rootdir</parameter>
+ <parameter>pattern</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>pattern</parameter></term>
+ <listitem><para>If you do not specify
+ <parameter>pattern</parameter>,
+ <function>Getdirs</function> assumes a default pattern of
+ <emphasis>*</emphasis>. You may use the common shell
+ wildcard characters in the pattern. If no directories
+ match the pattern, then a NULL string is
+ returned</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=find xreflabel="find procedure">
+ <title>Find Procedure</title>
+
+ <para>Search for files whose names match <emphasis>pattern</emphasis>
+ (using shell wildcard characters for filename expansion). Search
+ subdirectories recursively, starting at
+ <emphasis>rootdir</emphasis>. The result is the list of files whose
+ names match; if no files match, the result is empty. Filenames in the
+ result include all intervening subdirectory names. If no files match
+ the pattern, then a NULL string is returned.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>find</function></funcdef>
+ <paramdef><parameter>rootdir</parameter>
+ <parameter>pattern</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>rootdir</parameter></term>
+ <listitem><para>The top level directory to search the search
+ from.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>pattern</parameter></term>
+ <listitem><para>A csh "glob" style regular expression reprsenting
+ the files to find.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=which xreflabel="which procedure">
+ <title>Which Procedure</title>
+
+ <para>Searches the execution path for an executable file
+ <emphasis>binary</emphasis>, like the the BSD <command>which</command>
+ utility. This procedure uses the shell environment variable
+ <emphasis>PATH</emphasis>. It returns <emphasis>0</emphasis> if the
+ binary is not in the path, or if there is no <emphasis>PATH</emphasis>
+ environment variable. If <command>binary</command> is in the path, it
+ returns the full path to <command>binary</command>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>which</function></funcdef>
+ <paramdef><parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>binary</parameter></term>
+ <listitem><para>The executable program or shell script to look
+ for.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=grep xreflabel="grep procedure">
+ <title>Grep Procedure</title>
+
+ <para>Search the file called <filename>filename</filename> (a fully
+ specified path) for lines that contain a match for regular expression
+ <emphasis>regexp</emphasis>. The result is a list of all the lines that
+ match. If no lines match, the result is an empty string. Specify
+ <emphasis>regexp</emphasis> using the standard regular expression style
+ used by the Unix utility program grep.</para>
+
+ <para>Use the optional third argument <emphasis>line</emphasis> to
+ start lines in the result with the line number in
+ <filename>filename</filename>. (This argument is simply an option
+ flag; type it just as shown <option>--line</option>.)
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>grep</function></funcdef>
+ <paramdef><parameter>filename</parameter>
+ <parameter>regexp</parameter>
+ <parameter>--line</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>filename</parameter></term>
+ <listitem><para>The file to search.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>regexp</parameter></term>
+ <listitem><para>The Unix style regular expression (as used by the
+ <command>grep</command> Unix utility) to search
+ for.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>--line</parameter></term>
+ <listitem><para>Prefix the line number to each line where the
+ regexp matches.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect3>
+ <sect3 id=prune xreflabel="prune procedure">
+ <title>Prune Procedure</title>
+
+ <para>Remove elements of the Tcl list <emphasis>list</emphasis>.
+ Elements are fields delimited by spaces. The result is a copy of
+ list, without any elements that match <emphasis>pattern</emphasis>.
+ You can use the common shell wildcard characters to specify the
+ pattern.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>prune</function></funcdef>
+ <paramdef><parameter>list</parameter>
+ <parameter>pattern</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>list</parameter></term>
+ <listitem><para>A Tcl list containing the original data. Commonly
+ this is the output of a batch executed command, like running a
+ compiler.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>pattern</parameter></term>
+ <listitem><para>The csh shell "glob" style pattern to search
+ for.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect3>
+
+ <sect3 id=slay xreflabel="slay procedure">
+ <title>Slay Procedure</title>
+
+ <para>This look in the process table for <emphasis>name</emphasis>
+ and send it a unix SIGINT, killing the process. This will only work
+ under NT if you have Cygwin or another Unix system for NT
+ installed.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>slay</function></funcdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem><para>The name of the program to kill.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect3>
+
+ <sect3 id=absolute xreflabel="absolute procedure">
+ <title>Absolute Procedure</title>
+
+ <para>This procedure takes the relative <emphasis>path</emphasis>,
+ and converts it to an absolute path.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>absolute</function></funcdef>
+ <paramdef><parameter>path</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>path</parameter></term>
+ <listitem><para>The path to convert.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=psource xreflabel="psource procedure">
+ <title>Psource Procedure</title>
+
+ <para>This sources the file <emphasis>filename</emphasis>, and traps
+ all errors. It also ignores all extraneous output. If there was an
+ error it returns a <emphasis>1</emphasis>, otherwise it returns a
+ <emphasis>0</emphasis>.
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>psource</function></funcdef>
+ <paramdef><parameter>file</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>filename</parameter></term>
+ <listitem><para>The filename to Tcl script to
+ source.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=runtestfilep xreflabel="runtest_file_p procedure">
+ <title>Runtest_file_p Procedure</title>
+
+ <para>Search <emphasis>runtest</emphasis>s for
+ <emphasis>testcase</emphasis> and return <emphasis>1</emphasis> if
+ found, <emphasis>0</emphasis> if not. <emphasis>runtests</emphasis>
+ is a list of two elements. The first is the pathname of the
+ testsuite expect script running. The second is a copy of what was on
+ the right side of the <emphasis>=</emphasis> if
+ <programlisting>foo.exp="..."</programlisting>" was specified, or
+ an empty string if no such argument is present. This is used by tools
+ like compilers where each testcase is a file.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>runtest_file_p</function></funcdef>
+ <paramdef><parameter>runtests</parameter>
+ <parameter>testcase</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>runtests</parameter></term>
+ <listitem><para>The pathname of the testsuite expect script
+ running</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>testcase</parameter></term>
+ <listitem><para>The test case filename.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=diff xreflabel="diff procedure">
+ <title>Diff Procedure</title>
+
+ <para>Compares the two files and returns a <emphasis>1</emphasis> if
+ they match, or a <emphasis>0</emphasis> if they don't. If
+ <symbol>verbose</symbol> is set, then it'll print the differences to
+ the screen.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>diff</function></funcdef>
+ <paramdef><parameter>file_1</parameter>
+ <parameter>file_2</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>file_1</parameter></term>
+ <listitem><para>The first file to compare.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>file_2</parameter></term>
+ <listitem><para>The second file to compare.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=setenv xreflabel="setenv procedure">
+ <title>Setenv Procedure</title>
+
+ <para>Sets the environment variable <emphasis>var</emphasis> to the
+ value <emphasis>val</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>setenv</function></funcdef>
+ <paramdef><parameter>var</parameter>
+ <parameter>val</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>var</parameter></term>
+ <listitem><para>The environment variable to set.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>val</parameter></term>
+ <listitem><para>The value to set the variable to.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <sect3 id=unsetenv xreflabel="unsetenv procedure">
+ <title>unsetenv Procedure</title>
+
+ <para>Unsets the environment variable
+ <emphasis>var</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>unsetenv</function></funcdef>
+ <paramdef><parameter>var</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>var</parameter></term>
+ <listitem><para>The environment variable to
+ unset.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=getenv xreflabel="getenv procedure">
+ <title>Getenv Procedure</title>
+
+ <para>Returns the value of <emphasis>var</emphasis> in the
+ environment if it exists, otherwise it returns NULL.
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>getenv</function></funcdef>
+ <paramdef><parameter>var</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>var</parameter></term>
+ <listitem><para>The environment variable to get the value
+ of.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <sect3 id=prunesystemcrud xreflabel="prune_system_crud procedure">
+ <title>Prune_system_crud Procedure</title>
+
+ <para>For system <emphasis>system</emphasis>, delete text the host or
+ target operating system might issue that will interfere with pattern
+ matching of program output in <emphasis>text</emphasis>. An example
+ is the message that is printed if a shared library is out of
+ date.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>prune_system_crud</function></funcdef>
+ <paramdef><parameter>system</parameter>
+ <parameter>test</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>system</parameter></term>
+ <listitem><para>The system error messages to look for to screen out
+ .</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>text</parameter></term>
+ <listitem><para>The Tcl variable containing the
+ text.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ </sect2>
+
+ <sect2 id=libgloss xreflabel="Libgloss">
+ <title>Libgloss, A Free BSP</title>
+
+ <para>Libgloss is a free <firstterm>BSP</firstterm> (Board Support
+ Package) commonly used with GCC and G++ to produce a fully linked
+ executable image for an embedded systems.</para>
+
+ <sect3 id=libglosslinkflags xreflabel="libgloss_link_flags procedure">
+ <title>Libgloss_link_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>libgloss_link_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=libglossincludeflags xreflabel="libgloss_include_flags
+ procedure">
+ <title>Libgloss_include_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>libgloss_include_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=newliblinkflags xreflabel="newlib_link_flags procedure">
+ <title>Newlib_link_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>newlib_link_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=newlibincludeflags xreflabel="newlib_include_flags
+ procedure">
+ <title>Newlib_include_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>newlib_include_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=libioincludeflags xreflabel="libio_include_flags
+ procedure">
+ <title>Libio_include_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>libio_include_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=libiolinkflags xreflabel="libio_link_flags procedure">
+ <title>Libio_link_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>libio_link_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=gxxincludeflags xreflabel="g++_include_flags procedure">
+ <title>G++_include_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>g++_include_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=gxxlinkflags xreflabel="g++_link_flags procedure">
+ <title>G++_link_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>g++_link_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=libstdcxxincludeflags xreflabel="libstdc++_include_flags
+ procedure">
+ <title>Libstdc++_include_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>libstdc++_include_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=libstdcxxlinkflags xreflabel="libstdc++_link_flags
+ procedure">
+ <title>Libstdc++_link_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>libstdc++_link_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=getmultilibs xreflabel="get_multilibs procedure">
+ <title>Get_multilibs Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>get_multilibs</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=findbinutilsprog xreflabel="find_binutils_prog procedure">
+ <title>Find_binutils_prog Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>find_binutils_prog</function></funcdef>
+ <paramdef><parameter>name</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=findgcc xreflabel="find_gcc procedure">
+ <title>Find_gcc Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>find_gcc</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=findgcj xreflabel="find_gcj procedure">
+ <title>Find_gcj Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>find_gcj</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=findgxx xreflabel="find_g++ procedure">
+ <title>Find_g++ Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>find_g++</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=findg77 xreflabel="find_g77 procedure">
+ <title>Find_g77 Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>find_g77</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=processmultiliboptions xreflabel="process_multilib_options
+ procedure">
+ <title>Process_multilib_options Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>process_multilib_options</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=addmultiliboption xreflabel="add_multilib_option
+ procedure">
+ <title>Add_multilib_option Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>add_multilib_option</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=findgas xreflabel="find_gas procedure">
+ <title>Find_gas Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>find_gas</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=findld xreflabel="find_ld procedure">
+ <title>Find_ld Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>find_ld</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ </sect3>
+
+ <sect3 id=buildwrapper xreflabel="build_wrapper procedure">
+ <title>Build_wrapper Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>build_wrapper</function></funcdef>
+ <paramdef><parameter>gluefile</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>gluefile</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=winsupincludeflags xreflabel="winsup_include_flags
+ procedure">
+ <title>Winsup_include_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>winsup_include_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=winsuplinkflags xreflabel="winsup_link_flags procedure">
+ <title>Winsup_link_flags Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>winsup_link_flags</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ </sect2>
+
+ <sect2 id=debugprocs xreflabel="Debugging Procedures">
+ <title>Procedures for debugging your Tcl code.</title>
+
+ <para><filename>lib/debugger.exp</filename>defines these utility
+ procedures:</para>
+
+ <sect3 id=dumpvars xreflabel="dumpvars procedure">
+ <title>Dumpvars Procedure</title>
+
+ <para>This takes a csh style regular expression (glob rules) and prints
+ the values of the global variable names that match. It is abbreviated
+ as <emphasis>dv</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>dumpvars</function></funcdef>
+ <paramdef><parameter>vars</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>vars</parameter></term>
+ <listitem><para>The variables to dump.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=dumplocals xreflabel="dumplocals procedure">
+ <title>Dumplocals Procedure</title>
+
+ <para>This takes a csh style regular expression (glob rules) and
+ prints the values of the local variable names that match. It is
+ abbreviated as <emphasis>dl</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>dumplocals</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=dumprocs xreflabel="dumprocs procedure">
+ <title>Dumprocs Procedure</title>
+
+ <para>This takes a csh style regular expression (glob rules) and
+ prints the body of all procs that match. It is abbreviated as
+ <emphasis>dp</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>dumprocs</function></funcdef>
+ <paramdef><parameter>pattern</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>pattern</parameter></term>
+ <listitem><para>The csh "glob" style pattern to look
+ for.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=dumpwatch xreflabel="dumpwatch procedure">
+ <title>Dumpwatch Procedure</title>
+
+ <para>This takes a csh style regular expression (glob rules) and
+ prints all the watchpoints. It is abbreviated as
+ <emphasis>dw</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>dumpwatch</function></funcdef>
+ <paramdef><parameter>pattern</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>pattern</parameter></term>
+ <listitem><para>The csh "glob" style pattern to look
+ for.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=watcharray xreflabel="watcharray procedure">
+ <title>Watcharray Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>watcharray</function></funcdef>
+ <paramdef><parameter>element</parameter>
+ <parameter>type</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem><para>The csh "glob" style pattern to look
+ for.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=watchvar xreflabel="watchvar procedure">
+ <title>Watchvar Procedure</title>
+
+ <para></para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>watchvar</function></funcdef>
+ <paramdef><parameter>var</parameter>
+ <parameter>type</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter></parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=watchunset xreflabel="watchunset procedure">
+ <title>Watchunset Procedure</title>
+
+ <para>This breaks program execution when the variable
+ <symbol>var</symbol> is unset. It is abbreviated as
+ <emphasis>wu</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>watchunset</function></funcdef>
+ <paramdef><parameter>arg</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=watchwrite xreflabel="watchwrite procedure">
+ <title>Watchwrite Procedure</title>
+
+ <para>This breaks program execution when the variable
+ <symbol>var</symbol> is written. It is abbreviated as
+ <emphasis>ww</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>watchwrite</function></funcdef>
+ <paramdef><parameter>var</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>var</parameter></term>
+ <listitem><para>The variable to watch.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=watchread xreflabel="watchread procedure">
+ <title>Watchread Procedure</title>
+
+ <para>This breaks program execution when the variable
+ <symbol>var</symbol> is read. It is abbreviated as
+ <emphasis>wr</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>watchread</function></funcdef>
+ <paramdef><parameter>var</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>var</parameter></term>
+ <listitem><para>The variable to watch.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=watchdel xreflabel="watchdel procedure">
+ <title>Watchdel Procedure</title>
+
+ <para>This deletes a the watchpoint from the watch list. It is
+ abbreviated as <emphasis>wd</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>watchdel</function></funcdef>
+ <paramdef><parameter>args</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>args</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=print xreflabel="print procedure">
+ <title>Print Procedure</title>
+
+ <para>This prints the value of the variable
+ <parameter>var</parameter>. It is abbreviated as
+ <emphasis>p</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>print</function></funcdef>
+ <paramdef><parameter>var</parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>var</parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 id=quit xreflabel="quit procedure">
+ <title>Quit Procedure</title>
+
+ <para>This makes runtest exit. It is abbreviated as
+ <emphasis>q</emphasis>.</para>
+
+ <funcsynopsis role="tcl">
+ <funcdef><function>quit</function></funcdef>
+ <paramdef><parameter></parameter></paramdef>
+ </funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><parameter></parameter></term>
+ <listitem><para></para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id=filemap>
+ <title>File Map</title>
+
+ <para>This is a map of the files in DejaGnu.</para>
+
+ <itemizedlist>
+ <listitem><para>runtest</para></listitem>
+ <listitem><para>runtest.exp</para></listitem>
+ <listitem><para>stub-loader.c</para></listitem>
+ <listitem><para>testglue.c</para></listitem>
+ <listitem><para>config</para></listitem>
+ <listitem><para>baseboards</para></listitem>
+ <listitem><para>lib/debugger.exp</para></listitem>
+ <listitem><para>lib/dg.exp</para></listitem>
+ <listitem><para>lib/framework.exp</para></listitem>
+ <listitem><para>lib/ftp.exp</para></listitem>
+ <listitem><para>lib/kermit.exp</para></listitem>
+ <listitem><para>lib/libgloss.exp</para></listitem>
+ <listitem><para>lib/mondfe.exp</para></listitem>
+ <listitem><para>lib/remote.exp</para></listitem>
+ <listitem><para>lib/rlogin.exp</para></listitem>
+ <listitem><para>lib/rsh.exp</para></listitem>
+ <listitem><para>lib/standard.exp</para></listitem>
+ <listitem><para>lib/target.exp</para></listitem>
+ <listitem><para>lib/targetdb.exp</para></listitem>
+ <listitem><para>lib/telnet.exp</para></listitem>
+ <listitem><para>lib/tip.exp</para></listitem>
+ <listitem><para>lib/util-defs.exp</para></listitem>
+ <listitem><para>lib/utils.exp</para></listitem>
+ <listitem><para>lib/xsh.exp</para></listitem>
+ </itemizedlist>
+
+ </sect1>
+
+</chapter>
diff --git a/dejagnu/doc/runtest.1 b/dejagnu/doc/runtest.1
new file mode 100644
index 00000000000..861ec66cad6
--- /dev/null
+++ b/dejagnu/doc/runtest.1
@@ -0,0 +1,118 @@
+.TH runtest 1 "08 Dec 1998"
+.SH NAME
+runtest \- the DejaGnu test driver program
+.SH SYNOPSIS
+.B runtest
+[ options ]
+.SH DESCRIPTION
+.I DejaGnu
+is a framework for running test suites on GNU tools. It is written in
+expect, which uses TCL (Tool command language).
+.B runtest
+is the test driver program; use it to control what tests to run,
+and variations on how to run them.
+
+You can find a comprehensive description of DejaGnu and \fBruntest\fR in
+.I
+The DejaGnu Testing Framework
+or its Info version,
+.BR dejagnu.info .
+.SH OPTIONS
+.TP
+.B --all
+Print all test output to screen. By default, only unexpected results are
+displayed.
+.TP
+.BI --baud \ rate
+Set the baud rate for a serial line connection. Some serial interface
+programs (like \fBtip\fR) don't use this value but instead use a separate
+initialization file.
+.TP
+.BI --connect \ type
+The type of connection to use. The choices are
+.BR rlogin ,
+.BR telnet ,
+.BR rsh ,
+.BR kermit ,
+.BR tip
+and
+.BR mondfe .
+.TP
+.B --debug
+Turn on
+.B expect
+internal debugging output. All output is logged to
+a file called \fBdbg.out\fR.
+The output of the \fB--strace\fR also goes into this file.
+.TP
+.B --help
+Prints out a help screen and then exits.
+.TP
+.BI --host \ type
+The configuration string for the host.
+.TP
+.BI --ignore \ test1.exp\ test2.exp\ ...
+Do not run the specified tests.
+Electronic mail addresses to receive test results.
+.TP
+.BI --name \ hostname
+The network hostname of the target board.
+.TP
+.BI --objdir \ path
+\fIpath\fR is a directory containing compiled test code.
+.TP
+.BI --outdir \ directory
+The name of a directory for test log output.
+.TP
+.B --reboot
+Reboot the target board when \fBruntest\fR initializes
+(if supported).
+.TP
+.BI --srcdir \ path
+\fIpath\fR is a directory containing test directories.
+.TP
+.BI --strace \ N
+Turns on
+.B expect
+internal tracing to \fIN\fR levels deep.
+.TP
+.BI --target \ type
+The configuration string for the target.
+.TP
+.BI --tool \ toolname
+Specify the tool to be tested. \fItoolname\fR controls the test suite
+applied, and the associated initialization module.
+.TP
+.B --verbose,\ -v
+Turns on more debugging output from test cases and DejaGnu utility code.
+Use more than once to increase output further.
+.TP
+.B --version,\ -V
+Prints out the versions of DejaGnu, expect and Tcl.
+.TP
+.B -D[number]
+Activate the Tcl debugger.\fBnumber\fR can be either 1 or 0. If it is
+1, then the expect shell will break when it starts to run. All ^C's
+drop DejaGnu back to the debugger prompt. A 0 starts DejaGnu like
+normal, but a ^C drops to the debugger prompt.
+.TP 0
+Any file name on the command line is assumed to be a subset
+of the test names to run. Usually these are the names of the
+expect test driver, ie... special.exp.
+
+Makefile style variables are used to specify tool names and their
+flags; these and other configuration dependent values are saved in the
+file \fBsite.exp\fR, created during configuration.
+.SH EXIT CODES
+.B runtest
+sets the exit code to 1 if any of the tests failed, or
+sets it to 0 if all the tests passed.
+.SH SEE ALSO
+.I The DejaGnu Testing Framework
+.RB ( dejagnu.info ).
+This is the DejaGnu manual; its source is the SGML files
+.B
+doc/*.sgml.
+in the DejaGnu distribution.
+.SH AUTHOR
+Rob Savoye (rob@welcomehome.org)
diff --git a/dejagnu/doc/user.sgml b/dejagnu/doc/user.sgml
new file mode 100644
index 00000000000..2154d7401e8
--- /dev/null
+++ b/dejagnu/doc/user.sgml
@@ -0,0 +1,2355 @@
+ <chapter id=runningtests>
+ <title>Running Tests</title>
+
+ <para>There are two ways to execute a test suite. The most
+ common way is when there is existing support in the
+ <filename>Makefile</filename>. This support consists of a
+ <emphasis>check</emphasis> target. The other way is to execute the
+ <command>runtest</command> program directly. To run
+ <command>runtest</command> directcly from the command line requires
+ either all the correct options, or the <xref linkend=local> must be setup
+ correctly.</para>
+
+ <sect1 id=makecheck xreflabel="Make Check">
+ <title>Make check</title>
+
+ <para>To run tests from an existing collection, first use
+ <command>configure</command> as usual to set up the
+ build directory. Then try typing:</para>
+
+ <screen>
+ make check
+ </screen>
+
+ <para>If the <emphasis>check</emphasis> target exists, it
+ usually saves you some trouble. For instance, it can set up any
+ auxiliary programs or other files needed by the tests. The most
+ common file the check builds is the
+ <emphasis>site.exp</emphasis>. The site.exp file contains
+ various variables that DejaGnu used to dertermine the
+ configuration of the program being tested. This is mostly for
+ supporting remote testing.</para>
+
+ <para>The <emphasis>check</emphasis> target is supported by GNU
+ <productname>Automake</productname>. To have DejaGnu support added to your
+ generated <filename>Makefile.in</filename>, just add the keyword
+ dejagnu to the AUTOMAKE_OPTIONS variable in your
+ <filename>Makefile.am</filename> file.</para>
+
+ <para>Once you have run <emphasis>make check</emphasis> to build
+ any auxiliary files, you can invoke the test driver
+ <command>runtest</command> directly to repeat the tests.
+ You will also have to execute <command>runtest</command>
+ directly for test collections with no
+ <emphasis>check</emphasis> target in the
+ <filename>Makefile</filename>.</para>
+
+ </sect1>
+
+ <sect1 id=runtest xreflabel="Runtest">
+ <title>Runtest</title>
+
+ <para><command>runtest</command> is the executable test driver
+ for DejaGnu. You can specify two kinds of things on the
+ <command>runtest</command> command line: command line options,
+ and Tcl variables for the test scripts. The options are listed
+ alphabetically below.</para>
+
+ <para><command>runtest</command> returns an exit code of
+ <emphasis>1</emphasis> if any test has an unexpected result; otherwise
+ (if all tests pass or fail as expected) it returns <emphasis>0</emphasis>
+ as the exit code.</para>
+
+ <sect2 id=outputs xreflabel="Output States">
+ <title>Output States</title>
+
+ <para><filename>runtest</filename> flags the outcome of each
+ test as one of these cases. <xref linkend=posix> for a
+ discussion of how POSIX specifies the meanings of these
+ cases.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>PASS</term>
+ <listitem><para>The most desirable outcome: the test succeeded, and
+ was expected to succeed.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>XPASS</term>
+ <listitem><para>A pleasant kind of failure: a test was expected to
+ fail, but succeeded. This may indicate progress; inspect the test
+ case to determine whether you should amend it to stop expecting
+ failure.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>FAIL</term>
+ <listitem><para>A test failed, although it was expected to succeed.
+ This may indicate regress; inspect the test case and the failing
+ software to ocate the bug.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>XFAIL</term>
+ <listitem><para>A test failed, but it was expected to fail. This
+ result indicates no change in a known bug. If a test fails because
+ the operating system where the test runs lacks some facility required
+ by the test, the outcome is <emphasis>UNSUPPORTED</emphasis>
+ instead.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>UNRESOLVED</term>
+ <listitem><para>Output from a test requires manual inspection; the
+ test suite could not automatically determine the outcome. For
+ example, your tests can report this outcome is when a test does not
+ complete as expected.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>UNTESTED</term>
+ <listitem><para>A test case is not yet complete, and in particular
+ cannot yet produce a <emphasis>PASS</emphasis> or
+ <emphasis>FAIL</emphasis>. You can also use this outcome in dummy
+ ``tests'' that note explicitly the absence of a real test case for a
+ particular property.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>UNSUPPORTED</term>
+ <listitem><para>A test depends on a conditionally available feature
+ that does not exist (in the configured testing environment). For
+ example, you can use this outcome to report on a test case that does
+ not work on a particular target because its operating system support
+ does not include a required subroutine.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>runtest may also display the following messages:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>ERROR</term>
+ <listitem><para>Indicates a major problem (detected by the test case
+ itself) in running the test. This is usually an unrecoverable error,
+ such as a missing file or loss of communication to the target. (POSIX
+ test suites should not emit this message; use
+ <emphasis>UNSUPPORTED</emphasis>, <emphasis>UNTESTED</emphasis>, or
+ <emphasis>UNRESOLVED</emphasis> instead, as
+ appropriate.)</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>WARNING</term>
+ <listitem><para>Indicates a possible problem in running the
+ test. Usually warnings correspond to recoverable errors, or display
+ an important message about the following tests.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>NOTE</term>
+ <listitem><para>An informational message about the test
+ case.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id=invoking xreflabel="Invoking Runtest">
+ <title>Invoking Runtest</title>
+
+ <para>This is the full set of command line options that
+ <filename>runtest</filename> recognizes. Arguments may be
+ abbreviated to the shortest unique string.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>--all</option> (-a)</term>
+ <listitem><para>Display all test output. By default,
+ <emphasis>runtest</emphasis> shows only the output of tests that
+ produce unexpected results; that is, tests with status
+ <emphasis>FAIL</emphasis> (unexpected failure),
+ <emphasis>XPASS</emphasis> (unexpected success), or
+ <emphasis>ERROR</emphasis> (a severe error in the test case
+ itself). Specify <emphasis>--all</emphasis> to see output for tests
+ with status <emphasis>PASS</emphasis> (success, as expected)
+ <emphasis>XFAIL</emphasis> (failure, as expected), or
+ <emphasis>WARNING</emphasis> (minor error in the test case
+ itself).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--build [string]</option></term>
+ <listitem><para><emphasis>string</emphasis> is a full configuration
+ ``triple'' name as used by <command>configure</command>. This
+ is the type of machine DejaGnu and the tools to be tested are built
+ on. For a normal cross this is the same as the host, but for a
+ canadian cross, they are seperate.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--host [string]</option></term>
+ <listitem><para><symbol>string</symbol> is a full configuration
+ ``triple'' name as used by <emphasis>configure</emphasis>. Use this
+ option to override the default string recorded by your
+ configuration's choice of host. This choice does not change how
+ anything is actually configured unless --build is also specified; it
+ affects <emphasis>only</emphasis> DejaGnu procedures that compare the
+ host string with particular values. The procedures
+ <emphasis>ishost</emphasis>, <emphasis>istarget</emphasis>,
+ <emphasis>isnative</emphasis>, and <emphasis>setup</emphasis>xfail}
+ are affected by <emphasis>--host</emphasis>. In this usage,
+ <emphasis>host</emphasis> refers to the machine that the tests are to
+ be run on, which may not be the same as the
+ <emphasis>build</emphasis> machine. If <emphasis>--build</emphasis>
+ is also specified, then <emphasis>--host</emphasis> refers to the
+ machine that the tests wil, be run on, not the machine DejaGnu is run
+ on.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--host_board [name]</option></term>
+ <listitem><para>The host board to use.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--target [string]</option></term>
+ <listitem><para>Use this option to override the default setting
+ (running native tests). <emphasis>string</emphasis> is a full
+ configuration ``triple'' name of the form
+ <emphasis>cpu-vendor-os</emphasis> as used by
+ <command>configure</command>. This option changes the
+ configuration <emphasis>runtest</emphasis> uses for the default tool
+ names, and other setup information.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--debug</option> (-de)</term>
+ <listitem><para>Turns on the <emphasis>expect</emphasis> internal
+ debugging output. Debugging output is displayed as part of the
+ <emphasis>runtest</emphasis> output, and logged to a file called
+ <filename>dbg.log</filename>. The extra debugging output does
+ <emphasis>not</emphasis> appear on standard output, unless the
+ verbose level is greater than 2 (for instance, to see debug output
+ immediately, specify <emphasis>--debug</emphasis>-v -v}). The
+ debugging output shows all attempts at matching the test output of
+ the tool with the scripted patterns describing expected output. The
+ output generated with <emphasis>--strace</emphasis> also goes into
+ <filename>dbg.log</filename>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--help</option> (-he)</term>
+ <listitem><para>Prints out a short summary of the
+ <emphasis>runtest</emphasis> options, then exits (even if you also
+ specify other options).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--ignore [name(s)] </option></term>
+ <listitem><para>The names of specific tests to
+ ignore.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--objdir [path]</option></term>
+ <listitem><para>Use <emphasis>path</emphasis> as the top directory
+ containing any auxiliary compiled test code. This defaults to
+ <filename>.</filename>. Use this option to locate pre-compiled test
+ code. You can normally prepare any auxiliary files needed with
+ <emphasis>make</emphasis>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--outdir [path]</option></term>
+ <listitem><para>Write output logs in directory
+ <filename>path</filename>. The default is <emphasis>.},
+ the</emphasis> directory where you start
+ <emphasis>runtest</emphasis>. This option affects only the summary
+ and the detailed log files
+ <filename>tool.sum</filename> and
+ <filename>tool.log</filename>. The DejaGnu debug
+ log <filename>dbg.log</filename> always appears (when requested) in
+ the local directory.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--reboot [name]</option></term>
+ <listitem><para>Reboot the target board when
+ <emphasis>runtest</emphasis> initializes. Usually, when running tests
+ on a separate target board, it is safer to reboot the target to be
+ certain of its state. However, when developing test scripts,
+ rebooting takes a lot of time.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--srcdir [path]</option></term>
+ <listitem><para>Use <filename>path</filename> as the top directory
+ for test scripts to run. <emphasis>runtest</emphasis> looks in this
+ directory for any subdirectory whose name begins with the toolname
+ (specified with <emphasis>--tool</emphasis>). For instance, with
+ <emphasis>--tool</emphasis>gdb}, <emphasis>runtest</emphasis> uses
+ tests in subdirectories <filename>gdb.*</filename> (with the usual
+ shell-like filename expansion). If you do not use
+ <emphasis>--srcdir</emphasis>, <emphasis>runtest</emphasis> looks for
+ test directories under the current working
+ directory.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--strace [number]</option></term>
+ <listitem><para>Turn on internal tracing for
+ <emphasis>expect</emphasis>, to n levels deep. By adjusting the
+ level, you can control the extent to which your output expands
+ multi-level Tcl statements. This allows you to ignore some levels of
+ <emphasis>case</emphasis> or <emphasis>if</emphasis> statements.
+ Each procedure call or control structure counts as one ``level''. The
+ output is recorded in the same file, <filename>dbg.log</filename>,
+ used for output from <emphasis>--debug</emphasis>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--connect [program]</option></term>
+ <listitem><para>Connect to a target testing environment as specified
+ by <emphasis>type</emphasis>, if the target is not the computer
+ running <emphasis>runtest</emphasis>. For example, use
+ <emphasis>--connect</emphasis> to change the program used to connect
+ to a ``bare board'' boot monitor. The choices for
+ <emphasis>type</emphasis> in the DejaGnu 1.4 distribution are
+ <emphasis>rlogin</emphasis>, <emphasis>telnet</emphasis>,
+ <emphasis>rsh</emphasis>, <emphasis>tip</emphasis>,
+ <emphasis>kermit</emphasis>, and <emphasis>mondfe</emphasis>.</para>
+
+ <para>The default for this option depends on the configuration most
+ convenient communication method available, but often other
+ alternatives work as well; you may find it useful to try alternative
+ connect methods if you suspect a communication problem with your
+ testing target.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--baud [number]</option></term>
+ <listitem><para>Set the default baud rate to something other than
+ 9600. (Some serial interface programs, like <emphasis>tip</emphasis>,
+ use a separate initialization file instead of this
+ value.)</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--target_board [name(s)]</option></term>
+ <listitem><para>The list of target boards to run tests
+ on.</para></listitem>
+ </varlistentry>
+
+ <varlistentry id=tool-opt>
+ <term><option>--tool[name(s)]</option></term>
+ <listitem><para>Specifies which test suite to run, and what
+ initialization module to use. <option>--tool</option> is used
+ <emphasis>only</emphasis> for these two purposes. It is
+ <emphasis>not</emphasis> used to name the executable program to
+ test. Executable tool names (and paths) are recorded in
+ <filename>site.exp</filename> and you can override them by specifying
+ Tcl variables on the command line.</para>
+
+ <para>For example, including "<option>--tool</option> gcc" on the
+ <emphasis>runtest</emphasis> command line runs tests from all test
+ subdirectories whose names match <filename>gcc.*</filename>, and uses
+ one of the initialization modules named
+ <filename>config/*-gcc.exp</filename>. To specify the name of the
+ compiler (perhaps as an alternative path to what
+ <emphasis>runtest</emphasis> would use by default), use
+ <emphasis>GCC=binname</emphasis> on the <emphasis>runtest</emphasis>
+ command line.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--tool_exec [name]</option></term>
+ <listitem><para>The path to the tool executable to
+ test.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--tool_opts [options]</option></term>
+ <listitem><para>A list of additional options to pass to the
+ tool.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--verbose</option> (-v)</term>
+ <listitem><para>Turns on more output. Repeating this option increases
+ the amount of output displayed. Level one (<emphasis>-v</emphasis>)
+ is simply test output. Level two (<emphasis>-v</emphasis>-v}) shows
+ messages on options, configuration, and process control. Verbose
+ messages appear in the detailed (<filename>*.log</filename>) log
+ file, but not in the summary (<filename>*.sum</filename>) log
+ file.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--version</option> (-V)</term>
+ <listitem><para>Prints out the version numbers of DejaGnu,
+ <emphasis>expect</emphasis> and Tcl, and exits without running any
+ tests.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--D[0-1]</option></term>
+ <listitem><para>Start the internal Tcl debugger. The Tcl debugger
+ supports breakpoints, single stepping, and other common debugging
+ activities. See the document "Debugger for Tcl Applications} by Don
+ Libes. (Distributed in PostScript form with
+ <emphasis>expect</emphasis> as the file
+ <filename>expect/tcl-debug.ps.</filename>. If you specify
+ <emphasis>-D1</emphasis>, the <emphasis>expect</emphasis> shell stops
+ at a breakpoint as soon as DejaGnu invokes it. If you specify
+ <emphasis>-D0</emphasis>, DejaGnu starts as usual, but you can enter
+ the debugger by sending an interrupt (e.g. by typing
+ <keycombo><keycap>C</keycap><keycap>c</keycap></keycombo>).
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>testfile</filename>.exp[=arg(s)]</term>
+ <listitem><para>Specify the names of testsuites to run. By default,
+ <emphasis>runtest</emphasis> runs all tests for the tool, but you can
+ restrict it to particular testsuites by giving the names of the
+ <emphasis>.exp expect</emphasis> scripts that control
+ them. <emphasis>testsuite</emphasis>.exp may not include path
+ information; use plain filenames.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>testfile</filename>.exp="testfile1 ..."</term>
+ <listitem><para>Specify a subset of tests in a suite to run. For
+ compiler or assembler tests, which often use a single
+ <emphasis>.exp</emphasis> script covering many different source
+ files, this option allows you to further restrict the tests by
+ listing particular source files to compile. Some tools even support
+ wildcards here. The wildcards supported depend upon the tool, but
+ typically they are <emphasis>?</emphasis>, <emphasis>*</emphasis>,
+ and <emphasis>[chars]</emphasis>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>tclvar</symbol>=value</term>
+ <listitem><para>You can define Tcl variables for use by your test
+ scripts in the same style used with <emphasis>make</emphasis> for
+ environment variables. For example, <emphasis>runtest
+ GDB=gdb.old</emphasis> defines a variable called
+ <command>GDB</command>; when your scripts refer to
+ <symbol>$GDB</symbol> in this run, they use the value
+ <emphasis>gdb.old</emphasis>.</para>
+
+ <para>The default Tcl variables used for most tools are defined in
+ the main DejaGnu <emphasis>Makefile</emphasis>; their values are
+ captured in the <filename>site.exp</filename> file.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id=common xreflabel="Common Operations">
+ <title>Common Options</title>
+
+ <para>Typically, you don't need must to use any command-line options.
+ <option>--tool</option> used is only required when there are more than
+ one test suite in the same directory. The default options are in the
+ local site.exp file, created by "make site.exp".</para>
+
+ <para>For example, if the directory <filename>gdb/testsuite</filename>
+ contains a collection of DejaGnu tests for GDB, you can run them like
+ this:</para>
+
+ <screen>
+ eg$ cd gdb/testsuite
+ eg$ runtest --tool gdb
+ </screen>
+
+ <para>Test output follows, ending with:</para>
+
+ <screen>
+ === gdb Summary ===
+
+ # of expected passes 508
+ # of expected failures 103
+ /usr/latest/bin/gdb version 4.14.4 -nx
+ </screen>
+
+ <para>You can use the option <emphasis>--srcdir</emphasis> to point to
+ some other directory containing a collection of tests:</para>
+
+ <screen>
+ eg$ runtest--srcdir /devo/gdb/testsuite
+ </screen>
+
+ <para>By default, <command>runtest</command> prints only the
+ names of the tests it runs, output from any tests that have unexpected
+ results, and a summary showing how many tests passed and how many
+ failed. To display output from all tests (whether or not they behave
+ as expected), use the <emphasis>--all</emphasis> option. For more
+ verbose output about processes being run, communication, and so on, use
+ <emphasis>--verbose</emphasis>. To see even more output, use multiple
+ <emphasis>--verbose</emphasis> options. for a more detailed explanation
+ of each <command>runtest</command> option.
+
+ <para>Test output goes into two files in your current directory:
+ summary output in <filename>tool.sum</filename>,
+ and detailed output in <filename>
+ tool.log</filename>. (<emphasis>tool</emphasis>
+ refers to the collection of tests; for example, after a run with
+ <emphasis>--tool</emphasis> gdb, look for output files
+ <filename>gdb.sum</filename> and <filename>gdb.log</filename>.)
+ </sect2>
+ </sect1>
+
+ <sect1 id=outputfiles xreflabel="Output Files">
+
+ <title>The files DejaGnu produces.</title>
+
+ <para>DejaGnu always writes two kinds of output files: summary
+ logs and detailed logs. The contents of both of these are
+ determined by your tests.</para>
+
+ <para>For troubleshooting, a third kind of output file is useful:
+ use <option>--debug</option> to request an output file showing
+ details of what <productname>Expect</productname> is doing
+ internally.</para>
+
+ <sect2 id=sum xreflabel="Summary File">
+ <title>Summary File</title>
+
+ <para>DejaGnu always produces a summary output file
+ <filename>tool.sum</filename>. This summary shows the names of
+ all test files run; for each test file, one line of output from
+ each <command>pass</command> command (showing status
+ <emphasis>PASS</emphasis> or <emphasis>XPASS</emphasis>) or
+ <command>fail</command> command (status
+ <emphasis>FAIL</emphasis> or <emphasis>XFAIL</emphasis>);
+ trailing summary statistics that count passing and failing tests
+ (expected and unexpected); and the full pathname and version
+ number of the tool tested. (All possible outcomes, and all
+ errors, are always reflected in the summary output file,
+ regardless of whether or not you specify <option>--all</option>.)
+
+ <para>If any of your tests use the procedures
+ <command>unresolved</command>, <command>unsupported</command>,
+ or <command>runtested</command>, the summary output also
+ tabulates the corresponding outcomes.</para>
+
+ <para>For example, after <command>runtest --tool
+ binutils</command>, look for a summary log in
+ <filename>binutils.sum</filename>. Normally, DejaGnu writes this
+ file in your current working directory; use the
+ <option>--outdir</option> option to select a different
+ directory.</para>
+
+ <example>
+ <title>Here is a short sample summary log</title>
+
+ <screen>
+ Test Run By rob on Mon May 25 21:40:57 PDT 1992
+ === gdb tests ===
+ Running ./gdb.t00/echo.exp ...
+ PASS: Echo test
+ Running ./gdb.all/help.exp ...
+ PASS: help add-symbol-file
+ PASS: help aliases
+ PASS: help breakpoint "bre" abbreviation
+ FAIL: help run "r" abbreviation
+ Running ./gdb.t10/crossload.exp ...
+ PASS: m68k-elf (elf-big) explicit format; loaded
+ XFAIL: mips-ecoff (ecoff-bigmips) "ptype v_signed_char" signed C types
+ === gdb Summary ===
+ # of expected passes 5
+ # of expected failures 1
+ # of unexpected failures 1
+ /usr/latest/bin/gdb version 4.6.5 -q
+ </screen>
+ </example>
+
+ </sect2>
+
+ <sect2 id=log xreflabel="Log File">
+ <title>Log File</title>
+
+ <para>DejaGnu also saves a detailed log file
+ <filename>tool.log</filename>, showing any output generated by
+ tests as well as the summary output. For example, after
+ <command>runtest --tool binutils</command>, look for a detailed
+ log in <filename>binutils.log</filename>. Normally, DejaGnu
+ writes this file in your current working directory; use the
+ <option>--outdir</option> option to select a different
+ directory.</para>
+
+
+ <example>
+ <title>Here is a brief example showing a detailed log for
+ <productname>G++</productname> tests</title>
+
+ <screen>
+ Test Run By rob on Mon May 25 21:40:43 PDT 1992
+
+ === g++ tests ===
+
+ --- Running ./g++.other/t01-1.exp ---
+ PASS: operate delete
+
+ --- Running ./g++.other/t01-2.exp ---
+ FAIL: i960 bug EOF
+ p0000646.C: In function `int warn_return_1 ()':
+ p0000646.C:109: warning: control reaches end of non-void function
+ p0000646.C: In function `int warn_return_arg (int)':
+ p0000646.C:117: warning: control reaches end of non-void function
+ p0000646.C: In function `int warn_return_sum (int, int)':
+ p0000646.C:125: warning: control reaches end of non-void function
+ p0000646.C: In function `struct foo warn_return_foo ()':
+ p0000646.C:132: warning: control reaches end of non-void function
+
+ --- Running ./g++.other/t01-4.exp ---
+ FAIL: abort
+ 900403_04.C:8: zero width for bit-field `foo'
+ --- Running ./g++.other/t01-3.exp ---
+ FAIL: segment violation
+ 900519_12.C:9: parse error before `;'
+ 900519_12.C:12: Segmentation violation
+ /usr/latest/bin/gcc: Internal compiler error: program cc1plus got fatal signal
+
+ === g++ Summary ===
+
+ # of expected passes 1
+ # of expected failures 3
+ /usr/latest/bin/g++ version cygnus-2.0.1
+ </screen>
+ </example>
+
+ </sect2>
+
+ <sect2 id=debugfile xreflabel="Debug Log File">
+ <title>Debug Log File</title>
+
+ <para>With the <option>--debug</option> option, you can request
+ a log file showing the output from
+ <productname>Expect</productname> itself, running in debugging
+ mode. This file (<filename>dbg.log</filename>, in the directory
+ where you start <command>runtest</command>) shows each pattern
+ <productname>Expect</productname> considers in analyzing test
+ output.</para>
+
+ <para>This file reflects each <command>send</command> command,
+ showing the string sent as input to the tool under test; and
+ each <productname>Expect</productname> command, showing each
+ pattern it compares with the tool output.</para>
+
+ <example>
+ <title>The log messages begin with a message of the form</title>
+
+ <screen>
+
+ expect: does {<symbol>tool output</symbol>} (spawn_id <symbol>n</symbol>)
+ match pattern {<emphasis>expected pattern</emphasis>}?
+
+ </screen>
+ </example>
+
+ <para>For every unsuccessful match,
+ <productname>Expect</productname> issues a
+ <emphasis>no</emphasis> after this message; if other patterns
+ are specified for the same <productname>Expect</productname>
+ command, they are reflected also, but without the first part of
+ the message (<emphasis>expect... match pattern</emphasis>).</para>
+
+ <para>When <productname>Expect</productname> finds a match, the
+ log for the successful match ends with <emphasis>yes</emphasis>,
+ followed by a record of the <productname>Expect</productname>
+ variables set to describe a successful match.</para>
+
+ <example>
+ <title>Here is an excerpt from the debugging log for a
+ <productname>GDB</productname> test:</title>
+
+ <screen>
+ send: sent {break gdbme.c:34\n} to spawn id 6
+ expect: does {} (spawn_id 6) match pattern {Breakpoint.*at.* file
+ gdbme.c, line 34.*\(gdb\) $}? no
+ {.*\(gdb\) $}? no
+ expect: does {} (spawn_id 0) match pattern {return} ? no
+ {\(y or n\) }? no
+ {buffer_full}? no
+ {virtual}? no
+ {memory}? no
+ {exhausted}? no
+ {Undefined}? no
+ {command}? no
+ break gdbme.c:34
+ Breakpoint 8 at 0x23d8: file gdbme.c, line 34.
+ (gdb) expect: does {break gdbme.c:34\r\nBreakpoint 8 at 0x23d8:
+ file gdbme.c, line 34.\r\n(gdb) } (spawn_id 6) match pattern
+ {Breakpoint.*at.* file gdbme.c, line 34.*\(gdb\) $}? yes
+ expect: set expect_out(0,start) {18}
+ expect: set expect_out(0,end) {71}
+ expect: set expect_out(0,string) {Breakpoint 8 at 0x23d8: file
+ gdbme.c, line 34.\r\n(gdb) }
+ epect: set expect_out(spawn_id) {6}
+ expect: set expect_out(buffer) {break gdbme.c:34\r\nBreakpoint 8
+ at 0x23d8: file gdbme.c, line 34.\r\n(gdb) }
+ PASS: 70 0 breakpoint line number in file
+ </screen>
+ </example>
+
+ <para>This example exhibits three properties of
+ <productname>Expect</productname> and
+ <productname>DejaGnu</productname> that might be surprising at
+ first glance:</para>
+
+ <itemizedlist mark="bullet">
+ <listitem><para>Empty output for the first attempted match. The
+ first set of attempted matches shown ran against the output
+ <emphasis>{}</emphasis> --- that is, no
+ output. <productname>Expect</productname> begins
+ attempting to match the patterns supplied immediately; often,
+ the first pass is against incomplete output (or completely
+ before all output, as in this case).</para></listitem>
+
+ <listitem><para>Interspersed tool output. The beginning of
+ the log entry for the second attempted match may be hard to
+ spot: this is because the prompt <emphasis>{(gdb) }</emphasis>
+ appears on the same line, just before the
+ <emphasis>expect:</emphasis> that marks the beginning of the
+ log entry.</para></listitem>
+
+ <listitem><para>Fail-safe patterns. Many of the patterns
+ tested are fail-safe patterns provided by
+ <productname>GDB</productname> testing utilities, to reduce
+ possible indeterminacy. It is useful to anticipate potential
+ variations caused by extreme system conditions
+ (<productname>GDB</productname> might issue the message
+ <emphasis>virtual memory exhausted</emphasis> in rare
+ circumstances), or by changes in the tested program
+ (<emphasis>Undefined command</emphasis> is the likeliest
+ outcome if the name of a tested command changes).</para>
+
+ <para>The pattern <emphasis>{return}</emphasis> is a
+ particularly interesting fail-safe to notice; it checks for an
+ unexpected <keycap>RET</keycap> prompt. This may happen,
+ for example, if the tested tool can filter output through a
+ pager.</para>
+
+ <para>These fail-safe patterns (like the debugging log itself)
+ are primarily useful while developing test scripts. Use the
+ <command>error</command> procedure to make the actions for
+ fail-safe patterns produce messages starting with
+ <emphasis>ERROR</emphasis> on standard output, and in the
+ detailed log file.</para></listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+ </chapter>
+
+ <chapter id=Customizing xreflabel="Customizing DejaGnu">
+ <title>Customizing DejaGnu</title>
+
+ <para>The site configuration file, <filename>site.exp</filename>,
+ captures configuration-dependent values and propagates them to the
+ DejaGnu test environment using Tcl variables. This ties the
+ DejaGnu test scripts into the <command>configure</command> and
+ <command>make</command> programs. If this file is setup correctly,
+ it is possible to execute a test suite merely by typing
+ <command>runtest</command>.</para>
+
+ <para>DejaGnu supports two <filename>site.exp</filename>
+ files. The multiple instances of <filename>site.exp</filename> are
+ loaded in a fixed order built into DejaGnu. The first file loaded
+ is the local file <filename>site.exp</filename>, and then the
+ optional global <filename>site.exp</filename> file as
+ pointed to by the <symbol>DEJAGNU</symbol> environment
+ variable.</para>
+
+ <para>There is an optional <emphasis>master</emphasis>
+ <filename>site.exp</filename>, capturing configuration values that
+ apply to DejaGnu across the board, in each configuration-specific
+ subdirectory of the DejaGnu library directory.
+ <command>runtest</command> loads these values first. The master
+ <filename>site.exp</filename> contains the default values for all
+ targets and hosts supported by DejaGnu. This master file is
+ identified by setting the environment variable
+ <symbol>DEJAGNU</symbol> to the name of the file. This is also
+ refered to as the ``global'' config file.</para>
+
+ <para>Any directory containing a configured test suite also has a
+ local <filename>site.exp</filename>, capturing configuration values
+ specific to the tool under test. Since <command>runtest</command>
+ loads these values last, the individual test configuration can
+ either rely on and use, or override, any of the global values from
+ the global <filename>site.exp</filename> file.</para>
+
+ <para>You can usually generate or update the testsuite's local
+ <filename>site.exp</filename> by typing <command>make
+ site.exp</command> in the test suite directory, after the test
+ suite is configured.</para>
+
+ <para>You can also have a file in your home directory called
+ <filename>.dejagnurc</filename>. This gets loaded first before the
+ other config files. Usually this is used for personal stuff, like
+ setting the <symbol>all_flag</symbol> so all the output gets
+ printed, or your own verbosity levels. This file is usually
+ restricted to setting command line options.</para>
+
+ <para>You can further override the default values in a
+ user-editable section of any <filename>site.exp</filename>, or by
+ setting variables on the <command>runtest</command> command
+ line.</para>
+
+ <sect1 id=local xreflabel="Local Config File">
+ <title>Local Config File</title>
+
+ <para>It is usually more convenient to keep these <emphasis>manual
+ overrides</emphasis> in the <filename>site.exp</filename>
+ local to each test directory, rather than in the global
+ <filename>site.exp</filename> in the installed DejaGnu
+ library. This file is mostly for supplying tool specific info
+ that is required by the test suite.</para>
+
+ <para>All local <filename>site.exp</filename> files have
+ two sections, separated by comment text. The first section is
+ the part that is generated by <command>make</command>. It is
+ essentially a collection of Tcl variable definitions based on
+ <filename>Makefile</filename> environment variables. Since they
+ are generated by <command>make</command>, they contain the
+ values as specified by <command>configure</command>. (You can
+ also customize these values by using the <option>--site</option>
+ option to <command>configure</command>.) In particular, this
+ section contains the <filename>Makefile</filename>
+ variables for host and target configuration data. Do not edit
+ this first section; if you do, your changes are replaced next
+ time you run <command>make</command>.</para>
+
+ <example>
+ <title>The first section starts with</title>
+
+ <programlisting>
+ ## these variables are automatically generated by make ##
+ # Do not edit here. If you wish to override these values
+ # add them to the last section
+ </programlisting>
+ </example>
+
+ <para>In the second section, you can override any default values
+ (locally to DejaGnu) for all the variables. The second section
+ can also contain your preferred defaults for all the command
+ line options to <command>runtest</command>. This allows you to
+ easily customize <command>runtest</command> for your preferences
+ in each configured test-suite tree, so that you need not type
+ options repeatedly on the command line. (The second section may
+ also be empty, if you do not wish to override any defaults.)</para>
+
+ <example>
+ <title>The first section ends with this line</title>
+
+ <programlisting>
+ ## All variables above are generated by configure. Do Not Edit ##
+ </programlisting>
+ </example>
+
+ <para>You can make any changes under this line. If you wish to
+ redefine a variable in the top section, then just put a
+ duplicate value in this second section. Usually the values
+ defined in this config file are related to the configuration of
+ the test run. This is the ideal place to set the variables
+ <symbol>host_triplet</symbol>, <symbol>build_triplet</symbol>,
+ <symbol>target_triplet</symbol>. All other variables are tool
+ dependant. ie for testing a compiler, the value for
+ <symbol>CC</symbol> might be set to a freshly built binary, as
+ opposed to one in the user's path.</para>
+
+ <para>Here's an example local site.exp file, as used for
+ <productname>GCC/G++</productname> testing.</para>
+
+ <example>
+ <title>Local Config File</title>
+
+ <programlisting>
+ ## these variables are automatically generated by make ##
+ # Do not edit here. If you wish to override these values
+ # add them to the last section
+ set rootme "/build/devo-builds/i586-pc-linux-gnulibc1/gcc"
+ set host_triplet i586-pc-linux-gnulibc1
+ set build_triplet i586-pc-linux-gnulibc1
+ set target_triplet i586-pc-linux-gnulibc1
+ set target_alias i586-pc-linux-gnulibc1
+ set CFLAGS ""
+ set CXXFLAGS "-I/build/devo-builds/i586-pc-linux-gnulibc1/gcc/../libio -I$srcdir/../libg++/src -I$srcdir/../libio -I$srcdir/../libstdc++ -I$srcdir/../libstdc++/stl -L/build/devo-builds/i586-pc-linux-gnulibc1/gcc/../libg++ -L/build/devo-builds/i586-pc-linux-gnulibc1/gcc/../libstdc++"
+ append LDFLAGS " -L/build/devo-builds/i586-pc-linux-gnulibc1/gcc/../ld"
+ set tmpdir /build/devo-builds/i586-pc-linux-gnulibc1/gcc/testsuite
+ set srcdir "${srcdir}/testsuite"
+ ## All variables above are generated by configure. Do Not Edit ##
+
+ </programlisting>
+ </example>
+
+ <para>This file defines the required fields for a local config
+ file, namely the three config triplets, and the srcdir. It also
+ defines several other Tcl variables that are used exclusivly by
+ the GCC test suite. For most test cases, the CXXFLAGS and LDFLAGS
+ are supplied by DejaGnu itself for cross testing, but to test a
+ compiler, GCC needs to manipulate these itself.</para>
+
+ </sect1>
+ <sect1 id=global xreflabel="Global Config File">
+ <title>Global Config File</title>
+
+ <para>The master config file is where all the target specific
+ config variables get set for a whole site get set. The idea is
+ that for a centralized testing lab where people have to share a
+ target between multiple developers. There are settings for both
+ remote targets and remote hosts. Here's an example of a Master
+ Config File (also called the Global config file) for a
+ <emphasis>canadian cross</emphasis>. A canadian cross is when
+ you build and test a cross compiler on a machine other than the
+ one it's to be hosted on.</para>
+
+ <para>Here we have the config settings for our California
+ office. Note that all config values are site dependant. Here we
+ have two sets of values that we use for testing m68k-aout cross
+ compilers. As both of these target boards has a different
+ debugging protocol, we test on both of them in sequence.</para>
+
+ <example>
+ <title>Global Config file</title>
+
+ <programlisting>
+
+ # Make sure we look in the right place for the board description files.
+ if ![info exists boards_dir] {
+ set boards_dir {}
+ }
+ lappend boards_dir "/nfs/cygint/s1/cygnus/dejagnu/boards"
+
+ verbose "Global Config File: target_triplet is $target_triplet" 2
+ global target_list
+
+ case "$target_triplet" in {
+ { "native" } {
+ set target_list "unix"
+ }
+ { "sparc64-*elf" } {
+ set target_list "sparc64-sim"
+ }
+ { "mips-*elf" } {
+ set target_list "mips-sim wilma barney"
+ }
+ { "mips-lsi-elf" } {
+ set target_list "mips-lsi-sim{,soft-float,el}"
+ }
+ { "sh-*hms" } {
+ set target_list { "sh-hms-sim" "bloozy" }
+ }
+ }
+ </programlisting>
+ </example>
+
+ <para>In this case, we have support for several cross compilers,
+ that all run on this host. For testing on operating systems that
+ don't support Expect, DejaGnu can be run on the local build
+ machine, and it can connect to the remote host and run all the
+ tests for this cross compiler on that host. All the remote OS
+ requires is a working telnetd.</para>
+
+ <para>As you can see, all one does is set the variable
+ <symbol>target_list</symbol> to the list of targets and options to
+ test. The simple settings, like for
+ <emphasis>sparc64-elf</emphasis> only require setting the name of
+ the single board config file. The <emphasis>mips-elf</emphasis>
+ target is more complicated. Here it sets the list to three target
+ boards. One is the default mips target, and both
+ <emphasis>wilma</emphasis> <emphasis>barney</emphasis> are
+ symbolic names for other mips boards. Symbolic names are covered
+ in the <xref linkend=addboard> chapter. The more complicated
+ example is the one for <emphasis>mips-lsi-elf</emphasis>. This one
+ runs the tests with multiple iterations using all possible
+ combinations of the <option>--soft-float</option> and the
+ <option>--el</option> (little endian) option. Needless to say,
+ this last feature is mostly compiler specific.</para>
+
+ </sect1>
+
+ <sect1 id=boardconfig xreflabel="Board Config File">
+ <title>Board Config File</title>
+
+ <para>The board config file is where board specfic config data
+ is stored. A board config file contains all the higher-level
+ configuration settings. There is a rough inheritance scheme, where it is
+ possible to base a new board description file on an existing one. There
+ are also collections of custom procedures for common environments. For
+ more information on adding a new board config file, go to the <xref
+ linkend=addboard> chapter. </para>
+
+ <para>An example board config file for a GNU simulator is as
+ follows. <function>set_board_info</function> is a procedure that sets the
+ field name to the specified value. The procedures in square brackets
+ <emphasis>[]</emphasis> are <emphasis>helper procedures</emphasis>. Thes
+ are used to find parts of a tool chain required to build an executable
+ image that may reside in various locations. This is mostly of use for
+ when the startup code, the standard C lobraries, or the tool chain itself
+ is part of your build tree.</para>
+
+ <example>
+ <title>Board Config File</title>
+
+ <programlisting>
+ # This is a list of toolchains that are supported on this board.
+ set_board_info target_install {sparc64-elf}
+
+ # Load the generic configuration for this board. This will define any
+ # routines needed by the tool to communicate with the board.
+ load_generic_config "sim"
+
+ # We need this for find_gcc and *_include_flags/*_link_flags.
+ load_base_board_description "basic-sim"
+
+ # Use long64 by default.
+ process_multilib_options "long64"
+
+ setup_sim sparc64
+
+ # We only support newlib on this target. We assume that all multilib
+ # options have been specified before we get here.
+ set_board_info compiler "[find_gcc]"
+ set_board_info cflags "[libgloss_include_flags] [newlib_include_flags]"
+ set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags]"
+ # No linker script.
+ set_board_info ldscript "";
+
+ # Used by a few gcc.c-torture testcases to delimit how large the
+ # stack can be.
+ set_board_info gcc,stack_size 16384
+ # The simulator doesn't return exit statuses and we need to indicate this
+ # the standard GCC wrapper will work with this target.
+ set_board_info needs_status_wrapper 1
+ # We can't pass arguments to programs.
+ set_board_info noargs 1
+ </programlisting>
+ </example>
+
+ <para>There are five helper procedures used in this example. The first
+ one, <function>find gcc</function> looks for a copy of the GNU compiler in
+ your build tree, or it uses the one in your path. This will also return
+ the proper transformed name for a cross compiler if you whole build tree
+ is configured for one. The next helper procedures are
+ <function>libgloss_include_flags</function> &
+ <function>libgloss_link_flags</function>. These return the proper flags to
+ compiler and link an executable image using <xref
+ linkend=libgloss>, the GNU BSP (Board Support Package). The final
+ procedures are <function>newlib_include_flag</function> &
+ <function>newlib_include_flag</function>. These find the Newlib C
+ library, which is a reentrant standard C library for embedded systems
+ comprising of non GPL'd code.</para>
+
+ </sect1>
+
+ <sect1 id=releng xreflabel="Remote Host Testing">
+ <title>Remote Host Testing</title>
+
+ <note><para>Thanks to Dj Delorie for the original paper that
+ this section is based on.</para></note>
+
+ <para>DejaGnu also supports running the tests on a remote
+ host. To set this up, the remote host needs an ftp server, and a
+ telnet server. Currently foreign operating systems used as
+ remote hosts are VxWorks, VRTX, Dos/Win3.1, MacOS, and
+ win95/win98/NT.</para>
+
+ <para>The recommended source for a win95/win98/NT based ftp
+ server is to get IIS (either IIS 1 or Personal Web Server) from
+ <ulink
+ URL="http://www.microsoft.com">http://www.microsoft.com</ulink>.
+ When you install it, make sure you install the FTP server - it's
+ not selected by default. Go into the IIS manager and change the
+ FTP server so that it does not allow anonymous ftp. Set the home
+ directory to the root directory (i.e. c:\) of a suitable
+ drive. Allow writing via ftp.</para>
+
+ <para>It will create an account like IUSR_FOOBAR where foobar is
+ the name of your machine. Go into the user editor and give that
+ account a password that you don't mind hanging around in the
+ clear (i.e. not the same as your admin or personal
+ passwords). Also, add it to all the various permission groups.</para>
+
+ <para>You'll also need a telnet server. For win95/win98/NT, go
+ to the <ulink URL="http://ataman.com">Ataman</ulink> web site,
+ pick up the Ataman Remote Logon Services for Windows, and
+ install it. You can get started on the eval period anyway. Add
+ IUSR_FOOBAR to the list of allowed users, set the HOME directory
+ to be the same as the FTP default directory. Change the Mode
+ prompt to simple.</para>
+
+ <para>Ok, now you need to pick a directory name to do all the
+ testing in. For the sake of this example, we'll call it piggy
+ (i.e. c:\piggy). Create this directory.</para>
+
+ <para>You'll need a unix machine. Create a directory for the
+ scripts you'll need. For this example, we'll use
+ /usr/local/swamp/testing. You'll need to have a source tree
+ somewhere, say /usr/src/devo. Now, copy some files from
+ releng's area in SV to your machine:</para>
+
+ <example>
+ <title>Remote host setup</title>
+
+ <screen>
+ cd /usr/local/swamp/testing
+ mkdir boards
+ scp darkstar.welcomehome.org:/dejagnu/cst/bin/MkTestDir .
+ scp darkstar.welcomehome.org:/dejagnu/site.exp .
+ scp darkstar.welcomehome.org:/dejagnu/boards/useless98r2.exp boards/foobar.exp
+ export DEJAGNU=/usr/local/swamp/testing/site.exp
+
+ </screen>
+ </example>
+
+ <para>You must edit the boards/foobar.exp file to reflect your
+ machine; change the hostname (foobar.com), username
+ (iusr_foobar), password, and ftp_directory (c:/piggy) to match
+ what you selected.</para>
+
+ <para>Edit the global <filename> site.exp</filename> to reflect your
+ boards directory:</para>
+
+ <example>
+ <title>Add The Board Directory</title>
+
+ <programlisting>
+ lappend boards_dir "/usr/local/swamp/testing/boards"
+ </programlisting>
+ </example>
+
+ <para>Now run MkTestDir, which is in the contrib
+ directory. The first parameter is the toolchain prefix, the
+ second is the location of your devo tree. If you are testing a
+ cross compiler (ex: you have sh-hms-gcc.exe in your PATH on
+ the PC), do something like this:</para>
+
+ <example>
+ <title>Setup Cross Remote Testing</title>
+
+ <programlisting>
+ ./MkTestDir sh-hms /usr/dejagnu/src/devo
+ </programlisting>
+ </example>
+
+ <para>If you are testing a native PC compiler (ex: you have
+ gcc.exe in your PATH on the PC), do this:
+
+ <example>
+ <title>Setup Native Remote Testing</title>
+
+ <programlisting>
+ ./MkTestDir '' /usr/dejagnu/src/devo
+ </programlisting>
+ </example>
+
+ <para>To test the setup, <command>ftp</command> to your PC
+ using the username (iusr_foobar) and password you selected. CD
+ to the test directory. Upload a file to the PC. Now telnet to
+ your PC using the same username and password. CD to the test
+ directory. Make sure the file is there. Type "set" and/or "gcc
+ -v" (or sh-hms-gcc -v) and make sure the default PATH contains
+ the installation you want to test.</para>
+
+ <example>
+ <title>Run Test Remotely</title>
+
+ <programlisting>
+ cd /usr/local/swamp/testing
+ make -k -w check RUNTESTFLAGS="--host_board foobar --target_board foobar -v -v" > check.out 2>&1
+ </programlisting>
+ </example>
+
+ <para>To run a specific test, use a command like this (for
+ this example, you'd run this from the gcc directory that
+ MkTestDir created):</para>
+
+ <example>
+ <title>Run a Test Remotely</title>
+
+ <programlisting>
+ make check RUNTESTFLAGS="--host_board sloth --target_board sloth -v compile.exp=921202-1.c"
+ </programlisting>
+ </example>
+
+ <para>Note: if you are testing a cross-compiler, put in the
+ correct target board. You'll also have to download more .exp
+ files and modify them for your local configuration. The -v's
+ are optional.</para>
+
+ </sect1>
+
+ <sect1 id=configfile xreflabel="Config File Values">
+ <title>Config File Values</title>
+
+ <para>DejaGnu uses a named array in Tcl to hold all the info for
+ each machine. In the case of a canadian cross, this means host
+ information as well as target information. The named array is
+ called <symbol>target_info</symbol>, and it has two indices. The
+ following fields are part of the array.</para>
+
+ <sect1 id=optiondefs xreflabel="Option Variables">
+ <title>Command Line Option Variables</title>
+
+ <para>In the user editable second section of the <xref
+ linkend=personal> you can not only override the configuration
+ variables captured in the first section, but also specify
+ default values for all on the <command>runtest</command>
+ command line options. Save for <option>--debug</option>,
+ <option>--help</option>, and <option>--version</option>, each
+ command line option has an associated Tcl variable. Use the
+ Tcl <command>set</command> command to specify a new default
+ value (as for the configuration variables). The following
+ table describes the correspondence between command line
+ options and variables you can set in
+ <filename>site.exp</filename>. <xref linkend=invoking>, for
+ explanations of the command-line options.</para>
+
+ <para><table frame=all rowsep=0 colsep=0>
+ <title>Tcl Variables For Command Line Options</title>
+
+ <tgroup cols=3 align="char" rowsep=1 colsep=0>
+ <thead><row>
+ <entry>runtest</entry><entry>Tcl</entry>
+ <entry>option</entry><entry>variable</entry><entry>description</entry>
+ </row></thead>
+ <tbody>
+
+ <row>
+ <entry>--all</entry>
+ <entry>all_flag</entry>
+ <entry>display all test results if set</entry>
+ </row>
+
+ <row>
+ <entry>--baud</entry>
+ <entry>baud</entry>
+ <entry>set the default baud rate to something other than
+ 9600.</entry>
+ </row>
+
+ <row>
+ <entry>--connect</entry>
+ <entry>connectmode</entry>
+ <entry><command>rlogin</command>,
+ <command>telnet</command>, <command>rsh</command>,
+ <command>kermit</command>, <command>tip</command>, or
+ <command>mondfe</command></entry>
+ </row>
+
+ <row>
+ <entry>--outdir</entry>
+ <entry>outdir</entry>
+ <entry>directory for <filename>tool.sum</filename> and
+ <filename>tool.log.</filename></entry>
+ </row>
+
+ <row>
+ <entry>--objdir</entry>
+ <entry>objdir</entry>
+ <entry>directory for pre-compiled binaries</entry>
+ </row>
+
+ <row>
+ <entry>--reboot</entry>
+ <entry>reboot</entry>
+ <entry>reboot the target if set to
+ <emphasis>"1"</emphasis>; do not reboot if set to
+ <emphasis>"0"</emphasis> (the default).</entry>
+ </row>
+
+ <row>
+ <entry>--srcdir</entry>
+ <entry>srcdir</entry>
+ <entry>directory of test subdirectories</entry>
+ </row>
+
+ <row>
+ <entry>--strace</entry>
+ <entry>tracelevel</entry>
+ <entry>a number: Tcl trace depth</entry>
+ </row>
+
+ <row>
+ <entry>--tool</entry>
+ <entry>tool</entry>
+ <entry>name of tool to test; identifies init, test subdir</entry>
+ </row>
+
+ <row>
+ <entry>--verbose</entry>
+ <entry>verbose</entry>
+ <entry>verbosity level. As option, use multiple times; as
+ variable, set a number, 0 or greater.</entry>
+ </row>
+
+ <row>
+ <entry>--target</entry>
+ <entry>target_triplet</entry>
+ <entry>The canonical configuration string for the target.</entry>
+ </row>
+
+ <row>
+ <entry>--host</entry>
+ <entry>host_triplet</entry>
+ <entry>The canonical configuration string for the host.</entry>
+ </row>
+
+ <row>
+ <entry>--build</entry>
+ <entry>build_triplet</entry>
+ <entry>The canonical configuration string for the build
+ host.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+
+ </sect1>
+
+ <sect1 id=personal xreflabel="Personal Config File">
+ <title>Personal Config File</title>
+
+ <para>The personal config file is used to customize
+ <command>runtest's</command> behaviour for each person. It's
+ typically used to set the user prefered setting for verbosity,
+ and any experimental Tcl procedures. My personal
+ <filename>~/.dejagnurc</filename> file looks like:</para>
+
+ <example>
+ <title>Personal Config File</title>
+
+ <programlisting>
+ set all_flag 1
+ set RLOGIN /usr/ucb/rlogin
+ set RSH /usr/local/sbin/ssh
+ </programlisting>
+ </example>
+
+ <para>Here I set <symbol>all_flag</symbol> so I see all the test
+ cases that PASS along with the ones that FAIL. I also set
+ <symbol>RLOGIN</symbol> to the BSD version. I have
+ <productname>Kerberos</productname> installed, and when I rlogin
+ to a target board, it usually isn't supported. So I use the non
+ secure version rather than the default that's in my path. I also
+ set <symbol>RSH</symbol> to the <productname>SSH</productname>
+ secure shell, as rsh is mostly used to test unix
+ machines within a local network here.</para>
+
+ </sect1>
+
+ </chapter>
+
+ <chapter id=Extending xreflabel="Extending DejaGnu">
+ <title>Extending DejaGnu</title>
+
+ <sect1 id=addsuite xreflabel="Adding a new Test Suite">
+ <title>Adding A New Test Suite</title>
+
+ <para>The testsuite for a new tool should always be located in that tools
+ source directory. DejaGnu require the directory be named
+ <filename>testsuite</filename>. Under this directory, the test cases go
+ in a subdirectory whose name begins with the tool name. For example, for
+ a tool named <emphasis>flubber</emphasis>, each subdirectory containing
+ testsuites must start with <emphasis>"flubber."</emphasis>.</para>
+
+ </sect1>
+
+ <sect1 id=addtool xreflabel="Adding A New Tool">
+ <title>Adding A New Tool</title>
+
+ <para>In general, the best way to learn how to write (code or even prose)
+ is to read something similar. This principle applies to test cases and
+ to test suites. Unfortunately, well-established test suites have a way
+ of developing their own conventions: as test writers become more
+ experienced with DejaGnu and with Tcl, they accumulate more utilities,
+ and take advantage of more and more features of
+ <productname>Expect</productname> and <productname>Tcl</productname> in
+ general.</para>
+
+ <para>Inspecting such established test suites may make the prospect of
+ creating an entirely new test suite appear overwhelming. Nevertheless,
+ it is quite straightforward to get a new test suite going.</para>
+
+ <para>There is one test suite that is guaranteed not to grow more
+ elaborate over time: both it and the tool it tests were created expressly
+ to illustrate what it takes to get started with DejaGnu. The
+ <filename>example/</filename> directory of the DejaGnu distribution
+ contains both an interactive tool called <command>calc</command>, and a
+ test suite for it. Reading this test suite, and experimenting with it,
+ is a good way to supplement the information in this section. (Thanks to
+ Robert Lupton for creating calc and its test suite---and also the first
+ version of this section of the manual!)</para>
+
+ <para>To help orient you further in this task, here is an outline of the
+ steps to begin building a test suite for a program example.</para>
+
+ <itemizedlist mark=bullet>
+
+ <listitem><para>Create or select a directory to contain your new
+ collection of tests. Change into that directory (shown here as
+ <filename>testsuite</filename>):</para>
+
+ <para>Create a <filename>configure.in</filename> file in this directory,
+ to control configuration-dependent choices for your tests. So far as
+ DejaGnu is concerned, the important thing is to set a value for the
+ variable <symbol>target_abbrev</symbol>; this value is the link to the
+ init file you will write soon. (For simplicity, we assume the
+ environment is Unix, and use <emphasis>unix</emphasis> as the
+ value.)</para>
+
+ <para>What else is needed in <filename>configure.in</filename> depends on
+ the requirements of your tool, your intended test environments, and which
+ configure system you use. This example is a minimal configure.in for use
+ with <productname>GNU Autoconf</productname>. </para></listitem>
+
+ <listitem><para>Create <filename>Makefile.in</filename> (if you are using
+ Autoconf), or <filename>Makefile.am</filename>(if you are using
+ Automake), the source file used by configure to build your
+ <filename>Makefile</filename>. If you are using GNU Automake.just add the
+ keyword <emphasis>dejagnu</emphasis> to the
+ <emphasis>AUTOMAKE_OPTIONS</emphasis> variable in your
+ <filename>Makefile.am</filename> file. This will add all the Makefile
+ support needed to run DejaGnu, and support the <xref linkend=makecheck>
+ target.</para>
+
+ <para>You also need to include two targets important to DejaGnu:
+ <emphasis>check</emphasis>, to run the tests, and
+ <emphasis>site.exp</emphasis>, to set up the Tcl copies of
+ configuration-dependent values. This is called the <xref linkend=local>
+ The check target must run the <command>runtest</command> program to
+ execute the tests.</para>
+
+ <para>The <filename>site.exp</filename> target should usually set up
+ (among other things) the $tool variable for the name of your program. If
+ the local site.exp file is setup correctly, it is possible to execute the
+ tests by merely typing <command>runtest</command> on the command
+ line.</para>
+
+ <example>
+ <title>Sample Makefile.in Fragment</title>
+
+ <programlisting>
+ # Look for a local version of DejaGnu, otherwise use one in the path
+ RUNTEST = `if test -f $(top_srcdir)/../dejagnu/runtest; then \
+ echo $(top_srcdir) ../dejagnu/runtest; \
+ else \
+ echo runtest; \
+ fi`
+
+ # The flags to pass to runtest
+ RUNTESTFLAGS =
+
+ # Execute the tests
+ check: site.exp all
+ $(RUNTEST) $(RUNTESTFLAGS) \
+ --tool <symbol>${example}</symbol> --srcdir $(srcdir)
+
+ # Make the local config file
+ site.exp: ./config.status Makefile
+ @echo "Making a new config file..."
+ -@rm -f ./tmp?
+ @touch site.exp
+
+ -@mv site.exp site.bak
+ @echo "## these variables are automatically\
+ generated by make ##" > ./tmp0
+ @echo "# Do not edit here. If you wish to\
+ override these values" >> ./tmp0
+ @echo "# add them to the last section" >> ./tmp0
+ @echo "set host_os ${host_os}" >> ./tmp0
+ @echo "set host_alias ${host_alias}" >> ./tmp0
+ @echo "set host_cpu ${host_cpu}" >> ./tmp0
+ @echo "set host_vendor ${host_vendor}" >> ./tmp0
+ @echo "set target_os ${target_os}" >> ./tmp0
+ @echo "set target_alias ${target_alias}" >> ./tmp0
+ @echo "set target_cpu ${target_cpu}" >> ./tmp0
+ @echo "set target_vendor ${target_vendor}" >> ./tmp0
+ @echo "set host_triplet ${host_canonical}" >> ./tmp0
+ @echo "set target_triplet ${target_canonical}">>./tmp0
+ @echo "set tool binutils" >> ./tmp0
+ @echo "set srcdir ${srcdir}" >> ./tmp0
+ @echo "set objdir `pwd`" >> ./tmp0
+ @echo "set <symbol>${examplename}</symbol> <symbol>${example}</symbol>" >> ./tmp0
+ @echo "## All variables above are generated by\
+ configure. Do Not Edit ##" >> ./tmp0
+ @cat ./tmp0 > site.exp
+ @sed < site.bak \
+ -e '1,/^## All variables above are.*##/ d' \
+ >> site.exp
+ -@rm -f ./tmp?
+
+ </programlisting>
+ </example>
+ </listitem>
+
+ <listitem><para>Create a directory (in <filename>testsuite</filename>)
+ called <filename>config</filename>. Make a <emphasis>Tool Init
+ File</emphasis> in this directory. Its name must start with the
+ <symbol>target_abbrev</symbol> value, or be named
+ <filename>default.exp</filename> so call it
+ <filename>config/unix.exp</filename> for our Unix based example. This
+ is the file that contains the target-dependent procedures.
+ Fortunately, on Unix, most of them do not have to do very much in
+ order for <command>runtest</command> to run.</para>
+
+ <para>If the program being tested is not interactive, you can get
+ away with this minimal <filename>unix.exp</filename> to begin
+ with:</para>
+
+ <example>
+ <title>Simple Batch Program Tool Init File</title>
+
+ <programlisting>
+
+ proc foo_exit {} {}
+ proc foo_version {} {}
+
+ </programlisting>
+ </example>
+
+ <para>If the program being tested is interactive, however, you might
+ as well define a <emphasis>start</emphasis> routine and invoke it by
+ using an init file like this:</para>
+
+ <example>
+ <title>Simple Interactive Program Tool Init File</title>
+
+ <programlisting>
+
+ proc foo_exit {} {}
+ proc foo_version {} {}
+
+ proc foo_start {} {
+ global ${examplename}
+ spawn ${examplename}
+ expect {
+ -re "" {}
+ }
+ }
+
+ # Start the program running we want to test
+ foo_start
+
+ </programlisting>
+ </example>
+ </listitem>
+
+ <listitem><para>Create a directory whose name begins with your tool's
+ name, to contain tests. For example, if your tool's name is
+ <emphasis>gcc</emphasis>, then the directories all need to start with
+ <emphasis>"gcc."</emphasis>.</para></listitem>
+
+ <listitem><para>Create a sample test file. Its name must end with
+ <filename>.exp</filename>. You can use
+ <filename>first-try.exp</filename>. To begin with, just write there a
+ line of Tcl code to issue a message.</para>
+
+ <example>
+ <title>Testing A New Tool Config</title>
+
+ <programlisting>
+
+ send_user "Testing: one, two...\n"
+
+ </programlisting>
+ </example>
+ </listitem>
+
+ <listitem><para>Back in the <filename>testsuite</filename> (top
+ level) directory, run <command>configure</command>. Typically you do
+ this while in the build directory. You may have to specify more of a
+ path, if a suitable configure is not available in your execution
+ path.</para></listitem>
+
+ <listitem><para>e now ready to triumphantly type <command>make
+ check</command> or <command>runtest</command>. You should see
+ something like this:</para>
+
+ <example>
+ <title>Example Test Case Run</title>
+
+ <screen>
+ Test Run By rhl on Fri Jan 29 16:25:44 EST 1993
+
+ === example tests ===
+
+ Running ./example.0/first-try.exp ...
+ Testing: one, two...
+
+ === example Summary ===
+
+ </screen>
+ </example>
+
+ <para>There is no output in the summary, because so far the example
+ does not call any of the procedures that establish a test
+ outcome.</para></listitem>
+
+ <listitem><para>Write some real tests. For an interactive tool, you
+ should probably write a real exit routine in fairly short order. In
+ any case, you should also write a real version routine
+ soon. </para></listitem>
+
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 id=addtarget xreflabel="Adding A New Target">
+ <title>Adding A New Target</title>
+
+ <para>DejaGnu has some additional requirements for target support, beyond
+ the general-purpose provisions of configure. DejaGnu must actively
+ communicate with the target, rather than simply generating or managing
+ code for the target architecture. Therefore, each tool requires an
+ initialization module for each target. For new targets, you must supply
+ a few Tcl procedures to adapt DejaGnu to the target. This permits
+ DejaGnu itself to remain target independent.</para>
+
+ <para>Usually the best way to write a new initialization module is to
+ edit an existing initialization module; some trial and error will be
+ required. If necessary, you can use the @samp{--debug} option to see what
+ is really going on.</para>
+
+ <para>When you code an initialization module, be generous in printing
+ information controlled by the <function>verbose</function>
+ procedure.</para>
+
+ <para>For cross targets, most of the work is in getting the
+ communications right. Communications code (for several situations
+ involving IP networks or serial lines) is available in a DejaGnu library
+ file.</para>
+
+ <para>If you suspect a communication problem, try running the connection
+ interactively from <productname>Expect</productname>. (There are three
+ ways of running <productname>Expect</productname> as an interactive
+ interpreter. You can run <productname>Expect</productname> with no
+ arguments, and control it completely interactively; or you can use
+ <command>expect -i</command> together with other command-line options and
+ arguments; or you can run the command <command>interpreter</command> from
+ any <productname>Expect</productname> procedure. Use
+ <command>return</command> to get back to the calling procedure (if any),
+ or <command>return -tcl</command> to make the calling procedure itself
+ return to its caller; use <command>exi</command>t or end-of-file to leave
+ Expect altogether.) Run the program whose name is recorded in
+ <symbol>$connectmode</symbol>, with the arguments in
+ <symbol>$targetname</symbol>, to establish a connection. You should at
+ least be able to get a prompt from any target that is physically
+ connected.</para>
+
+ </sect1>
+
+ <sect1 id=addboard xreflabel="Adding A New Board">
+ <title>Adding A New Board</title>
+
+ <para>Adding a new board consists of creating a new board config
+ file. Examples are in
+ <filename>dejagnu/baseboards</filename>. Usually to make a new
+ board file, it's easiest to copy an existing one. It is also
+ possible to have your file be based on a
+ <emphasis>baseboard</emphasis> file with only one or two
+ changes needed. Typically, this can be as simple as just
+ changing the linker script. Once the new baseboard file is done,
+ add it to the <symbol>boards_DATA</symbol> list in the
+ <filename>dejagnu/baseboards/Makefile.am</filename>, and regenerate the
+ Makefile.in using automake. Then just rebuild and install DejaGnu. You
+ can test it by:</para>
+
+ <para>There is a crude inheritance scheme going on with board files, so
+ you can include one board file into another, The two main procedures used
+ to do this are <function>load_generic_config</function> and
+ <function>load_base_board_description</function>. The generic config file
+ contains other procedures used for a certain class of target. The
+ board description file is where the board specfic settings go. Commonly
+ there are similar target environments with just different
+ processors.</para>
+
+ <example>
+ <title>Testing a New Board Config File</title>
+
+ <screen>
+ make check RUNTESTFLAGS="--target_board=<emphasis>newboardfile</emphasis>".
+ </screen>
+ </example>
+
+ <para>Here's an example of a board config file. There are
+ several <emphasis>helper procedures</emphasis> used in this
+ example. A helper procedure is one that look for a tool of files
+ in commonly installed locations. These are mostly used when
+ testing in the build tree, because the executables to be tested
+ are in the same tree as the new dejagnu files. The helper
+ procedures are the ones in square braces
+ <emphasis>[]</emphasis>, which is the Tcl execution characters.</para>
+
+ <example>
+ <title>Example Board Config File</title>
+
+ <programlisting>
+
+ # Load the generic configuration for this board. This will define a basic
+ # set of routines needed by the tool to communicate with the board.
+ load_generic_config "sim"
+
+ # basic-sim.exp is a basic description for the standard Cygnus simulator.
+ load_base_board_description "basic-sim"
+
+ # The compiler used to build for this board. This has *nothing* to do
+ # with what compiler is tested if we're testing gcc.
+ set_board_info compiler "[find_gcc]"
+
+ # We only support newlib on this target.
+ # However, we include libgloss so we can find the linker scripts.
+ set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]"
+ set_board_info ldflags "[newlib_link_flags]"
+
+ # No linker script for this board.
+ set_board_info ldscript "-Tsim.ld";
+
+ # The simulator doesn't return exit statuses and we need to indicate this.
+ set_board_info needs_status_wrapper 1
+
+ # Can't pass arguments to this target.
+ set_board_info noargs 1
+
+ # No signals.
+ set_board_info gdb,nosignals 1
+
+ # And it can't call functions.
+ set_board_info gdb,cannot_call_functions 1
+
+ </programlisting>
+ </example>
+
+ </sect1>
+
+ <sect1 id=boarddefs xreflabel="Board File Values">
+ <title>Board Config File Values</title>
+
+ <para>These fields are all in the <symbol>board_info</symbol> These are
+ all set by using the <function>set_board_info</function> procedure. The
+ parameters are the field name, followed by the value to set the field
+ to.</para>
+
+ <para><table frame=all rowsep=0 colsep=0>
+ <title>Common Board Info Fields</title>
+
+ <tgroup cols=3 align="char" rowsep=1 colsep=0>
+ <thead><row>
+ <entry>Field</entry>
+ <entry>Sample Value</entry>
+ <entry>Description</entry>
+ </row></thead>
+ <tbody>
+
+ <row>
+ <entry>compiler</entry>
+ <entry>"[find_gcc]"</entry>
+ <entry>The path to the compiler to use.</entry>
+ </row>
+
+ <row>
+ <entry>cflags</entry>
+ <entry>"-mca"</entry>
+ <entry>Compilation flags for the compiler.</entry>
+ </row>
+
+ <row>
+ <entry>ldflags</entry>
+ <entry>"[libgloss_link_flags] [newlib_link_flags]"</entry>
+ <entry>Linking flags for the compiler.</entry>
+ </row>
+
+ <row>
+ <entry>ldscript</entry>
+ <entry>"-Wl,-Tidt.ld"</entry>
+ <entry>The linker script to use when cross compiling.</entry>
+ </row>
+
+ <row>
+ <entry>libs</entry>
+ <entry>"-lgcc"</entry>
+ <entry>Any additional libraries to link in.</entry>
+ </row>
+
+ <row>
+ <entry>shell_prompt</entry>
+ <entry>"cygmon>"</entry>
+ <entry>The command prompt of the remote shell.</entry>
+ </row>
+
+ <row>
+ <entry>hex_startaddr</entry>
+ <entry>"0xa0020000"</entry>
+ <entry>The Starting address as a string.</entry>
+ </row>
+
+ <row>
+ <entry>start_addr</entry>
+ <entry>0xa0008000</entry>
+ <entry>The starting address as a value.</entry>
+ </row>
+
+ <row>
+ <entry>startaddr</entry>
+ <entry>"a0020000"</entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry>exit_statuses_bad</entry>
+ <entry>1</entry>
+ <entry>Whether there is an accurate exit status.</entry>
+ </row>
+
+ <row>
+ <entry>reboot_delay</entry>
+ <entry>10</entry>
+ <entry>The delay between power off and power on.</entry>
+ </row>
+
+ <row>
+ <entry>unreliable</entry>
+ <entry>1</entry>
+ <entry>Whether communication with the board is unreliable.</entry>
+ </row>
+
+ <row>
+ <entry>sim</entry>
+ <entry>[find_sim]</entry>
+ <entry>The path to the simulator to use.</entry>
+ </row>
+
+ <row>
+ <entry>objcopy</entry>
+ <entry>$tempfil</entry>
+ <entry>The path to the <command>objcopy</command> program.</entry>
+ </row>
+
+ <row>
+ <entry>support_libs</entry>
+ <entry>"${prefix_dir}/i386-coff/"</entry>
+ <entry>Support libraries needed for cross compiling.</entry>
+ </row>
+
+ <row>
+ <entry>addl_link_flags</entry>
+ <entry>"-N"</entry>
+ <entry>Additional link flags, rarely used.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+
+ <para>These fields are used by the GCC and GDB tests, and are mostly
+ only useful to somewhat trying to debug a new board file for one of
+ these tools. Many of these are used only by a few testcases, and their
+ purpose is esoteric. These are listed with sample values as a guide to
+ better guessing if you need to change any of these.</para>
+
+ <para><table frame=all rowsep=0 colsep=0>
+ <title>Board Info Fields For GCC & GDB</title>
+
+ <tgroup cols=3 align="char" rowsep=1 colsep=0>
+ <thead><row>
+ <entry>Field</entry>
+ <entry>Sample Value</entry>
+ <entry>Description</entry>
+ </row></thead>
+ <tbody>
+
+ <row>
+ <entry>strip</entry>
+ <entry>$tempfile</entry>
+ <entry>Strip the executable of symbols.</entry>
+ </row>
+
+ <row>
+ <entry>gdb_load_offset</entry>
+ <entry>"0x40050000"</entry>
+ </row>
+
+ <row>
+ <entry>gdb_protocol</entry>
+ <entry>"remote"</entry>
+ <entry>The GDB debugging protocol to use.</entry>
+ </row>
+
+ <row>
+ <entry>gdb_sect_offset</entry>
+ <entry>"0x41000000";</entry>
+ </row>
+
+ <row>
+ <entry>gdb_stub_ldscript</entry>
+ <entry>"-Wl,-Teva-stub.ld"</entry>
+ <entry>The linker script to use with a GDB stub.</entry>
+ </row>
+
+ <row>
+ <entry>gdb_init_command</entry>
+ <entry>"set mipsfpu none"</entry>
+ </row>
+
+ <row>
+ <entry>gdb,cannot_call_functions</entry>
+ <entry>1</entry>
+ <entry>Whether GDB can call functions on the target,</entry>
+ </row>
+
+ <row>
+ <entry>gdb,noargs</entry>
+ <entry>1</entry>
+ <entry>Whether the target can take command line arguments.</entry>
+ </row>
+
+ <row>
+ <entry>gdb,nosignals</entry>
+ <entry>1</entry>
+ <entry>Whether there are signals on the target.</entry>
+ </row>
+
+ <row>
+ <entry>gdb,short_int</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>gdb,start_symbol</entry>
+ <entry>"_start";</entry>
+ <entry>The starting symbol in the executable.</entry>
+ </row>
+
+ <row>
+ <entry>gdb,target_sim_options</entry>
+ <entry>"-sparclite"</entry>
+ <entry>Special options to pass to the simulator.</entry>
+ </row>
+
+ <row>
+ <entry>gdb,timeout</entry>
+ <entry>540</entry>
+ <entry>Timeout value to use for remote communication.</entry>
+ </row>
+
+ <row>
+ <entry>gdb_init_command</entry>
+ <entry>"print/x \$fsr = 0x0"</entry>
+ </row>
+
+ <row>
+ <entry>gdb_load_offset</entry>
+ <entry>"0x12020000"</entry>
+ </row>
+
+ <row>
+ <entry>gdb_opts</entry>
+ <entry>"--command gdbinit"</entry>
+ </row>
+
+ <row>
+ <entry>gdb_prompt</entry>
+ <entry>"\\(gdb960\\)"</entry>
+ <entry>The prompt GDB is using.</entry>
+ </row>
+
+ <row>
+ <entry>gdb_run_command</entry>
+ <entry>"jump start"</entry>
+ </row>
+
+ <row>
+ <entry>gdb_stub_offset</entry>
+ <entry>"0x12010000"</entry>
+ </row>
+
+ <row>
+ <entry>use_gdb_stub</entry>
+ <entry>1</entry>
+ <entry>Whether to use a GDB stub.</entry>
+ </row>
+
+ <row>
+ <entry>use_vma_offset</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>wrap_m68k_aout</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>gcc,no_label_values</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>gcc,no_trampolines</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>gcc,no_varargs</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>gcc,stack_size</entry>
+ <entry>16384</entry>
+ <entry>Stack size to use with some GCC testcases.</entry>
+ </row>
+
+ <row>
+ <entry>ieee_multilib_flags</entry>
+ <entry>"-mieee";</entry>
+ </row>
+
+ <row>
+ <entry>is_simulator</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>needs_status_wrapper</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>no_double</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>no_long_long</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>noargs</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry>nullstone,lib</entry>
+ <entry>"mips-clock.c"</entry>
+ </row>
+
+ <row>
+ <entry>nullstone,ticks_per_sec</entry>
+ <entry>3782018</entry>
+ </row>
+
+ <row>
+ <entry>sys_speed_value</entry>
+ <entry>200</entry>
+ </row>
+
+ <row>
+ <entry>target_install</entry>
+ <entry>{sh-hms}</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+
+ </sect1>
+
+ <sect1 id=writing xreflabel="Writing A Test Case">
+ <title>Writing A Test Case</title>
+
+ <para>The easiest way to prepare a new test case is to base it
+ on an existing one for a similar situation. There are two major
+ categories of tests: batch or interactive. Batch oriented tests
+ are usually easier to write.</para>
+
+ <para>The GCC tests are a good example of batch oriented tests.
+ All GCC tests consist primarily of a call to a single common
+ procedure, Since all the tests either have no output, or only
+ have a few warning messages when successfully compiled. Any
+ non-warning output is a test failure. All the C code needed is
+ kept in the test directory. The test driver, written in Tcl,
+ need only get a listing of all the C files in the directory, and
+ compile them all using a generic procedure. This procedure and a
+ few others supporting for these tests are kept in the library
+ module <filename>lib/c-torture.exp</filename> in the GCC test
+ suite. Most tests of this kind use very few
+ <productname>expect</productname> features, and are coded almost
+ purely in Tcl.</para>
+
+ <para>Writing the complete suite of C tests, then, consisted of
+ these steps:</para>
+
+ <itemizedlist mark=bullet>
+ <listitem><para>Copying all the C code into the test directory.
+ These tests were based on the C-torture test created by Torbjorn
+ Granlund (on behalf of the Free Software Foundation) for GCC
+ development.</para></listitem>
+
+ <listitem><para>Writing (and debugging) the generic Tcl procedures for
+ compilation.</para></listitem>
+
+ <listitem><para>Writing the simple test driver: its main task is to
+ search the directory (using the Tcl procedure
+ <emphasis>glob</emphasis> for filename expansion with wildcards)
+ and call a Tcl procedure with each filename. It also checks for
+ a few errors from the testing procedure.</para></listitem>
+ </itemizedlist>
+
+ <para>Testing interactive programs is intrinsically more
+ complex. Tests for most interactive programs require some trial
+ and error before they are complete.</para>
+
+ <para>However, some interactive programs can be tested in a
+ simple fashion reminiscent of batch tests. For example, prior
+ to the creation of DejaGnu, the GDB distribution already
+ included a wide-ranging testing procedure. This procedure was
+ very robust, and had already undergone much more debugging and
+ error checking than many recent DejaGnu test cases.
+ Accordingly, the best approach was simply to encapsulate the
+ existing GDB tests, for reporting purposes. Thereafter, new GDB
+ tests built up a family of Tcl procedures specialized for GDB
+ testing.</para>
+
+ </sect1>
+
+ <sect1 id=debugging xreflabel="Debugging A Test Case">
+ <title>Debugging A Test Case</title>
+
+ <para>These are the kinds of debugging information available
+ from DejaGnu:</para>
+
+ <itemizedlist mark=bullet>
+
+ <listitem><para>Output controlled by test scripts themselves,
+ explicitly allowed for by the test author. This kind of
+ debugging output appears in the detailed output recorded in the
+ DejaGnu log file. To do the same for new tests, use the
+ <command>verbose</command> procedure (which in turn uses the
+ variable also called <emphasis>verbose</emphasis>) to control
+ how much output to generate. This will make it easier for other
+ people running the test to debug it if necessary. Whenever
+ possible, if <emphasis>$verbose</emphasis> is
+ <emphasis>0</emphasis>, there should be no output other than the
+ output from <emphasis>pass</emphasis>,
+ <emphasis>fail</emphasis>, <emphasis>error</emphasis>, and
+ <emphasis>warning</emphasis>. Then, to whatever extent is
+ appropriate for the particular test, allow successively higher
+ values of <emphasis>$verbose</emphasis> to generate more
+ information. Be kind to other programmers who use your tests:
+ provide for a lot of debugging information.</para>
+
+ <listitem><para>Output from the internal debugging functions of
+ Tcl and <productname>Expect</productname>. There is a command
+ line options for each; both forms of debugging output are
+ recorded in the file <filename>dbg.log</filename> in the current
+ directory.</para>
+
+ <para>Use <option>--debug</option> for information from the
+ expect level; it generates displays of the expect attempts to
+ match the tool output with the patterns specified. This output
+ can be very helpful while developing test scripts, since it
+ shows precisely the characters received. Iterating between the
+ latest attempt at a new test script and the corresponding
+ <filename>dbg.log</filename> can allow you to create the final
+ patterns by ``cut and paste''. This is sometimes the best way
+ to write a test case.</para>
+
+ <listitem><para>Use <option>--strace</option> to see more
+ detail at the Tcl level; this shows how Tcl procedure
+ definitions expand, as they execute. The associated number
+ controls the depth of definitions expanded.</para></listitem>
+
+ <listitem><para>Finally, if the value of
+ <emphasis>verbose</emphasis> is 3 or greater,DejaGnu turns on
+ the expect command <command>log_user</command>. This command
+ prints all expect actions to the expect standard output, to the
+ detailed log file, and (if <option>--debug</option> is on) to
+ <filename>dbg.log</filename>.</para>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 id=adding xreflabel="Adding A Test Case To A Test Suite">
+ <title>Adding A Test Case To A Test Suite.</title>
+
+ <para>There are two slightly different ways to add a test
+ case. One is to add the test case to an existing directory. The
+ other is to create a new directory to hold your test. The
+ existing test directories represent several styles of testing,
+ all of which are slightly different; examine the directories for
+ the tool of interest to see which (if any) is most suitable.</para>
+
+ <para>Adding a GCC test can be very simple: just add the C code
+ to any directory beginning with <filename>gcc</filename>. and it
+ runs on the next <programlisting>runtest --tool
+ gcc</programlisting>.</para>
+
+ <para>To add a test to GDB, first add any source code you will
+ need to the test directory. Then you can either create a new
+ expect file, or add your test to an existing one (any
+ file with a <emphasis>.exp</emphasis> suffix). Creating a new
+ .exp file is probably a better idea if the test is significantly
+ different from existing tests. Adding it as a separate file also
+ makes upgrading easier. If the C code has to be already compiled
+ before the test will run, then you'll have to add it to the
+ <filename>Makefile.in</filename> file for that test directory,
+ then run <command>configure</command> and
+ <command>make</command>.</para>
+
+ <para>Adding a test by creating a new directory is very
+ similar:</para>
+
+ <itemizedlist mark=bullet>
+
+ <listitem><para>Create the new directory. All subdirectory names
+ begin with the name of the tool to test; e.g. G++ tests might be
+ in a directory called <filename>g++.other</filename>. There can
+ be multiple test directories that start with the same tool name
+ (such as <emphasis>g++</emphasis>).</para></listitem>
+
+ <listitem><para>Add the new directory name to the
+ <symbol>configdirs</symbol> definition in the
+ <filename>configure.in</filename> file for the test suite
+ directory. This way when <command>make</command> and
+ <command>configure</command> next run, they include the new
+ directory.</para></listitem>
+
+ <listitem><para>Add the new test case to the directory, as
+ above. </para>
+
+ <listitem><para>To add support in the new directory for
+ configure and make, you must also create a
+ <filename>Makefile.in</filename> and a
+ <filename>configure.in</filename>.</para></listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 id=hints xreflabel="Hints On Writing A Test Case">
+ <title>Hints On Writing A Test Case</title>
+
+ <para>It is safest to write patterns that match all the output
+ generated by the tested program; this is called closure.
+ If a pattern does not match the entire output, any output that
+ remains will be examined by the next <command>expect</command>
+ command. In this situation, the precise boundary that determines
+ which <command>expect</command> command sees what is very
+ sensitive to timing between the Expect task and the task running
+ the tested tool. As a result, the test may sometimes appear to
+ work, but is likely to have unpredictable results. (This problem
+ is particularly likely for interactive tools, but can also
+ affect batch tools---especially for tests that take a long time
+ to finish.) The best way to ensure closure is to use the
+ <option>-re</option> option for the <command>expect</command>
+ command to write the pattern as a full regular expressions; then
+ you can match the end of output using a <emphasis>$</emphasis>.
+ It is also a good idea to write patterns that match all
+ available output by using <emphasis>.*\</emphasis> after the
+ text of interest; this will also match any intervening blank
+ lines. Sometimes an alternative is to match end of line using
+ <emphasis>\r</emphasis> or <emphasis>\n</emphasis>, but this is
+ usually too dependent on terminal settings.</para>
+
+ <para>Always escape punctuation, such as <emphasis>(</emphasis>
+ or <emphasis>"</emphasis>, in your patterns; for example, write
+ <emphasis>\(</emphasis>. If you forget to escape punctuation,
+ you will usually see an error message like <programlisting>extra
+ characters after close-quote.</programlisting></para>
+
+ <para>If you have trouble understanding why a pattern does not
+ match the program output, try using the <option>--debug</option>
+ option to <command>runtest</command>, and examine the debug log
+ carefully.</para>
+
+ <para>Be careful not to neglect output generated by setup rather
+ than by the interesting parts of a test case. For example,
+ while testing GDB, I issue a send <emphasis>set height
+ 0\n</emphasis> command. The purpose is simply to make sure GDB
+ never calls a paging program. The <emphasis>set
+ height</emphasis> command in GDB does not generate any
+ output; but running any command makes GDB issue a new
+ <emphasis>(gdb) </emphasis> prompt. If there were no
+ <command>expect</command> command to match this prompt, the
+ output <emphasis>(gdb) </emphasis> begins the text seen by the
+ next <command>expect</command> command---which might make that
+ pattern fail to match.</para>
+
+ <para>To preserve basic sanity, I also recommended that no test
+ ever pass if there was any kind of problem in the test case. To
+ take an extreme case, tests that pass even when the tool will
+ not spawn are misleading. Ideally, a test in this sort of
+ situation should not fail either. Instead, print an error
+ message by calling one of the DejaGnu procedures
+ <command>error</command> or <command>warning</command>.</para>
+
+ </sect1>
+
+ <sect1 id=tvariables xreflabel="Test Case Variables">
+ <title>Special variables used by test cases.</title>
+
+ <para>There are special variables used by test cases. These contain
+ other information from DejaGnu. Your test cases can use these variables,
+ with conventional meanings (as well as the variables saved in
+ <filename>site.exp</filename>. You can use the value of these variables,
+ but they should never be changed.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>$prms_id</term>
+ <listitem><para>The tracking system (e.g. GNATS) number identifying
+ a corresponding bugreport. (<emphasis>0</emphasis>} if you do not
+ specify it in the test script.)</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>$item bug_id</term>
+ <listitem><para>An optional bug id; may reflect a bug
+ identification from another organization. (<emphasis>0</emphasis>
+ if you do not specify it.)</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>$subdir</term>
+ <listitem><para>The subdirectory for the current test
+ case.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>$expect_out(buffer)</term>
+ <listitem><para>The output from the last command. This is an
+ internal variable set by Expect. More information can be found in
+ the Expect manual.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>$exec_output</term>
+ <listitem><para>This is the output from a
+ <function>${tool}_load</function> command. This only applies to
+ tools like GCC and GAS which produce an object file that must in
+ turn be executed to complete a test.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>$comp_output</term>
+ <listitem><para>This is the output from a
+ <function>${tool}_start</function> command. This is conventionally
+ used for batch oriented programs, like GCC and GAS, that may
+ produce interesting output (warnings, errors) without further
+ interaction.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect1>
+
+</chapter>
+
diff --git a/dejagnu/example/Makefile.am b/dejagnu/example/Makefile.am
new file mode 100644
index 00000000000..2c32b44a458
--- /dev/null
+++ b/dejagnu/example/Makefile.am
@@ -0,0 +1,5 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = dejagnu cygnus
+
+SUBDIRS = calc
diff --git a/dejagnu/example/Makefile.in b/dejagnu/example/Makefile.in
new file mode 100644
index 00000000000..2f826ce42f2
--- /dev/null
+++ b/dejagnu/example/Makefile.in
@@ -0,0 +1,314 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 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.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+BOARDS = @BOARDS@
+CC = @CC@
+CONFIG = @CONFIG@
+EXEEXT = @EXEEXT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+AUTOMAKE_OPTIONS = dejagnu cygnus
+
+SUBDIRS = calc
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_CLEAN_FILES =
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+EXPECT = `if test -f $(top_builddir)/../expect/expect; then echo $(top_builddir)/../expect/expect; else echo expect; fi`
+RUNTEST = `if test -f $(top_srcdir)/../dejagnu/runtest; then echo $(top_srcdir)/../dejagnu/runtest; else echo runtest; fi`
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus example/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = example
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+
+RUNTESTFLAGS =
+
+DEJATOOL = $(PACKAGE)
+
+RUNTESTDEFAULTFLAGS = --tool $(DEJATOOL) --srcdir $$srcdir
+
+check-DEJAGNU: site.exp
+ srcdir=`cd $(srcdir) && pwd`; export srcdir; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+site.exp: Makefile
+ @echo 'Making a new site.exp file...'
+ @test ! -f site.bak || rm -f site.bak
+ @echo '## these variables are automatically generated by make ##' > $@-t
+ @echo '# Do not edit here. If you wish to override these values' >> $@-t
+ @echo '# edit the last section' >> $@-t
+ @echo 'set tool $(DEJATOOL)' >> $@-t
+ @echo 'set srcdir $(srcdir)' >> $@-t
+ @echo 'set objdir' `pwd` >> $@-t
+ @echo '## All variables above are generated by configure. Do Not Edit ##' >> $@-t
+ @test ! -f site.exp || sed '1,/^## All variables above are.*##/ d' site.exp >> $@-t
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv $@-t site.exp
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am:
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-info-am:
+install-info: install-info-recursive
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+
+distclean: distclean-recursive
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+
+.PHONY: install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir check-DEJAGNU \
+info-am info dvi-am dvi check check-am installcheck-am installcheck \
+install-info-am install-info install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# 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/dejagnu/example/calc/Makefile.in b/dejagnu/example/calc/Makefile.in
new file mode 100644
index 00000000000..eb737969f15
--- /dev/null
+++ b/dejagnu/example/calc/Makefile.in
@@ -0,0 +1,110 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# target name
+PROG= calc
+
+# compiler specifics
+CC = @CC@
+CFLAGS = -g -I$(srcdir) -I.
+CALC = calc
+
+# directory specifics
+VPATH = @srcdir@
+srcdir = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+# testsuite specifics
+# Setup the testing framework, if you have one
+# Flags that we pass when building the testsuite.
+EXPECT = ` \
+ if [ -f $${rootme}/../../../expect/expect ] ; then \
+ echo $${rootme}/../../../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = ` \
+ if [ -f $${srcdir}/../../../dejagnu/runtest ] ; then \
+ echo $${srcdir}/../../../dejagnu/runtest ; \
+ else echo runtest ; fi`
+
+RUNTESTFLAGS=
+
+## --- NOTHING BELOW HERE SHOULD REQUIRE MODIFICATIONS --- ##
+
+SRCS= calc.c
+
+OBJS= calc.o
+
+all: ${PROG}
+
+calc.o: calc.c
+
+.c.o:
+ ${CC} ${CFLAGS} -I$(srcdir) -I. -c $<
+
+${PROG}: ${OBJS} ${DPADD}
+ ${CC} ${LDFLAGS} ${CFLAGS} -o $@ ${OBJS} ${DPADD} ${LDADD}
+
+check: site.exp all
+ rootme=`pwd`; export rootme; \
+ srcdir=${srcdir} ; export srcdir ; \
+ EXPECT=${EXPECT} ; export EXPECT ; \
+ if [ -f $${rootme}/../../expect/expect ] ; then \
+ TCL_LIBRARY=$${srcdir}/../../tcl/library ; \
+ export TCL_LIBRARY ; fi ; \
+ ${RUNTEST} ${RUNTESTFLAGS} --tool ${PROG} CALC=${PROG} --srcdir ${srcdir}/testsuite
+
+site.exp: ./config.status Makefile
+ @echo "Making a new config file..."
+ -@rm -f ./tmp?
+ @touch site.exp
+
+ -@mv site.exp site.bak
+ @echo "## these variables are automatically generated by make ##" > ./tmp0
+ @echo "# Do not edit here. If you wish to override these values" >> ./tmp0
+ @echo "# add them to the last section" >> ./tmp0
+ @echo "set tool calc" >> ./tmp0
+ @echo "set srcdir ${srcdir}" >> ./tmp0
+ @echo "set objdir `pwd`" >> ./tmp0
+ @echo "## All variables above are generated by configure. Do Not Edit ##" >> ./tmp0
+ @cat ./tmp0 > site.exp
+ @cat site.bak | sed \
+ -e '1,/^## All variables above are.*##/ d' >> site.exp
+ -@rm -f ./tmp?
+
+install: ${PROG}
+
+clean mostlyclean:
+ rm -f a.out [Ee]rrs tags mklog core ${OBJS} ${PROG}
+
+distclean maintainer-clean realclean: clean
+ rm -f config.status Makefile calc.h calc.log calc.plog calc.psum
+ rm -f calc.sum site.exp config.log
+
+Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) config.status
+ @echo "Rebuilding the Makefile..."
+ $(SHELL) ./config.status
+
+configure: $(srcdir)/configure.in $(srcdir)/Makefile.in $(srcdir)/../../aclocal.m4
+ @echo "Rebuilding configure..."
+ @cd ${srcdir} ;\
+ autoconf --localdir=${srcdir}/../..
+
+config.status:
+ @echo "Rebuilding config.status..."
+ $(SHELL) ./config.status --recheck
diff --git a/dejagnu/example/calc/calc.1 b/dejagnu/example/calc/calc.1
new file mode 100644
index 00000000000..ea603933821
--- /dev/null
+++ b/dejagnu/example/calc/calc.1
@@ -0,0 +1,29 @@
+.\"
+.TH SKEL 1 "28th Jan 1993"
+.SH NAME
+calc \- a very dumb calculator to demonstrate
+.I deja-gnu
+.SH SYNOPSIS
+.B calc
+.SH DESCRIPTION
+.LP
+.B calc
+accepts the commands:
+.TP
+.B add #1 #2
+Add #1 and #2 and print the answer.
+.TP
+.B multiply #1 #2
+Multiply #1 and #2 and print the answer.
+.TP
+.B quit
+.br
+Exit
+.TP
+.B version
+Print a version string.
+.SH BUGS
+.LP
+.B multiply 2 n
+gives the wrong answer (unless n == 0).
+
diff --git a/dejagnu/example/calc/calc.c b/dejagnu/example/calc/calc.c
new file mode 100644
index 00000000000..784e39b7c71
--- /dev/null
+++ b/dejagnu/example/calc/calc.c
@@ -0,0 +1,65 @@
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <ctype.h>
+#include <stdio.h>
+#include "calc.h"
+
+static int words();
+
+int main()
+{
+ char line[SIZE];
+ int nword;
+ char *words[NWORD];
+
+ while(printf("calc: "), fflush(stdout), fgets(line,SIZE,stdin) != NULL) {
+ if((nword = split(line,words,NWORD)) == 0) continue;
+ if(strcmp(words[0],"add") == 0) {
+ if(nword != 3) {
+ printf("Usage: add #1 #2\n");
+ } else {
+ printf("%d",atoi(words[1]) + atoi(words[2]));
+ }
+ } else if(strcmp(words[0],"multiply") == 0) {
+ if(nword != 3) {
+ printf("Usage: multiply #1 #2\n");
+ } else {
+ int i1 = atoi(words[1]);
+ if(i1 == 2) i1 = 3; /* this is a bug */
+ printf("%d",i1*atoi(words[2]));
+ }
+ } else if(strcmp(words[0],"quit") == 0) {
+ break;
+ } else if(strcmp(words[0],"version") == 0) {
+ printf("Version: %s",VERSION);
+ } else {
+ printf("Unknown command: %s",words[0]);
+ }
+ printf("\n");
+ }
+
+ return(0);
+}
+
+int
+split(line,words,nword)
+char *line;
+char **words;
+int nword; /* number of elements in words */
+{
+ int i;
+
+ while(isspace(*line)) line++;
+ if(*line == '\0') return(0);
+
+ for(i = 0;i < nword;i++) {
+ words[i] = line;
+ while(*line != '\0' && !isspace(*line)) line++;
+ if(*line == '\0') break;
+ *line++ = '\0';
+ while(isspace(*line)) line++;
+ }
+
+ return(i);
+}
diff --git a/dejagnu/example/calc/calc.h.in b/dejagnu/example/calc/calc.h.in
new file mode 100644
index 00000000000..1e420a77c4f
--- /dev/null
+++ b/dejagnu/example/calc/calc.h.in
@@ -0,0 +1,18 @@
+/*
+ * Check for headers
+ */
+#ifndef __CALC_H__
+#define __CALC_H__
+
+#undef HAVE_STDLIB_H
+
+/*
+ * Check for functions
+ */
+#undef HAVE_STRCMP
+
+#define NWORD 10
+#define SIZE 100
+#define VERSION "1.0 Beta"
+
+#endif /* __CALC_H__ */
diff --git a/dejagnu/example/calc/configure b/dejagnu/example/calc/configure
new file mode 100755
index 00000000000..e58d5cff323
--- /dev/null
+++ b/dejagnu/example/calc/configure
@@ -0,0 +1,1031 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=calc.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+CC=${CC-cc}
+
+#
+# Look for various header files
+#
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:530: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 545 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:551: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 562 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:568: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+ac_safe=`echo "stdlib.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6
+echo "configure:592: checking for stdlib.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 597 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:602: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define HAVE_STDLIB_H 1
+EOF
+
+fi
+
+
+#
+# Look for various functions
+#
+echo $ac_n "checking for strcmp""... $ac_c" 1>&6
+echo "configure:632: checking for strcmp" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strcmp'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 637 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strcmp(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strcmp();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strcmp) || defined (__stub___strcmp)
+choke me
+#else
+strcmp();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_strcmp=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strcmp=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strcmp`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRCMP 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+#
+# Output Makefile with substitutions
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile calc.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CPP@%$CPP%g
+s%@CC@%$CC%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="calc.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/dejagnu/example/calc/configure.in b/dejagnu/example/calc/configure.in
new file mode 100644
index 00000000000..3ee022a441b
--- /dev/null
+++ b/dejagnu/example/calc/configure.in
@@ -0,0 +1,20 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.5)
+AC_INIT(calc.c)
+AC_CONFIG_HEADER(calc.h)
+CC=${CC-cc}
+
+#
+# Look for various header files
+#
+AC_HEADER_CHECK(stdlib.h, ,AC_DEFINE(HAVE_STDLIB_H))
+
+#
+# Look for various functions
+#
+AC_FUNC_CHECK(strcmp, AC_DEFINE(HAVE_STRCMP))
+
+#
+# Output Makefile with substitutions
+AC_SUBST(CC)
+AC_OUTPUT(Makefile)
diff --git a/dejagnu/example/calc/testsuite/calc.test/calc.exp b/dejagnu/example/calc/testsuite/calc.test/calc.exp
new file mode 100644
index 00000000000..8986cf53480
--- /dev/null
+++ b/dejagnu/example/calc/testsuite/calc.test/calc.exp
@@ -0,0 +1,79 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+set timeout 3
+#
+# expectations that clean up in case of error. Note that `$test' is
+# a purely local variable.
+#
+# The first of these is used to match any bad responses, and resynchronise
+# things by finding a prompt. The second is a timeout error, and shouldn't
+# ever be triggered.
+#
+expect_after {
+ -re "\[^\n\r\]*$prompt$" {
+ fail "$test (bad match)"
+ if { $verbose > 0 } {
+ regexp ".*\r\n(\[^\r\n\]+)(\[\r\n\])+$prompt$" \
+ $expect_out(buffer) "" output
+ send_user "\tUnmatched output: \"$output\"\n"
+ }
+ }
+ timeout {
+ fail "$test (timeout)"
+ }
+}
+#
+# Here are the tests
+#
+set test "version"
+send "version\n"
+expect {
+ -re "Version:.*$prompt$" { pass "version" }
+}
+
+set test add1
+send "add 3 4\n"
+expect {
+ -re "7+.*$prompt$" { pass "$test" }
+}
+
+set test add2
+send "add 1 2 3\n"
+expect {
+ -re "Usage: add #1 #2.*$prompt$" { pass "$test" }
+}
+
+set test multiply1
+send "multiply 3 4\n"
+expect {
+ -re "12.*$prompt$" { pass "$test" }
+}
+
+set test multiply2
+send "multiply 2 4\n"
+expect {
+ -re "8.*$prompt$" { pass "$test" }
+}
+
+set test multiply3
+send "multiply 1 2 3\n"
+expect {
+ -re "Usage: multiply #1 #2.*$prompt$" { pass "$test" }
+}
diff --git a/dejagnu/example/calc/testsuite/config/unix.exp b/dejagnu/example/calc/testsuite/config/unix.exp
new file mode 100644
index 00000000000..9b73ac787b1
--- /dev/null
+++ b/dejagnu/example/calc/testsuite/config/unix.exp
@@ -0,0 +1,68 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+if ![info exists prompt] then {
+ set prompt "calc: "
+}
+#
+# calc_version -- extract and print the version number of calc
+#
+
+proc calc_version {} {
+ global CALC
+ global prompt
+ set tmp [exec echo "version" | $CALC]
+ regexp "$prompt *(\[^\n\]*)\n.*" $tmp tmp version
+ clone_output "[which $CALC] version $version\n"
+}
+#
+# calc_load -- loads the program
+#
+proc calc_load { arg } {
+ #
+}
+
+#
+# calc_exit -- quit and cleanup
+#
+proc calc_exit {} {
+ send "quit\n"
+}
+
+#
+# calc_start -- start calc running
+#
+proc calc_start {} {
+ global CALC
+ global prompt
+ global spawn_id
+ global verbose
+
+ if { $verbose > 1 } {
+ send_user "starting $CALC\n"
+ }
+ spawn $CALC
+ expect {
+ -re "No such file.*" { perror "Can't start $CALC"; exit 1 }
+ -re "$prompt$" { }
+ timeout { perror "Failed to spawn $CALC (timeout)"; exit 1 }
+ }
+}
+
+calc_start
diff --git a/dejagnu/i960glue.c b/dejagnu/i960glue.c
new file mode 100644
index 00000000000..0dc569d1c57
--- /dev/null
+++ b/dejagnu/i960glue.c
@@ -0,0 +1,19 @@
+#include "../newlib/libc/ctype/ctype_.c"
+#include "../newlib/libc/stdlib/strtol.c"
+#include "../newlib/libc/stdlib/atoi.c"
+#include "../newlib/libc/reent/impure.c"
+
+
+/* these are for ld -r -wrap */
+
+void
+__real_exit (int code)
+{
+ exit (code);
+}
+
+void
+__real_abort (void)
+{
+ abort ();
+}
diff --git a/dejagnu/install-sh b/dejagnu/install-sh
new file mode 100755
index 00000000000..e0421dd815b
--- /dev/null
+++ b/dejagnu/install-sh
@@ -0,0 +1,250 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/dejagnu/lib/debugger.exp b/dejagnu/lib/debugger.exp
new file mode 100644
index 00000000000..f00076d7dcf
--- /dev/null
+++ b/dejagnu/lib/debugger.exp
@@ -0,0 +1,244 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+#
+# Dump the values of a shell expression representing variable
+# names.
+proc dumpvars { args } {
+ uplevel 1 [list foreach i [uplevel 1 "info vars $args"] {
+ if { [catch "array names $i" names ] } {
+ eval "puts \"${i} = \$${i}\""
+ } else {
+ foreach k $names {
+ eval "puts \"$i\($k\) = \$$i\($k\)\""
+ }
+ }
+ }
+ ]
+}
+
+#
+# dump the values of a shell expression representing variable
+# names.
+proc dumplocals { args } {
+ uplevel 1 [list foreach i [uplevel 1 "info locals $args"] {
+ if { [catch "array names $i" names ] } {
+ eval "puts \"${i} = \$${i}\""
+ } else {
+ foreach k $names {
+ eval "puts \"$i\($k\) = \$$i\($k\)\""
+ }
+ }
+ }
+ ]
+}
+#
+# Dump the body of procedures specified by a regexp.
+#
+proc dumprocs { args } {
+ foreach i [info procs $args] {
+ puts "\nproc $i \{ [info args $i] \} \{ [info body $i]\}"
+ }
+}
+
+#
+# Dump all the current watchpoints
+#
+proc dumpwatch { args } {
+ foreach i [uplevel 1 "info vars $args"] {
+ set tmp ""
+ if { [catch "uplevel 1 array name $i" names] } {
+ set tmp [uplevel 1 trace vinfo $i]
+ if ![string match "" $tmp] {
+ puts "$i $tmp"
+ }
+ } else {
+ foreach k $names {
+ set tmp [uplevel 1 trace vinfo [set i]($k)]
+ if ![string match "" $tmp] {
+ puts "[set i]($k) = $tmp"
+ }
+ }
+ }
+ }
+}
+
+#
+# Trap a watchpoint for an array
+#
+proc watcharray { element type} {
+ upvar [set array]($element) avar
+ case $type {
+ "w" { puts "New value of [set array]($element) is $avar" }
+ "r" { puts "[set array]($element) (= $avar) was just read" }
+ "u" { puts "[set array]($element) (= $avar) was just unset" }
+ }
+}
+
+proc watchvar { v type } {
+ upvar $v var
+ case $type {
+ "w" { puts "New value of $v is $var" }
+ "r" { puts "$v (=$var) was just read" }
+ "u" { puts "$v (=$var) was just unset" }
+ }
+}
+
+#
+# Watch when a variable is written
+#
+proc watchunset { arg } {
+ if { [catch "uplevel 1 array name $arg" names ] } {
+ if ![uplevel 1 info exists $arg] {
+ puts stderr "$arg does not exist"
+ return
+ }
+ uplevel 1 trace variable $arg u watchvar
+ } else {
+ foreach k $names {
+ if ![uplevel 1 info exists $arg] {
+ puts stderr "$arg does not exist"
+ return
+ }
+ uplevel 1 trace variable [set arg]($k) u watcharray
+ }
+ }
+}
+
+#
+# Watch when a variable is written
+#
+proc watchwrite { arg } {
+ if { [catch "uplevel 1 array name $arg" names ] } {
+ if ![uplevel 1 info exists $arg] {
+ puts stderr "$arg does not exist"
+ return
+ }
+ uplevel 1 trace variable $arg w watchvar
+ } else {
+ foreach k $names {
+ if ![uplevel 1 info exists $arg] {
+ puts stderr "$arg does not exist"
+ return
+ }
+ uplevel 1 trace variable [set arg]($k) w watcharray
+ }
+ }
+}
+
+#
+# Watch when a variable is read
+#
+proc watchread { arg } {
+ if { [catch "uplevel 1 array name $arg" names ] } {
+ if ![uplevel 1 info exists $arg] {
+ puts stderr "$arg does not exist"
+ return
+ }
+ uplevel 1 trace variable $arg r watchvar
+ } else {
+ foreach k $names {
+ if ![uplevel 1 info exists $arg] {
+ puts stderr "$arg does not exist"
+ return
+ }
+ uplevel 1 trace variable [set arg]($k) r watcharray
+ }
+ }
+}
+
+#
+# Delete a watch point
+#
+proc watchdel { args } {
+ foreach i [uplevel 1 "info vars $args"] {
+ set tmp ""
+ if { [catch "uplevel 1 array name $i" names] } {
+ catch "uplevel 1 trace vdelete $i w watchvar"
+ catch "uplevel 1 trace vdelete $i r watchvar"
+ catch "uplevel 1 trace vdelete $i u watchvar"
+ } else {
+ foreach k $names {
+ catch "uplevel 1 trace vdelete [set i]($k) w watcharray"
+ catch "uplevel 1 trace vdelete [set i]($k) r watcharray"
+ catch "uplevel 1 trace vdelete [set i]($k) u watcharray"
+ }
+ }
+ }
+}
+
+#
+# This file creates GDB style commands for the Tcl debugger
+#
+proc print { var } {
+ puts "$var"
+}
+
+proc quit { } {
+ log_and_exit;
+}
+
+proc bt { } {
+ puts "[w]"
+}
+
+#
+# create some stub procedures since we can't alias the command names
+#
+proc dp { args } {
+ uplevel 1 dumprocs $args
+}
+
+proc dv { args } {
+ uplevel 1 dumpvars $args
+}
+
+proc dl { args } {
+ uplevel 1 dumplocals $args
+}
+
+proc dw { args } {
+ uplevel 1 dumpwatch $args
+}
+
+proc q { } {
+ quit
+}
+
+proc p { args } {
+ uplevel 1 print $args
+}
+
+proc wu { args } {
+ uplevel 1 watchunset $args
+}
+
+proc ww { args } {
+ uplevel 1 watchwrite $args
+}
+
+proc wr { args } {
+ uplevel 1 watchread $args
+}
+
+proc wd { args } {
+ uplevel 1 watchdel $args
+}
diff --git a/dejagnu/lib/dg.exp b/dejagnu/lib/dg.exp
new file mode 100644
index 00000000000..d733388bad9
--- /dev/null
+++ b/dejagnu/lib/dg.exp
@@ -0,0 +1,909 @@
+# `dg' general purpose testcase driver.
+# Copyright (C) 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# dje@cygnus.com.
+
+# This file was written by Doug Evans (dje@cygnus.com).
+
+# This file is based on old-dejagnu.exp. It is intended to be more extensible
+# without incurring the overhead that old-dejagnu.exp can. All test framework
+# commands appear in the testcase as "{ dg-xxx args ... }". We pull them out
+# with one grep, and then run the function(s) named by "dg-xxx". When running
+# dg-xxx, the line number that it occurs on is always passed as the first
+# argument. We also support different kinds of tools via callbacks.
+#
+# The currently supported options are:
+#
+# dg-prms-id N
+# set prms_id to N
+#
+# dg-options "options ..." [{ target selector }]
+# specify special options to pass to the tool (eg: compiler)
+#
+# dg-do do-what-keyword [{ target/xfail selector }]
+# `do-what-keyword' is tool specific and is passed unchanged to
+# ${tool}-dg-test. An example is gcc where `keyword' can be any of:
+# preprocess|compile|assemble|link|run
+# and will do one of: produce a .i, produce a .s, produce a .o,
+# produce an a.out, or produce an a.out and run it (the default is
+# compile).
+#
+# dg-error regexp comment [{ target/xfail selector } [{.|0|linenum}]]
+# indicate an error message <regexp> is expected on this line
+# (the test fails if it doesn't occur)
+# Linenum=0 for general tool messages (eg: -V arg missing).
+# "." means the current line.
+#
+# dg-warning regexp comment [{ target/xfail selector } [{.|0|linenum}]]
+# indicate a warning message <regexp> is expected on this line
+# (the test fails if it doesn't occur)
+#
+# dg-bogus regexp comment [{ target/xfail selector } [{.|0|linenum}]]
+# indicate a bogus error message <regexp> use to occur here
+# (the test fails if it does occur)
+#
+# dg-build regexp comment [{ target/xfail selector }]
+# indicate the build use to fail for some reason
+# (errors covered here include bad assembler generated, tool crashes,
+# and link failures)
+# (the test fails if it does occur)
+#
+# dg-excess-errors comment [{ target/xfail selector }]
+# indicate excess errors are expected (any line)
+# (this should only be used sparingly and temporarily)
+#
+# dg-output regexp [{ target selector }]
+# indicate the expected output of the program is <regexp>
+# (there may be multiple occurrences of this, they are concatenated)
+#
+# dg-final { tcl code }
+# add some tcl code to be run at the end
+# (there may be multiple occurrences of this, they are concatenated)
+# (unbalanced braces must be \-escaped)
+#
+# "{ target selector }" is a list of expressions that determine whether the
+# test succeeds or fails for a particular target, or in some cases whether the
+# option applies for a particular target. If the case of `dg-do' it specifies
+# whether the testcase is even attempted on the specified target.
+#
+# The target selector is always optional. The format is one of:
+#
+# { xfail *-*-* ... } - the test is expected to fail for the given targets
+# { target *-*-* ... } - the option only applies to the given targets
+#
+# At least one target must be specified, use *-*-* for "all targets".
+# At present it is not possible to specify both `xfail' and `target'.
+# "native" may be used in place of "*-*-*".
+#
+# Example:
+#
+# [ ... some complicated code ... ]
+# return a; /* { dg-build "fatal" "ran out of spill regs" { xfail i386-*-* } } */
+#
+# In this example, the compiler use to crash on the "return a;" for some
+# target and that it still does crash on i386-*-*. Admittedly, this is a
+# contrived example.
+#
+# ??? It might be possible to add additional optional arguments by having
+# something like: { dg-error ".*syntax.*" "syntax error" { { foo 1 } ... } }
+#
+# Callbacks
+#
+# ${tool}-dg-test testfile do-what-keyword extra-flags
+#
+# Run the test, be it compiler, assembler, or whatever.
+#
+# ${tool}-dg-prune target_triplet text
+#
+# Optional callback to delete output from the tool that can occur
+# even in successful ("pass") situations and interfere with output
+# pattern matching. This also gives the tool an opportunity to review
+# the output and check for any conditions which indicate an "untested"
+# or "unresolved" state. An example is if a testcase is too big and
+# fills all available ram (which can happen for 16 bit cpus). The
+# result is either the pruned text or
+# "::untested|unresolved|unsupported::message"
+# (eg: "::unsupported::memory full").
+#
+# Notes:
+# 1) All runnable testcases must return 0 from main() for success.
+# You can't rely on getting any return code from target boards, and the
+# `exec' command says a program fails if it returns non-zero.
+#
+# Language independence is (theoretically) achieved by:
+#
+# 1) Using global $tool to indicate the language (eg: gcc, g++, gas, etc.).
+# This should only be used to look up other objects. We don't want to
+# have to add code for each new language that is supported. If this is
+# done right, no code needs to be added here for each new language.
+#
+# 2) Passing tool options in as arguments.
+#
+# Earlier versions of ${tool}_start (eg: gcc_start) would only take the name
+# of the file to compile as an argument. Newer versions accept a list of
+# one or two elements, the second being a string of *all* options to pass
+# to the tool. We require this facility.
+#
+# 3) Callbacks.
+#
+# Try not to do anything else that makes life difficult.
+#
+# The normal way to write a testsuite is to have a .exp file containing:
+#
+# load_lib ${tool}-dg.exp
+# dg-init
+# dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/foo*]] ...
+# dg-finish
+
+# Global state variables.
+# The defaults are for GCC.
+
+# The default do-what keyword.
+set dg-do-what-default compile
+
+# When dg-interpreter-batch-mode is 1, no execution test or excess error
+# tests are performed.
+set dg-interpreter-batch-mode 0
+
+# Line number format. This is how line numbers appear in program output.
+set dg-linenum-format ":%d:"
+proc dg-format-linenum { linenum } {
+ global dg-linenum-format
+ return [format ${dg-linenum-format} $linenum]
+}
+
+# Useful subroutines.
+
+# dg-get-options -- pick out the dg-xxx options in a testcase
+#
+# PROG is the file name of the testcase.
+# The result is a list of options found.
+#
+# Example: For the following testcase:
+#
+# /* { dg-prms-id 1234 } */
+# int foo { return 0; } /* { dg-build fatal "some comment" } */
+#
+# we return:
+#
+# { dg-prms-id 1 1234 } { dg-build 2 fatal "some comment" }
+
+proc dg-get-options { prog } {
+ set result ""
+
+ set tmp [grep $prog "{\[ \t\]\+dg-\[-a-z\]\+\[ \t\]\+.*\[ \t\]\+}" line]
+ if ![string match "" $tmp] {
+ foreach i $tmp {
+ #send_user "Found: $i\n"
+ # FIXME: When to use "+" and "\+" isn't clear.
+ # Seems to me it took awhile to get this to work.
+ regexp "(\[0-9\]\+)\[ \t\]\+{\[ \t\]+(dg-\[-a-z\]+)\[ \t\]\+(.*)\[ \t\]+}\[^\}\]*(\n|$)" $i i line cmd args
+ #send_user "Found: $cmd $line $args\n"
+ append result " { $cmd $line $args }"
+ }
+ }
+
+ #send_user "Returning: $result\n"
+ return $result
+}
+
+#
+# Process optional xfail/target arguments
+#
+# SELECTOR is "xfail target-triplet-1 ..." or "target target-triplet-1 ..."
+# `target-triplet' may be "native".
+# For xfail, the result is "F" (expected to Fail) if the current target is
+# affected, otherwise "P" (expected to Pass).
+# For target, the result is "S" (target is Selected) if the target is selected,
+# otherwise "N" (target is Not selected).
+#
+proc dg-process-target { selector } {
+ global target_triplet
+
+ set isnative [isnative]
+ set triplet_match 0
+
+ #send_user "dg-process-target: $selector\n"
+
+ set selector [string trim $selector]
+ if [regexp "^xfail " $selector] {
+ set what xfail
+ } elseif [regexp "^target " $selector] {
+ set what target
+ } else {
+ # The use of error here and in other dg-xxx utilities is intentional.
+ # dg-test will catch them and do the right thing.
+ error "syntax error in target selector \"$selector\""
+ }
+
+ # ??? This should work but it doesn't. tcl bug?
+ #if [regexp "^${what}(( \[^ \]+-\[^ \]+-\[^ \]+)|( native))+$" $selector tmp selector]
+ if [regexp "^${what}( \[^ \]+-\[^ \]+-\[^ \]+| native)+$" $selector] {
+ regsub "^${what} " $selector "" selector
+ #send_user "selector: $selector\n"
+ foreach triplet $selector {
+ if [string match $triplet $target_triplet] {
+ set triplet_match 1
+ } elseif { $isnative && $triplet == "native" } {
+ set triplet_match 1
+ }
+ }
+ } else {
+ error "syntax error in target selector \"$selector\""
+ }
+
+ if { $triplet_match } {
+ return [expr { $what == "xfail" ? "F" : "S" }]
+ } else {
+ return [expr { $what == "xfail" ? "P" : "N" }]
+ }
+}
+
+# Predefined user option handlers.
+# The line number is always the first element.
+# Note that each of these are varargs procs (they have an `args' argument).
+# Tests for optional arguments are coded with ">=" to simplify adding new ones.
+
+proc dg-prms-id { args } {
+ global prms_id ;# this is a testing framework variable
+
+ if { [llength $args] > 2 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ set prms_id [lindex $args 1]
+}
+
+#
+# Set tool options
+#
+# Different options can be used for different targets by having multiple
+# instances, selecting a different target each time. Since options are
+# processed in order, put the default value first. Subsequent occurrences
+# will override previous ones.
+#
+
+proc dg-options { args } {
+ upvar dg-extra-tool-flags extra-tool-flags
+
+ if { [llength $args] > 3 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ if { [llength $args] >= 3 } {
+ switch [dg-process-target [lindex $args 2]] {
+ "S" { set extra-tool-flags [lindex $args 1] }
+ "N" { }
+ "F" { error "[lindex $args 0]: `xfail' not allowed here" }
+ "P" { error "[lindex $args 0]: `xfail' not allowed here" }
+ }
+ } else {
+ set extra-tool-flags [lindex $args 1]
+ }
+}
+
+#
+# Record what to do (compile/run/etc.)
+#
+# Multiple instances are supported (since we don't support target and xfail
+# selectors on one line), though it doesn't make much sense to change the
+# compile/assemble/link/run field. Nor does it make any sense to have
+# multiple lines of target selectors (use one line).
+#
+proc dg-do { args } {
+ upvar dg-do-what do-what
+
+ if { [llength $args] > 3 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ set selected [lindex ${do-what} 1] ;# selected? (""/S/N)
+ set expected [lindex ${do-what} 2] ;# expected to pass/fail (P/F)
+
+ if { [llength $args] >= 3 } {
+ switch [dg-process-target [lindex $args 2]] {
+ "S" {
+ set selected "S"
+ }
+ "N" {
+ # Don't deselect a target if it's been explicitly selected,
+ # but indicate a specific target has been selected (so don't
+ # do this testcase if it's not appropriate for this target).
+ # The user really shouldn't have multiple lines of target
+ # selectors, but try to do the intuitive thing (multiple lines
+ # are OR'd together).
+ if { $selected != "S" } {
+ set selected "N"
+ }
+ }
+ "F" { set expected "F" }
+ "P" {
+ # There's nothing to do for "P". We don't want to clobber a
+ # previous xfail for this target.
+ }
+ }
+ } else {
+ # Note: A previous occurrence of `dg-do' with target/xfail selectors
+ # is a user mistake. We clobber previous values here.
+ set selected S
+ set expected P
+ }
+
+ switch [lindex $args 1] {
+ "preprocess" { }
+ "compile" { }
+ "assemble" { }
+ "link" { }
+ "run" { }
+ default {
+ error "[lindex $args 0]: syntax error"
+ }
+ }
+ set do-what [list [lindex $args 1] $selected $expected]
+}
+
+proc dg-error { args } {
+ upvar dg-messages messages
+
+ if { [llength $args] > 5 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ set xfail ""
+ if { [llength $args] >= 4 } {
+ switch [dg-process-target [lindex $args 3]] {
+ "F" { set xfail "X" }
+ "P" { set xfail "" }
+ "N" {
+ # If we get "N", this error doesn't apply to us so ignore it.
+ return
+ }
+ }
+ }
+
+ if { [llength $args] >= 5 } {
+ switch [lindex $args 4] {
+ "." { set line [dg-format-linenum [lindex $args 0]] }
+ "0" { set line "" }
+ "default" { set line [dg-format-linenum [lindex $args 4]] }
+ }
+ } else {
+ set line [dg-format-linenum [lindex $args 0]]
+ }
+
+ lappend messages [list $line "${xfail}ERROR" [lindex $args 1] [lindex $args 2]]
+}
+
+proc dg-warning { args } {
+ upvar dg-messages messages
+
+ if { [llength $args] > 5 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ set xfail ""
+ if { [llength $args] >= 4 } {
+ switch [dg-process-target [lindex $args 3]] {
+ "F" { set xfail "X" }
+ "P" { set xfail "" }
+ "N" {
+ # If we get "N", this warning doesn't apply to us so ignore it.
+ return
+ }
+ }
+ }
+
+ if { [llength $args] >= 5 } {
+ switch [lindex $args 4] {
+ "." { set line [dg-format-linenum [lindex $args 0]] }
+ "0" { set line "" }
+ "default" { set line [dg-format-linenum [lindex $args 4]] }
+ }
+ } else {
+ set line [dg-format-linenum [lindex $args 0]]
+ }
+
+ lappend messages [list $line "${xfail}WARNING" [lindex $args 1] [lindex $args 2]]
+}
+
+proc dg-bogus { args } {
+ upvar dg-messages messages
+
+ if { [llength $args] > 5 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ set xfail ""
+ if { [llength $args] >= 4 } {
+ switch [dg-process-target [lindex $args 3]] {
+ "F" { set xfail "X" }
+ "P" { set xfail "" }
+ "N" {
+ # If we get "N", this message doesn't apply to us so ignore it.
+ return
+ }
+ }
+ }
+
+ if { [llength $args] >= 5 } {
+ switch [lindex $args 4] {
+ "." { set line [dg-format-linenum [lindex $args 0]] }
+ "0" { set line "" }
+ "default" { set line [dg-format-linenum [lindex $args 4]] }
+ }
+ } else {
+ set line [dg-format-linenum [lindex $args 0]]
+ }
+
+ lappend messages [list $line "${xfail}BOGUS" [lindex $args 1] [lindex $args 2]]
+}
+
+proc dg-build { args } {
+ upvar dg-messages messages
+
+ if { [llength $args] > 4 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ set xfail ""
+ if { [ llength $args] >= 4 } {
+ switch [dg-process-target [lindex $args 3]] {
+ "F" { set xfail "X" }
+ "P" { set xfail "" }
+ "N" {
+ # If we get "N", this lossage doesn't apply to us so ignore it.
+ return
+ }
+ }
+ }
+
+ lappend messages [list [lindex $args 0] "${xfail}BUILD" [lindex $args 1] [lindex $args 2]]
+}
+
+proc dg-excess-errors { args } {
+ upvar dg-excess-errors-flag excess-errors-flag
+
+ if { [llength $args] > 3 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ if { [llength $args] >= 3 } {
+ switch [dg-process-target [lindex $args 2]] {
+ "F" { set excess-errors-flag 1 }
+ "S" { set excess-errors-flag 1 }
+ }
+ } else {
+ set excess-errors-flag 1
+ }
+}
+
+#
+# Indicate expected program output
+#
+# We support multiple occurrences, but we do not implicitly insert newlines
+# between them.
+#
+# Note that target boards don't all support this kind of thing so it's a good
+# idea to specify the target all the time. If one or more targets are
+# explicitly selected, the test won't be performed if we're not one of them
+# (as long as we were never mentioned).
+#
+# If you have target dependent output and want to set an xfail for one or more
+# of them, use { dg-output "" { xfail a-b-c ... } }. The "" won't contribute
+# to the expected output.
+#
+proc dg-output { args } {
+ upvar dg-output-text output-text
+
+ if { [llength $args] > 3 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ # Allow target dependent output.
+
+ set expected [lindex ${output-text} 0]
+ if { [llength $args] >= 3 } {
+ switch [dg-process-target [lindex $args 2]] {
+ "N" { return }
+ "S" { }
+ "F" { set expected "F" }
+ # Don't override a previous xfail.
+ "P" { }
+ }
+ }
+
+ if { [llength ${output-text}] == 1 } {
+ # First occurrence.
+ set output-text [list $expected [lindex $args 1]]
+ } else {
+ set output-text [list $expected "[lindex ${output-text} 1][lindex $args 1]"]
+ }
+}
+
+proc dg-final { args } {
+ upvar dg-final-code final-code
+
+ if { [llength $args] > 2 } {
+ error "[lindex $args 0]: too many arguments"
+ return
+ }
+
+ #send_user "dg-final: $args\n"
+ append final-code "[lindex $args 1]\n"
+}
+
+#
+# Set up our environment
+#
+# There currently isn't much to do, but always calling it allows us to add
+# enhancements without having to update our callers.
+# It must be run before calling `dg-test'.
+
+proc dg-init { } {
+}
+
+# dg-runtest -- simple main loop useful to most testsuites
+#
+# FLAGS is a set of options to always pass.
+# DEFAULT_EXTRA_FLAGS is a set of options to pass if the testcase doesn't
+# specify any (with dg-option).
+# ??? We're flipping between "flag" and "option" here.
+
+proc dg-runtest { testcases flags default-extra-flags } {
+ global runtests
+
+ foreach testcase $testcases {
+ # If we're only testing specific files and this isn't one of them, skip it.
+ if ![runtest_file_p $runtests $testcase] {
+ continue
+ }
+ verbose "Testing [file tail [file dirname $testcase]]/[file tail $testcase]"
+ dg-test $testcase $flags ${default-extra-flags}
+ }
+}
+
+# dg-test -- runs a new style DejaGnu test
+#
+# Syntax: dg-test [-keep-output] prog tool_flags default_extra_tool_flags
+#
+# PROG is the full path name of the file to pass to the tool (eg: compiler).
+# TOOL_FLAGS is a set of options to always pass.
+# DEFAULT_EXTRA_TOOL_FLAGS are additional options if the testcase has none.
+
+#proc dg-test { prog tool_flags default_extra_tool_flags } {
+proc dg-test { args } {
+ global dg-do-what-default dg-interpreter-batch-mode dg-linenum-format
+ global errorCode errorInfo
+ global tool
+ global srcdir ;# eg: /calvin/dje/devo/gcc/./testsuite/
+ global host_triplet target_triplet
+
+ set keep 0
+ set i 0
+
+ if { [string index [lindex $args 0] 0] == "-" } {
+ for { set i 0 } { $i < [llength $args] } { incr i } {
+ if { [lindex $args $i] == "--" } {
+ incr i
+ break
+ } elseif { [lindex $args $i] == "-keep-output" } {
+ set keep 1
+ } elseif { [string index [lindex $args $i] 0] == "-" } {
+ clone_output "ERROR: dg-test: illegal argument: [lindex $args $i]"
+ return
+ } else {
+ break
+ }
+ }
+ }
+
+ if { $i + 3 != [llength $args] } {
+ clone_output "ERROR: dg-test: missing arguments in call"
+ return
+ }
+ set prog [lindex $args $i]
+ set tool_flags [lindex $args [expr $i + 1]]
+ set default_extra_tool_flags [lindex $args [expr $i + 2]]
+
+ set text "\[- A-Za-z0-9\.\;\"\_\:\'\`\(\)\!\#\=\+\?\&\*]*"
+
+ regsub "^$srcdir/?" $prog "" name
+ # If we couldn't rip $srcdir out of `prog' then just do the best we can.
+ # The point is to reduce the unnecessary noise in the logs. Don't strip
+ # out too much because different testcases with the same name can confuse
+ # `test-tool'.
+ if [string match "/*" $name] {
+ set name "[file tail [file dirname $prog]]/[file tail $prog]"
+ }
+
+ # Process any embedded dg options in the testcase.
+
+ # Use "" for the second element of dg-do-what so we can tell if it's been
+ # explicitly set to "S".
+ set dg-do-what [list ${dg-do-what-default} "" P]
+ set dg-excess-errors-flag 0
+ set dg-messages ""
+ set dg-extra-tool-flags $default_extra_tool_flags
+ set dg-final-code ""
+
+ # `dg-output-text' is a list of two elements: pass/fail and text.
+ # Leave second element off for now (indicates "don't perform test")
+ set dg-output-text "P"
+
+ # Define our own "special function" `unknown' so we catch spelling errors.
+ # But first rename the existing one so we can restore it afterwards.
+ catch {rename dg-save-unknown ""}
+ rename unknown dg-save-unknown
+ proc unknown { args } {
+ return -code error "unknown dg option: $args"
+ }
+
+ set tmp [dg-get-options $prog]
+ foreach op $tmp {
+ verbose "Processing option: $op" 3
+ set status [catch "$op" errmsg]
+ if { $status != 0 } {
+ if { 0 && [info exists errorInfo] } {
+ # This also prints a backtrace which will just confuse
+ # testcase writers, so it's disabled.
+ perror "$name: $errorInfo\n"
+ } else {
+ perror "$name: $errmsg for \"$op\"\n"
+ }
+ # ??? The call to unresolved here is necessary to clear `errcnt'.
+ # What we really need is a proc like perror that doesn't set errcnt.
+ # It should also set exit_status to 1.
+ unresolved "$name: $errmsg for \"$op\""
+ return
+ }
+ }
+
+ # Restore normal error handling.
+ rename unknown ""
+ rename dg-save-unknown unknown
+
+ # If we're not supposed to try this test on this target, we're done.
+ if { [lindex ${dg-do-what} 1] == "N" } {
+ unsupported "$name"
+ verbose "$name not supported on this target, skipping it" 3
+ return
+ }
+
+ # Run the tool and analyze the results.
+ # The result of ${tool}-dg-test is in a bit of flux.
+ # Currently it is the name of the output file (or "" if none).
+ # If we need more than this it will grow into a list of things.
+ # No intention is made (at this point) to preserve upward compatibility
+ # (though at some point we'll have to).
+
+ set results [${tool}-dg-test $prog [lindex ${dg-do-what} 0] "$tool_flags ${dg-extra-tool-flags}"];
+
+ set comp_output [lindex $results 0];
+ set output_file [lindex $results 1];
+
+ #send_user "\nold_dejagnu.exp: comp_output1 = :$comp_output:\n\n"
+ #send_user "\nold_dejagnu.exp: message = :$message:\n\n"
+ #send_user "\nold_dejagnu.exp: message length = [llength $message]\n\n"
+
+ foreach i ${dg-messages} {
+ verbose "Scanning for message: $i" 4
+
+ # Remove all error messages for the line [lindex $i 0]
+ # in the source file. If we find any, success!
+ set line [lindex $i 0]
+ set pattern [lindex $i 2]
+ set comment [lindex $i 3]
+ #send_user "Before:\n$comp_output\n"
+ if [regsub -all "(^|\n)(\[^\n\]+$line\[^\n\]*($pattern)\[^\n\]*\n?)+" $comp_output "\n" comp_output] {
+ set comp_output [string trimleft $comp_output]
+ set ok pass
+ set uhoh fail
+ } else {
+ set ok fail
+ set uhoh pass
+ }
+ #send_user "After:\n$comp_output\n"
+
+ # $line will either be a formatted line number or a number all by
+ # itself. Delete the formatting.
+ scan $line ${dg-linenum-format} line
+ switch [lindex $i 1] {
+ "ERROR" {
+ $ok "$name $comment (test for errors, line $line)"
+ }
+ "XERROR" {
+ x$ok "$name $comment (test for errors, line $line)"
+ }
+ "WARNING" {
+ $ok "$name $comment (test for warnings, line $line)"
+ }
+ "XWARNING" {
+ x$ok "$name $comment (test for warnings, line $line)"
+ }
+ "BOGUS" {
+ $uhoh "$name $comment (test for bogus messages, line $line)"
+ }
+ "XBOGUS" {
+ x$uhoh "$name $comment (test for bogus messages, line $line)"
+ }
+ "BUILD" {
+ $uhoh "$name $comment (test for build failure, line $line)"
+ }
+ "XBUILD" {
+ x$uhoh "$name $comment (test for build failure, line $line)"
+ }
+ "EXEC" { }
+ "XEXEC" { }
+ }
+ #send_user "\nold_dejagnu.exp: comp_output2= :$comp_output:\n\n"
+ }
+ #send_user "\nold_dejagnu.exp: comp_output3 = :$comp_output:\n\n"
+
+ # Remove messages from the tool that we can ignore.
+ #send_user "comp_output: $comp_output\n"
+ set comp_output [prune_warnings $comp_output]
+
+ if { [info proc ${tool}-dg-prune] != "" } {
+ set comp_output [${tool}-dg-prune $target_triplet $comp_output]
+ switch -glob $comp_output {
+ "::untested::*" {
+ regsub "::untested::" $comp_output "" message
+ untested "$name: $message"
+ return
+ }
+ "::unresolved::*" {
+ regsub "::unresolved::" $comp_output "" message
+ unresolved "$name: $message"
+ return
+ }
+ "::unsupported::*" {
+ regsub "::unsupported::" $comp_output "" message
+ unsupported "$name: $message"
+ return
+ }
+ }
+ }
+
+ # See if someone forgot to delete the extra lines.
+ regsub -all "\n+" $comp_output "\n" comp_output
+ regsub "^\n+" $comp_output "" comp_output
+ #send_user "comp_output: $comp_output\n"
+
+ # Don't do this if we're testing an interpreter.
+ # FIXME: why?
+ if { ${dg-interpreter-batch-mode} == 0 } {
+ # Catch excess errors (new bugs or incomplete testcases).
+ if ${dg-excess-errors-flag} {
+ setup_xfail "*-*-*"
+ }
+ if ![string match "" $comp_output] {
+ fail "$name (test for excess errors)"
+ send_log "Excess errors:\n$comp_output\n"
+ } else {
+ pass "$name (test for excess errors)"
+ }
+ }
+
+ # Run the executable image if asked to do so.
+ # FIXME: This is the only place where we assume a standard meaning to
+ # the `keyword' argument of dg-do. This could be cleaned up.
+ if { [lindex ${dg-do-what} 0] == "run" } {
+ if ![file exists $output_file] {
+ warning "$name compilation failed to produce executable"
+ } else {
+ set status -1
+ set result [${tool}_load $output_file]
+ set status [lindex $result 0];
+ set output [lindex $result 1];
+ #send_user "After exec, status: $status\n"
+ if { [lindex ${dg-do-what} 2] == "F" } {
+ setup_xfail "*-*-*"
+ }
+ if { "$status" == "pass" } {
+ pass "$name execution test"
+ verbose "Exec succeeded." 3
+ if { [llength ${dg-output-text}] > 1 } {
+ #send_user "${dg-output-text}\n"
+ if { [lindex ${dg-output-text} 0] == "F" } {
+ setup_xfail "*-*-*"
+ }
+ set texttmp [lindex ${dg-output-text} 1]
+ if { ![regexp $texttmp ${output}] } {
+ fail "$name output pattern test, is ${output}, should match $texttmp"
+ verbose "Failed test for output pattern $texttmp" 3
+ } else {
+ pass "$name output pattern test, $texttmp"
+ verbose "Passed test for output pattern $texttmp" 3
+ }
+ unset texttmp
+ }
+ } elseif { "$status" == "fail" } {
+ # It would be nice to get some info out of errorCode.
+ if [info exists errorCode] {
+ verbose "Exec failed, errorCode: $errorCode" 3
+ } else {
+ verbose "Exec failed, errorCode not defined!" 3
+ }
+ fail "$name execution test"
+ } else {
+ $status "$name execution test"
+ }
+ }
+ }
+
+ # Are there any further tests to perform?
+ # Note that if the program has special run-time requirements, running
+ # of the program can be delayed until here. Ditto for other situations.
+ # It would be a bit cumbersome though.
+
+ if ![string match ${dg-final-code} ""] {
+ regsub -all "\\\\(\[{}\])" ${dg-final-code} "\\1" dg-final-code
+ # Note that the use of `args' here makes this a varargs proc.
+ proc dg-final-proc { args } ${dg-final-code}
+ verbose "Running dg-final tests." 3
+ verbose "dg-final-proc:\n[info body dg-final-proc]" 4
+ if [catch "dg-final-proc $prog" errmsg] {
+ perror "$name: error executing dg-final: $errmsg"
+ # ??? The call to unresolved here is necessary to clear `errcnt'.
+ # What we really need is a proc like perror that doesn't set errcnt.
+ # It should also set exit_status to 1.
+ unresolved "$name: error executing dg-final: $errmsg"
+ }
+ }
+
+ # Do some final clean up.
+ # When testing an interpreter, we don't compile something and leave an
+ # output file.
+ if { ! ${keep} && ${dg-interpreter-batch-mode} == 0 } {
+ catch "exec rm -f $output_file"
+ }
+}
+
+#
+# Do any necessary cleanups
+#
+# This is called at the end to undo anything dg-init did (that needs undoing).
+#
+proc dg-finish { } {
+ # Reset this in case caller wonders whether s/he should.
+ global prms_id
+ set prms_id 0
+
+ # The framework doesn't like to see any error remnants, so remove them.
+ global errorInfo
+ if [info exists errorInfo] {
+ unset errorInfo
+ }
+
+ # If the tool has a "finish" routine, call it.
+ # There may be a bit of duplication (eg: resetting prms_id), leave it.
+ # Let's keep these procs robust.
+ global tool
+ if ![string match "" [info procs ${tool}_finish]] {
+ ${tool}_finish
+ }
+}
diff --git a/dejagnu/lib/framework.exp b/dejagnu/lib/framework.exp
new file mode 100644
index 00000000000..51758414257
--- /dev/null
+++ b/dejagnu/lib/framework.exp
@@ -0,0 +1,887 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+# These variables are local to this file.
+# This or more warnings and a test fails.
+set warning_threshold 3
+# This or more errors and a test fails.
+set perror_threshold 1
+
+proc mail_file { file to subject } {
+ if [file readable $file] {
+ catch "exec mail -s \"$subject\" $to < $file"
+ }
+}
+
+#
+# Open the output logs
+#
+proc open_logs { } {
+ global outdir
+ global tool
+ global sum_file
+
+ if { ${tool} == "" } {
+ set tool testrun
+ }
+ catch "exec rm -f $outdir/$tool.sum"
+ set sum_file [open "$outdir/$tool.sum" w]
+ catch "exec rm -f $outdir/$tool.log"
+ log_file -a "$outdir/$tool.log"
+ verbose "Opening log files in $outdir"
+ if { ${tool} == "testrun" } {
+ set tool ""
+ }
+}
+
+
+#
+# Close the output logs
+#
+proc close_logs { } {
+ global sum_file
+
+ catch "close $sum_file"
+}
+
+#
+# Check build host triplet for pattern
+#
+# With no arguments it returns the triplet string.
+#
+proc isbuild { pattern } {
+ global build_triplet
+ global host_triplet
+
+ if ![info exists build_triplet] {
+ set build_triplet ${host_triplet}
+ }
+ if [string match "" $pattern] {
+ return $build_triplet
+ }
+ verbose "Checking pattern \"$pattern\" with $build_triplet" 2
+
+ if [string match "$pattern" $build_triplet] {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+#
+# Is $board remote? Return a non-zero value if so.
+#
+proc is_remote { board } {
+ global host_board;
+ global target_list;
+
+ verbose "calling is_remote $board" 3;
+ # Remove any target variant specifications from the name.
+ set board [lindex [split $board "/"] 0];
+
+ # Map the host or build back into their short form.
+ if { [board_info build name] == $board } {
+ set board "build";
+ } elseif { [board_info host name] == $board } {
+ set board "host";
+ }
+
+ # We're on the "build". The check for the empty string is just for
+ # paranoia's sake--we shouldn't ever get one. "unix" is a magic
+ # string that should really go away someday.
+ if { $board == "build" || $board == "unix" || $board == "" } {
+ verbose "board is $board, not remote" 3;
+ return 0;
+ }
+
+ if { $board == "host" } {
+ if { [info exists host_board] && $host_board != "" } {
+ verbose "board is $board, is remote" 3;
+ return 1;
+ } else {
+ verbose "board is $board, host is local" 3;
+ return 0;
+ }
+ }
+
+ if { $board == "target" } {
+ global current_target_name
+
+ if [info exists current_target_name] {
+ # This shouldn't happen, but we'll be paranoid anyway.
+ if { $current_target_name != "target" } {
+ return [is_remote $current_target_name];
+ }
+ }
+ return 0;
+ }
+ if [board_info $board exists isremote] {
+ verbose "board is $board, isremote is [board_info $board isremote]" 3;
+ return [board_info $board isremote];
+ }
+ return 1;
+}
+#
+# If this is a canadian (3 way) cross. This means the tools are
+# being built with a cross compiler for another host.
+#
+proc is3way {} {
+ global host_triplet
+ global build_triplet
+
+ if ![info exists build_triplet] {
+ set build_triplet ${host_triplet}
+ }
+ verbose "Checking $host_triplet against $build_triplet" 2
+ if { "$build_triplet" == "$host_triplet" } {
+ return 0
+ }
+ return 1
+}
+
+#
+# Check host triplet for pattern
+#
+# With no arguments it returns the triplet string.
+#
+proc ishost { pattern } {
+ global host_triplet
+
+ if [string match "" $pattern] {
+ return $host_triplet
+ }
+ verbose "Checking pattern \"$pattern\" with $host_triplet" 2
+
+ if [string match "$pattern" $host_triplet] {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+#
+# Check target triplet for pattern
+#
+# With no arguments it returns the triplet string.
+# Returns 1 if the target looked for, or 0 if not.
+#
+proc istarget { args } {
+ global target_triplet
+
+ # if no arg, return the config string
+ if [string match "" $args] {
+ if [info exists target_triplet] {
+ return $target_triplet
+ } else {
+ perror "No target configuration names found."
+ }
+ }
+
+ set triplet [lindex $args 0]
+
+ # now check against the cannonical name
+ if [info exists target_triplet] {
+ verbose "Checking \"$triplet\" against \"$target_triplet\"" 2
+ if [string match $triplet $target_triplet] {
+ return 1
+ }
+ }
+
+ # nope, no match
+ return 0
+}
+
+#
+# Check to see if we're running the tests in a native environment
+#
+# Returns 1 if running native, 0 if on a target.
+#
+proc isnative { } {
+ global target_triplet
+ global build_triplet
+
+ if [string match $build_triplet $target_triplet] {
+ return 1
+ }
+ return 0
+}
+
+#
+# unknown -- called by expect if a proc is called that doesn't exist
+#
+proc unknown { args } {
+ global errorCode
+ global errorInfo
+ global exit_status
+
+ clone_output "ERROR: (DejaGnu) proc \"$args\" does not exist."
+ if [info exists errorCode] {
+ send_error "The error code is $errorCode\n"
+ }
+ if [info exists errorInfo] {
+ send_error "The info on the error is:\n$errorInfo\n"
+ }
+
+ set exit_status 1;
+ log_and_exit;
+}
+
+#
+# Print output to stdout (or stderr) and to log file
+#
+# If the --all flag (-a) option was used then all messages go the the screen.
+# Without this, all messages that start with a keyword are written only to the
+# detail log file. All messages that go to the screen will also appear in the
+# detail log. This should only be used by the framework itself using pass,
+# fail, xpass, xfail, warning, perror, note, untested, unresolved, or
+# unsupported procedures.
+#
+proc clone_output { message } {
+ global sum_file
+ global all_flag
+
+ if { $sum_file != "" } {
+ puts $sum_file "$message"
+ }
+
+ regsub "^\[ \t\]*(\[^ \t\]+).*$" "$message" "\\1" firstword;
+ case "$firstword" in {
+ {"PASS:" "XFAIL:" "UNRESOLVED:" "UNSUPPORTED:" "UNTESTED:"} {
+ if $all_flag {
+ send_user "$message\n"
+ return "$message"
+ } else {
+ send_log "$message\n"
+ }
+ }
+ {"ERROR:" "WARNING:" "NOTE:"} {
+ send_error "$message\n"
+ return "$message"
+ }
+ default {
+ send_user "$message\n"
+ return "$message"
+ }
+ }
+}
+
+#
+# Reset a few counters.
+#
+proc reset_vars {} {
+ global test_names test_counts;
+ global warncnt errcnt;
+
+ # other miscellaneous variables
+ global prms_id
+ global bug_id
+
+ # reset them all
+ set prms_id 0;
+ set bug_id 0;
+ set warncnt 0;
+ set errcnt 0;
+ foreach x $test_names {
+ set test_counts($x,count) 0;
+ }
+
+ # Variables local to this file.
+ global warning_threshold perror_threshold
+ set warning_threshold 3
+ set perror_threshold 1
+}
+
+proc log_and_exit {} {
+ global exit_status;
+ global tool mail_logs outdir mailing_list;
+
+ log_summary total;
+ # extract version number
+ if {[info procs ${tool}_version] != ""} {
+ if {[catch "${tool}_version" output]} {
+ warning "${tool}_version failed:\n$output"
+ }
+ }
+ close_logs
+ cleanup
+ verbose -log "runtest completed at [timestamp -format %c]"
+ if $mail_logs {
+ mail_file $outdir/$tool.sum $mailing_list "Dejagnu Summary Log"
+ }
+ remote_close host
+ remote_close target
+ exit $exit_status
+}
+#
+# Print summary of all pass/fail counts
+#
+proc log_summary { args } {
+ global tool
+ global sum_file
+ global exit_status
+ global mail_logs
+ global outdir
+ global mailing_list
+ global current_target_name
+ global test_counts;
+ global testcnt;
+
+ if { [llength $args] == 0 } {
+ set which "count";
+ } else {
+ set which [lindex $args 0];
+ }
+
+ if { [llength $args] == 0 } {
+ clone_output "\n\t\t=== $tool Summary for $current_target_name ===\n"
+ } else {
+ clone_output "\n\t\t=== $tool Summary ===\n"
+ }
+
+ # If the tool set `testcnt', it wants us to do a sanity check on the
+ # total count, so compare the reported number of testcases with the
+ # expected number. Maintaining an accurate count in `testcnt' isn't easy
+ # so it's not clear how often this will be used.
+ if [info exists testcnt] {
+ if { $testcnt > 0 } {
+ set totlcnt 0;
+ # total all the testcases reported
+ foreach x { FAIL PASS XFAIL XPASS UNTESTED UNRESOLVED UNSUPPORTED } {
+ incr totlcnt test_counts($x,$which);
+ }
+ set testcnt test_counts(total,$which);
+
+ if { $testcnt>$totlcnt || $testcnt<$totlcnt } {
+ if { $testcnt > $totlcnt } {
+ set mismatch "unreported [expr $testcnt-$totlcnt]"
+ }
+ if { $testcnt < $totlcnt } {
+ set mismatch "misreported [expr $totlcnt-$testcnt]"
+ }
+ } else {
+ verbose "# of testcases run $testcnt"
+ }
+
+ if [info exists mismatch] {
+ clone_output "### ERROR: totals do not equal number of testcases run"
+ clone_output "### ERROR: # of testcases expected $testcnt"
+ clone_output "### ERROR: # of testcases reported $totlcnt"
+ clone_output "### ERROR: # of testcases $mismatch\n"
+ }
+ }
+ }
+ foreach x { PASS FAIL XPASS XFAIL UNRESOLVED UNTESTED UNSUPPORTED } {
+ set val $test_counts($x,$which);
+ if { $val > 0 } {
+ set mess "# of $test_counts($x,name)";
+ if { [string length $mess] < 24 } {
+ append mess "\t";
+ }
+ clone_output "$mess\t$val";
+ }
+ }
+}
+
+#
+# Close all open files, remove temp file and core files
+#
+proc cleanup {} {
+ global sum_file
+ global exit_status
+ global done_list
+ global subdir
+
+ #catch "exec rm -f [glob xgdb core *.x *.o *_soc a.out]"
+ #catch "exec rm -f [glob -nocomplain $subdir/*.o $subdir/*.x $subdir/*_soc]"
+}
+
+#
+# Setup a flag to control whether a failure is expected or not
+#
+# Multiple target triplet patterns can be specified for targets
+# for which the test fails. A decimal number can be specified,
+# which is the PRMS number.
+#
+proc setup_xfail { args } {
+ global xfail_flag
+ global xfail_prms
+
+ set xfail_prms 0
+ set argc [ llength $args ]
+ for { set i 0 } { $i < $argc } { incr i } {
+ set sub_arg [ lindex $args $i ]
+ # is a prms number. we assume this is a number with no characters
+ if [regexp "^\[0-9\]+$" $sub_arg] {
+ set xfail_prms $sub_arg
+ continue
+ }
+ if [istarget $sub_arg] {
+ set xfail_flag 1
+ continue
+ }
+ }
+}
+
+
+# check to see if a conditional xfail is triggered
+# message {targets} {include} {exclude}
+#
+#
+proc check_conditional_xfail { args } {
+ global compiler_flags
+
+ set all_args [lindex $args 0]
+
+ set message [lindex $all_args 0]
+
+ set target_list [lindex $all_args 1]
+ verbose "Limited to targets: $target_list" 3
+
+ # get the list of flags to look for
+ set includes [lindex $all_args 2]
+ verbose "Will search for options $includes" 3
+
+ # get the list of flags to exclude
+ if { [llength $all_args] > 3 } {
+ set excludes [lindex $all_args 3]
+ verbose "Will exclude for options $excludes" 3
+ } else {
+ set excludes ""
+ }
+
+ # loop through all the targets, checking the options for each one
+ verbose "Compiler flags are: $compiler_flags" 2
+
+ set incl_hit 0
+ set excl_hit 0
+ foreach targ $target_list {
+ if [istarget $targ] {
+ # look through the compiler options for flags we want to see
+ # this is really messy cause each set of options to look for
+ # may also be a list. We also want to find each element of the
+ # list, regardless of order to make sure they're found.
+ # So we look for lists in side of lists, and make sure all
+ # the elements match before we decide this is legit.
+ for { set i 0 } { $i < [llength $includes] } { incr i } {
+ set incl_hit 0
+ set opt [lindex $includes $i]
+ verbose "Looking for $opt to include in the compiler flags" 2
+ foreach j "$opt" {
+ if [string match "* $j *" $compiler_flags] {
+ verbose "Found $j to include in the compiler flags" 2
+ incr incl_hit
+ }
+ }
+ # if the number of hits we get is the same as the number of
+ # specified options, then we got a match
+ if {$incl_hit == [llength $opt]} {
+ break
+ } else {
+ set incl_hit 0
+ }
+ }
+ # look through the compiler options for flags we don't
+ # want to see
+ for { set i 0 } { $i < [llength $excludes] } { incr i } {
+ set excl_hit 0
+ set opt [lindex $excludes $i]
+ verbose "Looking for $opt to exclude in the compiler flags" 2
+ foreach j "$opt" {
+ if [string match "* $j *" $compiler_flags] {
+ verbose "Found $j to exclude in the compiler flags" 2
+ incr excl_hit
+ }
+ }
+ # if the number of hits we get is the same as the number of
+ # specified options, then we got a match
+ if {$excl_hit == [llength $opt]} {
+ break
+ } else {
+ set excl_hit 0
+ }
+ }
+
+ # if we got a match for what to include, but didn't find any reasons
+ # to exclude this, then we got a match! So return one to turn this into
+ # an expected failure.
+ if {$incl_hit && ! $excl_hit } {
+ verbose "This is a conditional match" 2
+ return 1
+ } else {
+ verbose "This is not a conditional match" 2
+ return 0
+ }
+ }
+ }
+ return 0
+}
+
+#
+# Clear the xfail flag for a particular target
+#
+proc clear_xfail { args } {
+ global xfail_flag
+ global xfail_prms
+
+ set argc [ llength $args ]
+ for { set i 0 } { $i < $argc } { incr i } {
+ set sub_arg [ lindex $args $i ]
+ case $sub_arg in {
+ "*-*-*" { # is a configuration triplet
+ if [istarget $sub_arg] {
+ set xfail_flag 0
+ set xfail_prms 0
+ }
+ continue
+ }
+ }
+ }
+}
+
+#
+# Record that a test has passed or failed (perhaps unexpectedly)
+#
+# This is an internal procedure, only used in this file.
+#
+proc record_test { type message args } {
+ global exit_status
+ global prms_id bug_id
+ global xfail_flag xfail_prms
+ global errcnt warncnt
+ global warning_threshold perror_threshold
+ global pf_prefix
+
+ if { [llength $args] > 0 } {
+ set count [lindex $args 0];
+ } else {
+ set count 1;
+ }
+ if [info exists pf_prefix] {
+ set message [concat $pf_prefix " " $message];
+ }
+
+ # If we have too many warnings or errors,
+ # the output of the test can't be considered correct.
+ if { $warning_threshold > 0 && $warncnt >= $warning_threshold
+ || $perror_threshold > 0 && $errcnt >= $perror_threshold } {
+ verbose "Error/Warning threshold exceeded: \
+ $errcnt $warncnt (max. $perror_threshold $warning_threshold)"
+ set type UNRESOLVED
+ }
+
+ incr_count $type;
+
+ switch $type {
+ PASS {
+ if $prms_id {
+ set message [concat $message "\t(PRMS $prms_id)"]
+ }
+ }
+ FAIL {
+ set exit_status 1
+ if $prms_id {
+ set message [concat $message "\t(PRMS $prms_id)"]
+ }
+ }
+ XPASS {
+ set exit_status 1
+ if { $xfail_prms != 0 } {
+ set message [concat $message "\t(PRMS $xfail_prms)"]
+ }
+ }
+ XFAIL {
+ if { $xfail_prms != 0 } {
+ set message [concat $message "\t(PRMS $xfail_prms)"]
+ }
+ }
+ UNTESTED {
+ # The only reason we look at the xfail stuff is to pick up
+ # `xfail_prms'.
+ if { $xfail_flag && $xfail_prms != 0 } {
+ set message [concat $message "\t(PRMS $xfail_prms)"]
+ } elseif $prms_id {
+ set message [concat $message "\t(PRMS $prms_id)"]
+ }
+ }
+ UNRESOLVED {
+ set exit_status 1
+ # The only reason we look at the xfail stuff is to pick up
+ # `xfail_prms'.
+ if { $xfail_flag && $xfail_prms != 0 } {
+ set message [concat $message "\t(PRMS $xfail_prms)"]
+ } elseif $prms_id {
+ set message [concat $message "\t(PRMS $prms_id)"]
+ }
+ }
+ UNSUPPORTED {
+ # The only reason we look at the xfail stuff is to pick up
+ # `xfail_prms'.
+ if { $xfail_flag && $xfail_prms != 0 } {
+ set message [concat $message "\t(PRMS $xfail_prms)"]
+ } elseif $prms_id {
+ set message [concat $message "\t(PRMS $prms_id)"]
+ }
+ }
+ default {
+ perror "record_test called with bad type `$type'"
+ set errcnt 0
+ return
+ }
+ }
+
+ if $bug_id {
+ set message [concat $message "\t(BUG $bug_id)"]
+ }
+
+ global multipass_name
+ if { $multipass_name != "" } {
+ clone_output "$type: $multipass_name: $message"
+ } else {
+ clone_output "$type: $message"
+ }
+
+ # Reset these so they're ready for the next test case. We don't reset
+ # prms_id or bug_id here. There may be multiple tests for them. Instead
+ # they are reset in the main loop after each test. It is also the
+ # testsuite driver's responsibility to reset them after each testcase.
+ set warncnt 0
+ set errcnt 0
+ set xfail_flag 0
+ set xfail_prms 0
+}
+
+#
+# Record that a test has passed
+#
+proc pass { message } {
+ global xfail_flag
+
+ # if we have a conditional xfail setup, then see if our compiler flags match
+ if [uplevel {info exists compiler_conditional_xfail_data}] {
+ if [uplevel {check_conditional_xfail $compiler_conditional_xfail_data}] {
+ set xfail_flag 1
+ }
+ uplevel {unset compiler_conditional_xfail_data}
+ }
+
+ if $xfail_flag {
+ record_test XPASS $message
+ } else {
+ record_test PASS $message
+ }
+}
+
+#
+# Record that a test has failed
+#
+proc fail { message } {
+ global xfail_flag
+
+ # if we have a conditional xfail setup, then see if our compiler flags match
+ if [uplevel {info exists compiler_conditional_xfail_data}] {
+ if [uplevel {check_conditional_xfail $compiler_conditional_xfail_data}] {
+ set xfail_flag 1
+ }
+ uplevel {unset compiler_conditional_xfail_data}
+ }
+
+ if $xfail_flag {
+ record_test XFAIL $message
+ } else {
+ record_test FAIL $message
+ }
+}
+
+#
+# Record that a test has passed unexpectedly
+#
+proc xpass { message } {
+ record_test XPASS $message
+}
+
+#
+# Record that a test has failed unexpectedly
+#
+proc xfail { message } {
+ record_test XFAIL $message
+}
+
+#
+# Set warning threshold
+#
+proc set_warning_threshold { threshold } {
+ set warning_threshold $threshold
+}
+
+#
+# Get warning threshold
+#
+proc get_warning_threshold { } {
+ return $warning_threshold
+}
+
+#
+# Prints warning messages
+# These are warnings from the framework, not from the tools being tested.
+# It takes a string, and an optional number and returns nothing.
+#
+proc warning { args } {
+ global warncnt
+
+ if { [llength $args] > 1 } {
+ set warncnt [lindex $args 1]
+ } else {
+ incr warncnt
+ }
+ set message [lindex $args 0]
+
+ clone_output "WARNING: $message"
+
+ global errorInfo
+ if [info exists errorInfo] {
+ unset errorInfo
+ }
+}
+
+#
+# Prints error messages
+# These are errors from the framework, not from the tools being tested.
+# It takes a string, and an optional number and returns nothing.
+#
+proc perror { args } {
+ global errcnt
+
+ if { [llength $args] > 1 } {
+ set errcnt [lindex $args 1]
+ } else {
+ incr errcnt
+ }
+ set message [lindex $args 0]
+
+ clone_output "ERROR: $message"
+
+ global errorInfo
+ if [info exists errorInfo] {
+ unset errorInfo
+ }
+}
+
+#
+# Prints informational messages
+#
+# These are messages from the framework, not from the tools being tested.
+# This means that it is currently illegal to call this proc outside
+# of dejagnu proper.
+#
+proc note { message } {
+ clone_output "NOTE: $message"
+
+ # ??? It's not clear whether we should do this. Let's not, and only do
+ # so if we find a real need for it.
+ #global errorInfo
+ #if [info exists errorInfo] {
+ # unset errorInfo
+ #}
+}
+
+#
+# untested -- mark the test case as untested
+#
+proc untested { message } {
+ record_test UNTESTED $message
+}
+
+#
+# Mark the test case as unresolved
+#
+proc unresolved { message } {
+ record_test UNRESOLVED $message
+}
+
+#
+# Mark the test case as unsupported
+#
+# Usually this is used for a test that is missing OS support.
+#
+proc unsupported { message } {
+ record_test UNSUPPORTED $message
+}
+
+#
+# Set up the values in the test_counts array (name and initial totals).
+#
+proc init_testcounts { } {
+ global test_counts test_names;
+ set test_counts(TOTAL,name) "testcases run"
+ set test_counts(PASS,name) "expected passes"
+ set test_counts(FAIL,name) "unexpected failures"
+ set test_counts(XFAIL,name) "expected failures"
+ set test_counts(XPASS,name) "unexpected successes"
+ set test_counts(WARNING,name) "warnings"
+ set test_counts(ERROR,name) "errors"
+ set test_counts(UNSUPPORTED,name) "unsupported tests"
+ set test_counts(UNRESOLVED,name) "unresolved testcases"
+ set test_counts(UNTESTED,name) "untested testcases"
+ set j "";
+
+ foreach i [lsort [array names test_counts]] {
+ regsub ",.*$" "$i" "" i;
+ if { $i == $j } {
+ continue;
+ }
+ set test_counts($i,total) 0;
+ lappend test_names $i;
+ set j $i;
+ }
+}
+
+#
+# Increment NAME in the test_counts array; the amount to increment can be
+# is optional (defaults to 1).
+#
+proc incr_count { name args } {
+ global test_counts;
+
+ if { [llength $args] == 0 } {
+ set count 1;
+ } else {
+ set count [lindex $args 0];
+ }
+ if [info exists test_counts($name,count)] {
+ incr test_counts($name,count) $count;
+ incr test_counts($name,total) $count;
+ } else {
+ perror "$name doesn't exist in incr_count"
+ }
+}
+
+
+#
+# Create an exp_continue proc if it doesn't exist
+#
+# For compatablity with old versions.
+#
+global argv0
+if ![info exists argv0] {
+ proc exp_continue { } {
+ continue -expect
+ }
+}
diff --git a/dejagnu/lib/ftp.exp b/dejagnu/lib/ftp.exp
new file mode 100644
index 00000000000..641f1122a01
--- /dev/null
+++ b/dejagnu/lib/ftp.exp
@@ -0,0 +1,246 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+#
+# Support downloading files using ftp.
+#
+
+#
+# Open a connection to HOST.
+#
+proc ftp_open { host } {
+ set prompt "ftp>"
+ global board_info
+
+ if [board_info $host exists name] {
+ set host [board_info $host name];
+ }
+
+ if [board_info $host exists ftp_fileid] {
+ return [board_info $host ftp_fileid];
+ }
+
+ if [board_info $host exists hostname] {
+ set remotehost [board_info $host hostname];
+ } else {
+ set remotehost $host;
+ }
+
+ # LoseQVT tends to get stuck sometimes; we'll loop around a few million
+ # times when it gets a "connection refused".
+ set spawn_id -1;
+ set count 3;
+ while { $spawn_id < 0 && $count >= 0 } {
+ spawn ftp -n $remotehost;
+ expect {
+ -i $spawn_id -re ".*220.*$prompt" { }
+ -i $spawn_id -re ".*Connection refused.*$prompt" {
+ sleep 2;
+ send "open $remotehost\n";
+ exp_continue
+ }
+ -i $spawn_id default {
+ close -i $spawn_id;
+ wait -i $spawn_id;
+ set spawn_id -1;
+ }
+ }
+ incr count -1;
+ }
+ if { $spawn_id < 0 } {
+ return -1;
+ }
+ set board_info($host,ftp_fileid) $spawn_id;
+ if [board_info $host exists ftp_username] {
+ if [board_info $host exists ftp_password] {
+ set command "user [board_info $host ftp_username] [board_info $host ftp_password]\n";
+ } else {
+ set command "user [board_info $host ftp_username]\n";
+ }
+ send "$command"
+ expect {
+ -i $spawn_id -re ".*230.*$prompt" { }
+ -i $spawn_id default {
+ close -i $spawn_id;
+ wait -i $spawn_id;
+ return -1;
+ }
+ }
+ }
+ set timeout 15
+ send -i $spawn_id "binary\n"
+ expect {
+ -i $spawn_id -re "200.*$prompt" { }
+ -i $spawn_id timeout {
+ close -i $spawn_id;
+ wait -i $spawn_id;
+ return -1
+ }
+ }
+ if [board_info $host exists ftp_directory] {
+ send "cd [board_info $host ftp_directory]\n";
+ expect {
+ -i $spawn_id -re "250.*$prompt" { }
+ -i $spawn_id default {
+ close -i $spawn_id;
+ wait -i $spawn_id;
+ return -1;
+ }
+ }
+ }
+
+ if [board_info $host exists ftp_no_passive] {
+ send "passive\n";
+ expect {
+ -i $spawn_id -re "Passive mode off.*$prompt" { }
+ -i $spawn_id -re "Passive mode on.*$prompt" {
+ send "passive\n";
+ exp_continue;
+ }
+ -i $spawn_id -re ".*$prompt" { }
+ }
+ }
+
+ set board_info($host,ftp_fileid) $spawn_id;
+ return $spawn_id;
+}
+
+#
+# Grab REMOTEFILE from HOST and store it as LOCALFILE.
+#
+proc ftp_upload { host remotefile localfile } {
+ set prompt "ftp>"
+
+ verbose "ftping $remotefile from $host to $localfile"
+ set timeout 15
+ set spawn_id [ftp_open $host];
+ if { $spawn_id < 0 } {
+ return "";
+ }
+ set loop 1;
+
+ while { $loop } {
+ send -i $spawn_id "get $remotefile $localfile\n";
+ expect {
+ -i $spawn_id -re ".*Too many open files.*$prompt" {
+ ftp_close $host;
+ }
+ -i $spawn_id -re ".*No such file or directory.*$prompt" {
+ set loop 0;
+ set remotefile "";
+ }
+ -i $spawn_id -re "(^|\[\r\n\])226.*$prompt" { set loop 0; }
+ -i $spawn_id -re "(^|\[\r\n\])\[0-9\]\[0-9\]\[0-9\].*$prompt" {
+ set loop 0;
+ set remotefile "";
+ }
+ -i $spawn_id default {
+ ftp_close $host;
+ }
+ }
+ if { $loop } {
+ set spawn_id [ftp_open $host];
+ if { $spawn_id < 0 } {
+ return "";
+ }
+ }
+ }
+ return $localfile;
+}
+
+#
+# Download LOCALFILE to HOST as REMOTEFILE.
+#
+proc ftp_download { host localfile remotefile } {
+ set prompt "ftp>"
+
+ verbose "putting $localfile $remotefile"
+
+ if [board_info $host exists hostname] {
+ set remotehost [board_info $host hostname];
+ } else {
+ set remotehost $host;
+ }
+
+ set spawn_id [ftp_open $host];
+ if { $spawn_id < 0 } {
+ return "";
+ }
+ set loop 1;
+
+ while { $loop } {
+ send -i $spawn_id "put $localfile $remotefile\n"
+ expect {
+ -i $spawn_id -re ".*Too many open files.*$prompt" {
+ ftp_close $host;
+ }
+ -i $spawn_id -re ".*No such file or directory.*$prompt" {
+ set loop 0;
+ set remotefile "";
+ }
+ -re "(^|\[\r\n\])150.*connection for (.*) \[(\]\[0-9.,\]+\\)\[\r\n\]" {
+ set remotefile $expect_out(2,string);
+ exp_continue;
+ }
+ -i $spawn_id -re "(^|\[\r\n\])226.*$prompt" {
+ set loop 0;
+ }
+ -i $spawn_id -re "Timeout.*$prompt" {
+ ftp_close $host;
+ }
+ -i $spawn_id -re "(^|\[\r\n\])\[0-9\]\[0-9\]\[0-9\].*$prompt" {
+ set loop 0;
+ set remotefile "";
+ }
+ -i $spawn_id default {
+ ftp_close $host;
+ }
+ }
+ if { $loop } {
+ set spawn_id [ftp_open $host];
+ if { $spawn_id < 0 } {
+ return "";
+ }
+ }
+ }
+ return $remotefile;
+}
+
+#
+# Close the connection.
+#
+proc ftp_close { host } {
+ global board_info
+
+ if [board_info $host exists name] {
+ set host [board_info $host name];
+ }
+
+ if ![board_info $host exists ftp_fileid] {
+ return "";
+ }
+
+ set spawn_id [board_info $host ftp_fileid];
+ unset board_info($host,ftp_fileid);
+
+ send -i $spawn_id "quit\n"
+ close -i $spawn_id
+ wait -i $spawn_id;
+ return "";
+}
diff --git a/dejagnu/lib/kermit.exp b/dejagnu/lib/kermit.exp
new file mode 100644
index 00000000000..6e1ac37777f
--- /dev/null
+++ b/dejagnu/lib/kermit.exp
@@ -0,0 +1,180 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+#
+# Connect to DEST using kermit. Note that we're just using kermit as a
+# simple serial or network connect program; we don't actually use Kermit
+# protocol to do downloads.
+# returns -1 if it failed, otherwise it returns
+# the spawn_id.
+#
+proc kermit_open { dest args } {
+ global spawn_id
+ global board_info
+
+ if [board_info $dest exists name] {
+ set dest [board_info $dest name];
+ }
+ if [board_info ${dest} exists serial] {
+ set port [board_info ${dest} serial];
+ set device "-l [board_info ${dest} serial]"
+ if [board_info ${dest} exists baud] {
+ append device " -b [board_info ${dest} baud]"
+ }
+ } else {
+ set port [board_info ${dest} netport];
+ set device "-j [board_info ${dest} netport]";
+ }
+
+ set tries 0
+ set result -1
+ verbose "kermit $device"
+ eval spawn kermit $device
+ if { $spawn_id < 0 } {
+ perror "invalid spawn id from kermit"
+ return -1
+ }
+
+ expect {
+ -re ".*ermit.*>.*$" {
+ send "c\n"
+ expect {
+ -re "Connecting to.*$port.*Type the escape character followed by C to.*options.*\[\r\n\]$" {
+ verbose "Got prompt\n"
+ set result 0
+ incr tries
+ }
+ timeout {
+ warning "Never got prompt from Kermit."
+ set result -1
+ incr tries
+ if { $tries <= 2 } {
+ exp_continue
+ }
+ }
+ }
+ }
+ -re "Connection Closed.*$" {
+ perror "Never connected."
+ set result -1
+ incr tries
+ if { $tries <= 2 } {
+ exp_continue
+ }
+ }
+ timeout {
+ warning "Timed out trying to connect."
+ set result -1
+ incr tries
+ if { $tries<=2 } {
+ exp_continue
+ }
+ }
+ }
+
+ if { $result < 0 } {
+ perror "Couldn't connect after $tries tries."
+ if [info exists board_info($dest,fileid)] {
+ unset board_info($dest,fileid);
+ }
+ return -1
+ } else {
+ verbose "Kermit connection established with spawn_id $spawn_id."
+ set board_info($dest,fileid) $spawn_id
+ kermit_command $dest "set file type binary" "set transfer display none"
+ if [board_info $dest exists transmit_pause] {
+ kermit_command $dest "set transmit pause [board_info $dest transmit_pause]"
+ }
+ return $spawn_id
+ }
+}
+
+#
+# Send a list of commands to the Kermit session connected to DEST.
+#
+proc kermit_command { dest args } {
+ if [board_info $dest exists name] {
+ set dest [board_info $dest name];
+ }
+ set shell_id [board_info $dest fileid];
+ # Sometimes we have to send multiple ^\c sequences. Don't know
+ # why.
+ set timeout 2;
+ for { set i 1; } {$i<=5} {incr i} {
+ send -i $shell_id "c";
+ expect {
+ -i $shell_id -re ".*Back at.*ermit.*>.*$" { set i 10;}
+ -i $shell_id timeout {
+ if { $i > 2 } {
+ warning "Unable to get prompt from kermit.";
+ }
+ }
+ }
+ }
+ foreach command $args {
+ set timeout 120
+ send -i $shell_id "${command}\r";
+ expect {
+ -i $shell_id -re ".*ermit.*>.*$" { }
+ -i $shell_id timeout {
+ perror "Response failed from kermit.";
+ return -1;
+ }
+ }
+ }
+ send -i $shell_id "c\r";
+ expect {
+ -i $shell_id -re ".*other options.\[\r\n\]+" { }
+ -i $shell_id timeout {
+ perror "Unable to resume kermit connection.";
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+#
+# Send STRING to DEST.
+#
+proc kermit_send { dest string args } {
+ if [board_info $dest exists transmit_pause] {
+ set f [open "/tmp/fff" "w"];
+ puts -nonewline $f "$string";
+ close $f;
+ set result [remote_transmit $dest /tmp/fff];
+ remote_file build delete "/tmp/fff";
+ return "$result";
+ } else {
+ return [standard_send $dest $string];
+ }
+}
+
+#
+# Transmit FILE directly to DEST as raw data. No translation is
+# performed.
+#
+proc kermit_transmit { dest file args } {
+ if [board_info $dest exists transmit_pause] {
+ kermit_command $dest "transmit $file";
+ return "";
+ } else {
+ return [standard_transmit $dest $file];
+ }
+}
diff --git a/dejagnu/lib/libgloss.exp b/dejagnu/lib/libgloss.exp
new file mode 100644
index 00000000000..3c186d0a86d
--- /dev/null
+++ b/dejagnu/lib/libgloss.exp
@@ -0,0 +1,835 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+# this contains a list of gcc options and their respective directories.
+
+#
+# Find the pieces of libgloss for testing the GNU development tools
+# needed to link a set of object files into an executable.
+# This usually means setting the -L and -B paths correctly.
+#
+proc libgloss_link_flags { args } {
+ global target_cpu
+ global srcdir
+
+ # libgloss doesn't work native
+ if [isnative] {
+ return ""
+ }
+
+ # if we're on a remote host, we can't search for the file, so we can only
+ # use an installed compiler, so we don't add any paths here.
+ if [is_remote host] {
+ return ""
+ }
+
+ set gccpath "[get_multilibs]"
+
+ # map the target_cpu to the proper libgloss directory. unfortunately, these
+ # directory names are hardcoded into libgloss.
+ switch -glob -- $target_cpu {
+ "sparc86x" {
+ set cpu sparc
+ }
+ "sparclite" {
+ set cpu sparc
+ }
+ "sparclet" {
+ set cpu sparc
+ }
+ "sparc64*" {
+ set cpu sparc
+ }
+ "hppa*" {
+ set cpu pa
+ }
+ "mips*" {
+ set cpu mips
+ }
+ "powerpc*" {
+ set cpu rs6000
+ }
+ "d10v*" {
+ set cpu libnosys
+ }
+ default {
+ set cpu $target_cpu
+ }
+ }
+
+ set gloss_srcdir ""
+ # look for the libgloss srcdir sp we can find the linker scripts
+ set gloss_srcdir [lookfor_file ${srcdir} libgloss/$cpu]
+
+ # set the proper paths for gcc if the target subdir exists, else assume we
+ # have no libgloss support for this target.
+ if { $gloss_srcdir == "" } {
+ return ""
+ }
+ if [file exists $gccpath/libgloss/$cpu] {
+ verbose "Libgloss path is $gccpath/libgloss/$cpu" 2
+ return "-B$gccpath/libgloss/$cpu/ -L$gccpath/libgloss/$cpu -L$gloss_srcdir"
+ } else {
+ verbose -log "No libgloss support for this target." 2
+ return ""
+ }
+}
+
+# There aren't any, but we'll be orthogonal here.
+
+proc libgloss_include_flags { args } {
+ return ""
+}
+
+#
+# Find the newlib libraries in the current source tree.
+#
+proc newlib_link_flags { args } {
+ global tool_root_dir
+
+ # libgloss doesn't work native
+ if [isnative] {
+ return ""
+ }
+
+ # if we're on a remote host, we can't search for the file, so we can only
+ # use an installed compiler, so we don't add any paths here.
+ if [is_remote host] {
+ return ""
+ }
+
+ set ld_script_path [lookfor_file ${tool_root_dir} "ld/ldscripts"];
+ if { $ld_script_path != "" } {
+ set result "-L[file dirname $ld_script_path]"
+ } else {
+ set result ""
+ }
+
+ set gccpath "[get_multilibs]"
+
+ verbose "Looking for $gccpath/newlib"
+ if [file exists $gccpath/newlib] {
+ verbose "Newlib path is $gccpath/newlib"
+ return "$result -B$gccpath/newlib/ -L$gccpath/newlib"
+ } else {
+ verbose "No newlib support for this target"
+ return "$result"
+ }
+}
+
+proc newlib_include_flags { args } {
+ global srcdir
+
+ if [isnative] {
+ return ""
+ }
+
+ if [is_remote host] {
+ return ""
+ }
+
+ set gccpath "[get_multilibs]"
+
+ if [file exists $gccpath/newlib] {
+ verbose "Newlib path is $gccpath/newlib"
+
+ set newlib_dir [lookfor_file ${srcdir} newlib/libc/include/assert.h]
+ if { ${newlib_dir} != "" } {
+ set newlib_dir [file dirname ${newlib_dir}]
+ }
+ return " -I$gccpath/newlib/targ-include -I${newlib_dir}"
+ } else {
+ verbose "No newlib support for this target"
+ }
+}
+
+proc libio_include_flags { args } {
+ global srcdir
+ global tool_root_dir
+
+ if [is_remote host] {
+ return ""
+ }
+
+ set gccpath "[get_multilibs]"
+
+ if { $gccpath == "" } {
+ set gccpath "$tool_root_dir";
+ }
+
+ set libio_bin_dir [lookfor_file ${gccpath} libio/_G_config.h];
+
+ # linux doesn't build _G_config.h and the test above fails, so
+ # we search for iostream.list too.
+ if { $libio_bin_dir == "" } {
+ set libio_bin_dir [lookfor_file ${gccpath} libio/iostream.list];
+ }
+
+ set libio_src_dir [lookfor_file ${srcdir} libio/Makefile.in]
+ if { $libio_bin_dir != "" && $libio_src_dir != "" } {
+ set libio_src_dir [file dirname ${libio_src_dir}]
+ set libio_bin_dir [file dirname ${libio_bin_dir}];
+ return " -I${libio_src_dir} -I${libio_bin_dir}"
+ } else {
+ return ""
+ }
+}
+
+proc libio_link_flags { args } {
+ if [is_remote host] {
+ return ""
+ }
+
+ set gccpath "[get_multilibs]"
+
+ set libio_dir [lookfor_file ${gccpath} libio/libio.a]
+ if { $libio_dir != "" } {
+ return "-L[file dirname ${libio_dir}]"
+ } else {
+ return ""
+ }
+}
+
+proc g++_include_flags { args } {
+ global srcdir
+
+ if [is_remote host] {
+ return ""
+ }
+
+ set gccpath [get_multilibs]
+ set libio_dir ""
+ set flags ""
+
+ set dir [lookfor_file ${srcdir} libg++]
+ if { ${dir} != "" } {
+ append flags "-I${dir} -I${dir}/src "
+ }
+ set dir [lookfor_file ${srcdir} libstdc++]
+ if { ${dir} != "" } {
+ append flags "-I${dir} -I${dir}/stl"
+ }
+ return "$flags"
+}
+
+proc g++_link_flags { args } {
+ global srcdir
+ global ld_library_path
+
+ set gccpath [get_multilibs];
+ set libio_dir ""
+ set flags ""
+ set ld_library_path "."
+
+ if { $gccpath != "" } {
+ if [file exists "${gccpath}/lib/libstdc++.a"] {
+ append ld_library_path ":${gccpath}/lib"
+ }
+ if [file exists "${gccpath}/libg++/libg++.a"] {
+ append flags "-L${gccpath}/libg++ "
+ append ld_library_path ":${gccpath}/libg++"
+ }
+ if [file exists "${gccpath}/libstdc++/libstdc++.a"] {
+ append flags "-L${gccpath}/libstdc++ "
+ append ld_library_path ":${gccpath}/libstdc++"
+ }
+ if [file exists "${gccpath}/libiberty/libiberty.a"] {
+ append flags "-L${gccpath}/libiberty "
+ }
+ if [file exists "${gccpath}/librx/librx.a"] {
+ append flags "-L${gccpath}/librx "
+ }
+ } else {
+ global tool_root_dir;
+
+ set libgpp [lookfor_file ${tool_root_dir} libg++];
+ if { $libgpp != "" } {
+ append flags "-L${libgpp} ";
+ append ld_library_path ":${libgpp}"
+ }
+ set libstdcpp [lookfor_file ${tool_root_dir} libstdc++];
+ if { $libstdcpp != "" } {
+ append flags "-L${libstdcpp} ";
+ append ld_library_path ":${libstdcpp}"
+ }
+ set libiberty [lookfor_file ${tool_root_dir} libiberty];
+ if { $libiberty != "" } {
+ append flags "-L${libiberty} ";
+ }
+ set librx [lookfor_file ${tool_root_dir} librx];
+ if { $librx != "" } {
+ append flags "-L${librx} ";
+ }
+ }
+ return "$flags"
+}
+
+proc libstdc++_include_flags { args } {
+ global srcdir
+
+ if [is_remote host] {
+ return ""
+ }
+
+ set gccpath [get_multilibs]
+ set libio_dir ""
+ set flags ""
+
+ set dir [lookfor_file ${srcdir} libstdc++]
+ if { ${dir} != "" } {
+ append flags "-I${dir} -I${dir}/stl"
+ }
+ return "$flags"
+}
+
+proc libstdc++_link_flags { args } {
+ global srcdir
+ global ld_library_path
+
+ set gccpath [get_multilibs];
+ set libio_dir ""
+ set flags ""
+
+ if { $gccpath != "" } {
+ if [file exists "${gccpath}/libstdc++/libstdc++.a"] {
+ append flags "-L${gccpath}/libstdc++ "
+ append ld_library_path ":${gccpath}/libstdc++"
+ }
+ if [file exists "${gccpath}/libiberty/libiberty.a"] {
+ append flags "-L${gccpath}/libiberty "
+ }
+ if [file exists "${gccpath}/librx/librx.a"] {
+ append flags "-L${gccpath}/librx "
+ }
+ } else {
+ global tool_root_dir;
+
+ set libstdcpp [lookfor_file ${tool_root_dir} libstdc++];
+ if { $libstdcpp != "" } {
+ append flags "-L${libstdcpp} ";
+ append ld_library_path ":${libstdcpp}"
+ }
+ set libiberty [lookfor_file ${tool_root_dir} libiberty];
+ if { $libiberty != "" } {
+ append flags "-L${libiberty} ";
+ }
+ set librx [lookfor_file ${tool_root_dir} librx];
+ if { $librx != "" } {
+ append flags "-L${librx} ";
+ }
+ }
+ return "$flags"
+}
+
+#
+# Get the list of directories and -m options for gcc. This is kinda bogus that
+# generic testing software needs support for gcc hardwired in, but to make
+# testing the GNU tools work right, there didn't seem to be any other way.
+#
+
+proc get_multilibs { args } {
+ global target_alias
+ global board
+ global board_info
+
+ # if we're on a remote host, we can't search for the file, so we can only
+ # use an installed compiler, so we don't add any paths here.
+ if [is_remote host] {
+ return ""
+ }
+
+ if [info exists board] {
+ set target_board $board;
+ } else {
+ set target_board [target_info name];
+ }
+
+ if { [llength $args] == 0 } {
+ if [board_info $target_board exists multitop] {
+ return "[board_info $target_board multitop]";
+ }
+
+ set board_info($target_board,multitop) ""
+ }
+
+ if { [board_info $target_board exists compiler] } {
+ set compiler [board_info $target_board compiler];
+ } else {
+ set compiler [find_gcc];
+ }
+
+ if { $compiler == "" } {
+ return "";
+ }
+
+ foreach x "$compiler" {
+ if [regexp "^-B" "$x"] {
+ regsub "^-B" "$x" "" comp_base_dir;
+ set comp_base_dir [file dirname $comp_base_dir];
+ break;
+ }
+ }
+ if { [llength $args] > 0 } {
+ set mopts [lindex $args 0];
+ } else {
+ if { [board_info $target_board exists multilib_flags] } {
+ set mopts [board_info $target_board multilib_flags];
+ } else {
+ set mopts ""
+ }
+ }
+
+ regsub "^-" $mopts "" moptions
+ regsub -all " -" $moptions " " dirty_moptions
+ set moptions ""
+ foreach x [split $dirty_moptions " "] {
+ if { $x != "" && [lsearch -exact $moptions $x] < 0 } {
+ lappend moptions $x
+ }
+ }
+
+ regexp "/.* " $compiler compiler
+ set compiler [string trimright $compiler " "]
+ verbose "compiler is $compiler"
+
+ if { [which $compiler] == 0 } {
+ return "";
+ }
+
+ if ![info exists comp_base_dir] {
+ set comp_base_dir [file dirname [file dirname [file dirname [file dirname [file dirname [exec $compiler --print-prog-name=cc1]]]]]];
+ }
+
+ # extract the options and their directory names as know by gcc
+ foreach i "[exec $compiler --print-multi-lib]" {
+ set opts ""
+ set dir ""
+ regexp -- "\[a-z0-9=/\.-\]*;" $i dir
+ set dir [string trimright $dir "\;@"]
+ regexp -- "\;@*\[\@a-zA-Z0-9=/\.-\]*" $i opts
+ set opts [split [string trimleft $opts "\;@"] "@"]
+ lappend multilibs "$dir {$opts }"
+ }
+
+ # extract the MULTILIB_MATCHES from dumpspecs
+ set multimatches ""
+ set lines [split [exec $compiler -dumpspecs] "\n"]
+ for {set i 0} {$i <= [llength $lines] - 1} {incr i 1} {
+ if {"*multilib_matches:" == "[lindex $lines $i]"} {
+ set multimatches [lindex $lines [expr $i + 1]]
+ break
+ }
+ }
+ # if we find some
+ if {$multimatches != ""} {
+ # Split it into a list of pairs. If an moptions are the first
+ # of a pair, then replace it with the second. If an moption
+ # is not in multimatches, we assume it's not a multilib option
+
+ set splitmatches [split $multimatches ";"]
+ set multimatches ""
+ foreach i $splitmatches {
+ lappend multimatches [split $i " "]
+ }
+ verbose "multimatches: $multimatches" 3
+
+ verbose "options before multimatches: $moptions" 3
+ set toptions $moptions
+ set moptions ""
+ foreach i $toptions {
+ foreach j $multimatches {
+ verbose "comparing [lindex $j 0] == $i" 3
+ if {[lindex $j 0] == $i} {
+ lappend moptions [lindex $j 1]
+ }
+ }
+ }
+ verbose "options after multimatches: $moptions" 3
+ }
+
+ # search for the top level multilib directory
+ set multitop [lookfor_file "${comp_base_dir}" "${target_alias}"]
+ if { $multitop == "" } {
+ set multitop [lookfor_file "${comp_base_dir}" "libraries"]
+ if { $multitop == "" } {
+ set multitop "[lookfor_file ${comp_base_dir} gcc/xgcc]"
+ if { $multitop != "" } {
+ set multitop [file dirname [file dirname $multitop]];
+ } else {
+ return ""
+ }
+ }
+ }
+
+ # make a list of -m<foo> options from the various compiler config variables
+ set gccpath ""
+
+ # compare the lists of gcc options with the list of support multilibs
+ verbose "Supported multilibs are: $multilibs" 3
+ set best 0;
+ foreach i "$multilibs" {
+ set hits 0
+ set opts [lindex $i 1];
+ if { [llength $opts] <= [llength $moptions] } {
+ foreach j "$moptions" {
+ # see if all the -m<foo> options match any of the multilibs
+ verbose "Looking in $i for $j" 3
+ if { [lsearch -exact $opts $j] >= 0 } {
+ incr hits
+ }
+ }
+
+ if { $hits > $best } {
+ verbose "[lindex $i 0] is better, using as gcc path" 2
+ set gccpath "[lindex $i 0]"
+ set best $hits;
+ }
+ }
+ }
+ if ![info exists multitop] {
+ return "";
+ }
+
+ verbose "gccpath is $gccpath" 3
+
+ if [file exists $multitop/$gccpath] {
+ verbose "GCC path is $multitop/$gccpath" 3
+ if { [llength $args] == 0 } {
+ set board_info($target_board,multitop) "$multitop/$gccpath"
+ }
+ return "$multitop/$gccpath"
+ } else {
+ verbose "GCC path is $multitop" 3
+ if { [llength $args] == 0 } {
+ set board_info($target_board,multitop) "$multitop"
+ }
+ return "$multitop"
+ }
+}
+
+proc find_binutils_prog { name } {
+ global tool_root_dir;
+
+ if ![is_remote host] {
+
+ set file [lookfor_file $tool_root_dir $name];
+ if { $file == "" } {
+ set file [lookfor_file $tool_root_dir ${name}-new];
+ }
+ if { $file == "" } {
+ set file [lookfor_file $tool_root_dir binutils/$name];
+ }
+ if { $file == "" } {
+ set file [lookfor_file $tool_root_dir binutils/${name}-new];
+ }
+ if { $file != "" } {
+ set NAME "$file";
+ } else {
+ set NAME [transform $name];
+ }
+ } else {
+ set NAME [transform $name]
+ }
+ return $NAME;
+}
+
+proc find_gcc {} {
+ global tool_root_dir
+
+ if ![is_remote host] {
+ set file [lookfor_file $tool_root_dir xgcc];
+ if { $file == "" } {
+ set file [lookfor_file $tool_root_dir gcc/xgcc];
+ }
+ if { $file != "" } {
+ set CC "$file -B[file dirname $file]/";
+ } else {
+ set CC [transform gcc];
+ }
+ } else {
+ set CC [transform gcc]
+ }
+ return $CC;
+}
+
+proc find_gcj {} {
+ global tool_root_dir
+
+ if ![is_remote host] {
+ set file [lookfor_file $tool_root_dir gcj];
+ if { $file == "" } {
+ set file [lookfor_file $tool_root_dir gcc/gcj];
+ }
+ if { $file != "" } {
+ set CC "$file -B[file dirname $file]/";
+ } else {
+ set CC [transform gcj];
+ }
+ } else {
+ set CC [transform gcj]
+ }
+ return $CC;
+}
+
+proc find_g++ {} {
+ global tool_root_dir
+
+ if ![is_remote host] {
+ set file [lookfor_file $tool_root_dir g++];
+ if { $file == "" } {
+ set file [lookfor_file $tool_root_dir gcc/g++];
+ }
+ if { $file != "" } {
+ set CC "$file -B[file dirname $file]/";
+ } else {
+ set CC [transform g++];
+ }
+ } else {
+ set CC [transform g++]
+ }
+ return $CC;
+}
+
+proc find_g77 {} {
+ global tool_root_dir
+
+ if ![is_remote host] {
+ set file [lookfor_file $tool_root_dir g77];
+ if { $file == "" } {
+ set file [lookfor_file $tool_root_dir gcc/g77];
+ }
+ if { $file != "" } {
+ set CC "$file -B[file dirname $file]/";
+ } else {
+ set CC [transform g77];
+ }
+ } else {
+ set CC [transform g77]
+ }
+ return $CC;
+}
+
+proc find_nm {} {
+ global tool_root_dir
+
+ set NM ""
+ if ![is_remote host] {
+ set NM [lookfor_file $tool_root_dir nm-new]
+ if {$NM == ""} {
+ set NM [lookfor_file $tool_root_dir binutils/nm-new]
+ }
+ }
+ if { $NM == ""} {
+ set NM [transform nm];
+ }
+ return $NM;
+}
+
+proc process_multilib_options { args } {
+ global board;
+ global board_variant_list;
+ global is_gdb_remote;
+
+ set is_gdb_remote 0;
+
+ if [board_info $board exists multilib_flags] {
+ return;
+ }
+ eval add_multilib_option $args;
+
+ set multilib_flags "";
+
+ foreach x $board_variant_list {
+ regsub -all "^\[ \t\]*" "$x" "" x;
+ regsub -all "\[ \t\]*$" "$x" "" x;
+
+ if { $x == "" } {
+ continue;
+ }
+ case $x in {
+ { aout } {
+ set_board_info obj_format "a.out";
+ }
+ { elf } {
+ set_board_info obj_format "elf";
+ }
+ { pe } {
+ set_board_info obj_format "pe";
+ }
+ { ecoff } {
+ set_board_info obj_format "ecoff";
+ }
+ { stabs } {
+ set_board_info debug_flags "-gstabs";
+ }
+ { dwarf2 } {
+ set_board_info debug_flags "-gdwarf2";
+ }
+ { gdb:*=* } {
+ regsub "^gdb:\[^=\]*=(.*)$" "$x" "\\1" value;
+ regsub "^gdb:(\[^=\]*)=.*$" "$x" "\\1" variable;
+ set_board_info $variable "$value";
+ }
+ { gdb*remote } {
+ set is_gdb_remote 1;
+ }
+ { little*endian el EL } {
+ append multilib_flags " -EL";
+ }
+ { big*endian eb EB } {
+ append multilib_flags " -EB";
+ }
+ { "soft*float" } {
+ append multilib_flags " -msoft-float"
+ }
+ { "-*" } {
+ append multilib_flags " $x";
+ }
+ default {
+ append multilib_flags " -m$x";
+ }
+ }
+ }
+ set_board_info multilib_flags $multilib_flags;
+}
+
+proc add_multilib_option { args } {
+ global board_variant_list
+
+ if ![info exists board_variant_list] {
+ set board_variant_list ""
+ }
+ set board_variant_list [concat $args $board_variant_list];
+}
+
+proc find_gas { } {
+ global tool_root_dir
+
+ set AS ""
+
+ if ![is_remote host] {
+ set AS [lookfor_file $tool_root_dir as-new];
+ if { $AS == "" } {
+ set AS [lookfor_file $tool_root_dir gas/as-new];
+ }
+ }
+ if { $AS == "" } {
+ set AS [transform as];
+ }
+ return $AS;
+}
+
+proc find_ld { } {
+ global tool_root_dir
+
+ set LD ""
+
+ if ![is_remote host] {
+ set LD [lookfor_file $tool_root_dir ld-new];
+ if { $LD == "" } {
+ set LD [lookfor_file $tool_root_dir ld/ld-new];
+ }
+ }
+ if { $LD == "" } {
+ set LD [transform ld];
+ }
+ return $LD;
+}
+
+proc build_wrapper { gluefile } {
+ global libdir
+
+ if [target_info exists wrap_m68k_aout] {
+ set flags "additional_flags=-DWRAP_M68K_AOUT";
+ set result "";
+ } elseif [target_info exists uses_underscores] {
+ set flags "additional_flags=-DUNDERSCORES";
+ set result "-Wl,-wrap,__exit -Wl,-wrap,_main -Wl,-wrap,_abort";
+ } else {
+ set flags "";
+ if [target_info exists is_vxworks] {
+ set flags "additional_flags=-DVXWORKS";
+ }
+ set result "-Wl,-wrap,exit -Wl,-wrap,main -Wl,-wrap,abort";
+ }
+ if [target_info exists wrap_compile_flags] {
+ lappend flags "additional_flags=[target_info wrap_compile_flags]";
+ }
+ if { [target_compile ${libdir}/testglue.c ${gluefile} object $flags] == "" } {
+ set gluefile [remote_download host ${gluefile} testglue.o];
+ return [list $gluefile $result];
+ } else {
+ return ""
+ }
+}
+
+
+proc winsup_include_flags { args } {
+ global srcdir
+
+ if [isnative] {
+ return ""
+ }
+
+ if [is_remote host] {
+ return ""
+ }
+
+ set gccpath "[get_multilibs]"
+
+ if [file exists $gccpath/winsup] {
+ verbose "Winsup path is $gccpath/winsup"
+
+ set winsup_dir [lookfor_file ${srcdir} winsup/include/windows.h]
+ if { ${winsup_dir} != "" } {
+ set winsup_dir [file dirname ${winsup_dir}]
+ return " -I${winsup_dir}"
+ }
+ }
+ verbose "No winsup support for this target"
+
+}
+#
+# Find the winsup libraries in the current source tree.
+#
+proc winsup_link_flags { args } {
+ # libgloss doesn't work native
+ if [isnative] {
+ return ""
+ }
+
+ # if we're on a remote host, we can't search for the file, so we can only
+ # use an installed compiler, so we don't add any paths here.
+ if [is_remote host] {
+ return ""
+ }
+
+ set gccpath "[get_multilibs]"
+
+ verbose "Looking for $gccpath/winsup"
+ if [file exists $gccpath/winsup] {
+ verbose "Winsup path is $gccpath/newlib"
+ return "-B$gccpath/winsup/ -L$gccpath/winsup"
+ } else {
+ verbose "No winsup support for this target"
+ return ""
+ }
+}
diff --git a/dejagnu/lib/mondfe.exp b/dejagnu/lib/mondfe.exp
new file mode 100644
index 00000000000..b46484efc85
--- /dev/null
+++ b/dejagnu/lib/mondfe.exp
@@ -0,0 +1,213 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+#
+# Connect to udi using mondfe
+#
+# HOSTNAME can be `iss' to talk to the simulator.
+# The result is the value of `spawn_id' or -1 for failure.
+#
+proc mondfe_open { hostname } {
+ global spawn_id
+ global board_info
+
+ set retries 0
+ set result -1
+
+ set shell_prompt [board_info $hostname shell_prompt]
+ if ![board_info $hostname exists mondfe,name] {
+ perror "Must set board_info(${hostname},mondfe,name)"
+ return -1;
+ }
+ if [board_info $hostname exists mondfe] {
+ set mondfe [board_info $hostname mondfe];
+ } else {
+ set mondfe "mondfe"
+ }
+
+ set remote_host [board_info $hostname mondfe,name];
+
+ if [board_info $hostname exists mondfe_host] {
+ set rh [board_info $hostname mondfe_host];
+ } else {
+ verbose "Attempting to connect to $hostname via mondfe."
+ set rh "host";
+ }
+
+ set shell_id [remote_spawn $rh "$mondfe -D -TIP $remote_host"];
+
+ remote_expect $rh 60 {
+ "$shell_prompt" {
+ verbose "Got prompt"
+ set result 0
+ }
+ "*server bind*failed: Address already in use*" {
+ warning "Socket file already exists."
+ incr retries
+ if { $retries <= 2 } {
+ exp_continue;
+ }
+ }
+ -indices -re ".*(UDIERROR\[^\r\n\]*)\[\r\n\]" {
+ warning "$expect_out(1,string)"
+ exp_continue;
+ }
+ -indices -re ".*(DFEERROR\[^\r\n\]*)\[\r\n\]" {
+ warning "$expect_out(1,string)"
+ exp_continue;
+ }
+ timeout {
+ warning "Timed out trying to connect."
+ set result -1
+ incr retries
+ if { $retries <= 2 } {
+ remote_send $rh "\n"
+ exp_continue;
+ }
+ }
+ }
+
+ if { $result < 0 } {
+ perror "Couldn't connect after $retries retries."
+ remote_close $rh;
+ return -1
+ } else {
+ set board_info($hostname,fileid) $shell_id;
+ return $shell_id;
+ }
+}
+
+#
+# Downloads using the y (yank) command in mondfe
+#
+# FILE is a full path name to the file to download.
+# Returns 1 if an error occured, 0 otherwise.
+#
+proc mondfe_ld { dest_machine file } {
+ global decimal # Regexp to match a decimal number.
+
+ if ![file exists $file] {
+ perror "$file doesn't exist."
+ return ""
+ }
+
+ set shell_prompt [board_info $dest_machine shell_prompt]
+
+ if [board_info $dest_machine exists mondfe_host] {
+ set remote_host [board_info $dest_machine mondfe_host];
+ set file [remote_download $remote_host $file montest]
+ } else {
+ set remote_host "host";
+ }
+
+ verbose "Downloading $file." 2
+ verbose "Shell prompt is $shell_prompt." 3
+ set result 1
+ remote_send $remote_host "y $file\n"
+ remote_expect $remote_host 60 {
+ "y $file" {
+ exp_continue;
+ }
+ -re "loading $file\[\r\n\]+" {
+ exp_continue;
+ }
+ -re "Load(ing|ed) *TEXT section from\[^\r\n\]*\[\r\n\]+" {
+ verbose -n "." 2
+ exp_continue;
+ }
+ -re "Load(ing|ed) *LIT section from\[^\r\n\]*\[\r\n\]+" {
+ verbose -n "." 2
+ exp_continue;
+ }
+ -re "Load(ing|ed) *DATA section from\[^\r\n\]*\[\r\n\]+" {
+ verbose -n "." 2
+ exp_continue;
+ }
+ -re "Clear(ing|ed) *BSS section from\[^\r\n\]*\[\r\n\]+" {
+ verbose -n "." 2
+ exp_continue;
+ }
+ -re "(^|\[\r\n\]+)$shell_prompt$" {
+ verbose "Downloaded $file successfully." 2
+ set result 0
+ }
+ -re "Command failed.*$shell_prompt$" {
+ set result 1
+ }
+ -re "DFEWARNING: $decimal : EMMAGIC: Bad COFF file magic number.*Command failed.*$shell_prompt$" {
+ warning "Bad COFF file magic number"
+ set result 1
+ }
+ -re "Ignoring COMMENT section \($decimal bytes\)\[^\r\n\]*\[\r\n\]+" {
+ verbose "Ignoring COMMENT section" 2
+ exp_continue;
+ }
+ timeout {
+ perror "Timed out trying to download $file."
+ set result 1
+ }
+ }
+
+ if { $result && [info exists expect_out(buffer)] } {
+ send_log $expect_out(buffer)
+ }
+
+ if [board_info $dest_machine exists mondfe_host] {
+ remote_file $remote_machine delete $file
+ }
+
+ return $result
+}
+
+#
+# Exit the remote shell
+#
+proc mondfe_close { hostname } {
+ global board_info
+
+ if [board_info $hostname exists mondfe_host] {
+ set remote_host [board_info $hostname mondfe_host];
+ } else {
+ set remote_host "host";
+ }
+
+ if ![board_info $hostname exists fileid] {
+ return 0;
+ }
+
+ if [board_info $remote_host exists fileid] {
+ remote_send $remote_host "q\n"
+ remote_expect $remote_host 30 {
+ "Goodbye." {
+ verbose "Exited mondfe."
+ }
+ timeout {
+ warning "mondfe didn't exit cleanly."
+ }
+ }
+
+ remote_close $remote_host;
+ }
+
+ unset board_info($hostname,fileid);
+
+ return 0;
+}
diff --git a/dejagnu/lib/remote.exp b/dejagnu/lib/remote.exp
new file mode 100644
index 00000000000..0bc8ed09b73
--- /dev/null
+++ b/dejagnu/lib/remote.exp
@@ -0,0 +1,1265 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+# load various protocol support modules
+
+load_lib "mondfe.exp"
+load_lib "xsh.exp"
+load_lib "telnet.exp"
+load_lib "rlogin.exp"
+load_lib "kermit.exp"
+load_lib "tip.exp"
+load_lib "rsh.exp"
+load_lib "ftp.exp"
+
+#
+# Open a connection to a remote host or target. This requires the target_info
+# array be filled in with the proper info to work.
+#
+# type is either "build", "host", "target", or the name of a board loaded
+# into the board_info array. The default is target if no name is supplied.
+# It returns the spawn id of the process that is the connection.
+#
+
+proc remote_open { args } {
+ global reboot
+
+ if { [llength $args] == 0 } {
+ set type "target"
+ } else {
+ set type $args
+ }
+
+ # Shudder...
+ if { $reboot && $type == "target" } {
+ reboot_target;
+ }
+
+ return [call_remote "" open $type];
+}
+
+proc remote_raw_open { args } {
+ return [eval call_remote raw open $args];
+}
+
+# Run the specified COMMANDLINE on the local machine, redirecting input
+# to file INP (if non-empty), redirecting output to file OUTP (if non-empty),
+# and waiting TIMEOUT seconds for the command to complete before killing
+# it. A two-member list is returned; the first member is the exit status
+# of the command, the second is any output produced from the command
+# (if output is redirected, this may or may not be empty). If output is
+# redirected, both stdout and stderr will appear in the specified file.
+#
+# Caveats: A pipeline is used if input or output is redirected. There
+# will be problems with killing the program if a pipeline is used. Either
+# the "tee" command or the "cat" command is used in the pipeline if input
+# or output is redirected. If the program needs to be killed, /bin/sh and
+# the kill command will be invoked.
+#
+proc local_exec { commandline inp outp timeout } {
+ # TCL's exec is a pile of crap. It does two very inappropriate things;
+ # firstly, it has no business returning an error if the program being
+ # executed happens to write to stderr. Secondly, it appends its own
+ # error messages to the output of the command if the process exits with
+ # non-zero status.
+ #
+ # So, ok, we do this funny stuff with using spawn sometimes and
+ # open others because of spawn's inability to invoke commands with
+ # redirected I/O. We also hope that nobody passes in a command that's
+ # a pipeline, because spawn can't handle it.
+ #
+ # We want to use spawn in most cases, because tcl's pipe mechanism
+ # doesn't assign process groups correctly and we can't reliably kill
+ # programs that bear children. We can't use tcl's exec because it has
+ # no way to timeout programs that hang. *sigh*
+ #
+ if { "$inp" == "" && "$outp" == "" } {
+ set id -1;
+ set result [catch "eval spawn \{${commandline}\}" pid];
+ if { $result == 0 } {
+ set result2 0;
+ } else {
+ set pid 0;
+ set result2 5;
+ }
+ } else {
+ # Can you say "uuuuuugly"? I knew you could!
+ # All in the name of non-infinite hangs.
+ if { $inp != "" } {
+ set inp "< $inp";
+ set mode "r";
+ } else {
+ set mode "w";
+ }
+
+ set use_tee 0;
+ # We add |& cat so that TCL exec doesn't freak out if the
+ # program writes to stderr.
+ if { $outp == "" } {
+ set outp "|& cat"
+ } else {
+ set outpf "$outp";
+ set outp "> $outp"
+ if { $inp != "" } {
+ set use_tee 1;
+ }
+ }
+ # Why do we use tee? Because open can't redirect both input and output.
+ if { $use_tee } {
+ set result [catch {open "| ${commandline} $inp |& tee $outpf" RDONLY} id] ;
+ } else {
+ set result [catch {open "| ${commandline} $inp $outp" $mode} id] ;
+ }
+
+ if { $result != 0 } {
+ global errorInfo
+ return [list -1 "open of $commandline $inp $outp failed: $errorInfo"];
+ }
+ set pid [pid $id];
+ set result [catch "spawn -leaveopen $id" result2];
+ }
+ # Prepend "-" to each pid, to generate the "process group IDs" needed by
+ # kill.
+ set pgid "-[join $pid { -}]";
+ verbose "pid is $pid $pgid";
+ if { $result != 0 || $result2 != 0 } {
+ # This shouldn't happen.
+ global errorInfo;
+ if [info exists errorInfo] {
+ set foo $errorInfo;
+ } else {
+ set foo "";
+ }
+ verbose "spawn -open $id failed, $result $result2, $foo";
+ catch "close $id";
+ return [list -1 "spawn failed"];
+ }
+
+ set got_eof 0;
+ set output "";
+
+ # Wait for either $timeout seconds to elapse, or for the program to
+ # exit.
+ expect {
+ -i $spawn_id -timeout $timeout -re ".+" {
+ append output $expect_out(buffer);
+ if { [string length $output] < 512000 } {
+ exp_continue -continue_timer;
+ }
+ }
+ timeout {
+ warning "program timed out.";
+ }
+ eof {
+ set got_eof 1;
+ }
+ }
+
+ # Uuuuuuugh. Now I'm getting really sick.
+ # If we didn't get an EOF, we have to kill the poor defenseless program.
+ # However, TCL has no kill primitive, so we have to execute an external
+ # command in order to execute the execution. (English. Gotta love it.)
+ if { ! $got_eof } {
+ verbose "killing $pid $pgid";
+ exec sh -c "exec > /dev/null 2>&1 && (kill -2 $pgid || kill -2 $pid) && sleep 5 && (kill -15 $pgid || kill $pid) && sleep 5 && (kill -9 $pgid || kill -9 $pid)" &;
+ }
+ # This will hang if the kill doesn't work. Nothin' to do, and it's not ok.
+ catch "close -i $spawn_id";
+ set r2 [catch "wait -i $spawn_id" wres];
+ if { $id > 0 } {
+ set r2 [catch "close $id" res];
+ } else {
+ verbose "waitres is $wres" 2;
+ if { $r2 == 0 } {
+ set r2 [lindex $wres 3];
+ if { [llength $wres] > 4 } {
+ if { [lindex $wres 4] == "CHILDKILLED" } {
+ set r2 1;
+ }
+ }
+ if { $r2 != 0 } {
+ set res "$wres";
+ } else {
+ set res "";
+ }
+ } else {
+ set res "wait failed";
+ }
+ }
+ if { $r2 != 0 || $res != "" || ! $got_eof } {
+ verbose "close result is $res";
+ set status 1;
+ } else {
+ set status 0;
+ }
+ verbose "output is $output";
+ if { $outp == "" } {
+ return [list $status $output];
+ } else {
+ return [list $status ""];
+ }
+}
+
+#
+# Execute the supplied program on HOSTNAME. There are four optional arguments;
+# the first is a set of arguments to pass to PROGRAM, the second is an
+# input file to feed to stdin of PROGRAM, the third is the name of an
+# output file where the output from PROGRAM should be written, and
+# the fourth is a timeout value (we give up after the specified # of seconds
+# has elapsed).
+#
+# A two-element list is returned. The first value is the exit status of the
+# program (-1 if the exec failed). The second is any output produced by
+# the program (which may or may not be empty if output from the program was
+# redirected).
+#
+proc remote_exec { hostname program args } {
+ if { [llength $args] > 0 } {
+ set pargs [lindex $args 0];
+ } else {
+ set pargs ""
+ }
+
+ if { [llength $args] > 1 } {
+ set inp "[lindex $args 1]";
+ } else {
+ set inp ""
+ }
+
+ if { [llength $args] > 2 } {
+ set outp "[lindex $args 2]";
+ } else {
+ set outp ""
+ }
+
+ # 300 is probably a lame default.
+ if { [llength $args] > 3 } {
+ set timeout "[lindex $args 3]";
+ } else {
+ set timeout 300
+ }
+
+ verbose -log "Executing on $hostname: $program $pargs $inp $outp (timeout = $timeout)" 2;
+
+ # Run it locally if appropriate.
+ if { ![is_remote $hostname] } {
+ return [local_exec "$program $pargs" $inp $outp $timeout];
+ } else {
+ return [call_remote "" exec $hostname $program $pargs $inp $outp];
+ }
+}
+
+proc standard_exec { hostname args } {
+ return [eval rsh_exec \"$hostname\" $args];
+}
+
+#
+# Close the remote connection.
+# arg - This is the name of the machine whose connection we're closing,
+# or target, host or build.
+#
+
+proc remote_close { host } {
+ while { 1 } {
+ set result [call_remote "" close "$host"];
+ if { [remote_pop_conn $host] != "pass" } {
+ break;
+ }
+ }
+ return $result;
+}
+
+proc remote_raw_close { host } {
+ return [call_remote raw close "$host"];
+}
+
+proc standard_close { host } {
+ global board_info
+
+ if [board_info ${host} exists fileid] {
+ set shell_id [board_info ${host} fileid];
+ set pid -1;
+
+ verbose "Closing the remote shell $shell_id" 2
+ if [board_info ${host} exists fileid_origid] {
+ set oid [board_info ${host} fileid_origid];
+ set pid [pid $oid];
+ unset board_info(${host},fileid_origid);
+ } else {
+ set result [catch "exp_pid -i $shell_id" pid];
+ if { $result != 0 || $pid <= 0 } {
+ set result [catch "pid $shell_id" pid];
+ if { $result != 0 } {
+ set pid -1;
+ }
+ }
+ }
+ if { $pid > 0 } {
+ verbose "doing kill, pid is $pid";
+ # This is very, very nasty. Then again, if after did something
+ # reasonable...
+ set pgid "-[join $pid { -}]";
+ exec sh -c "exec > /dev/null 2>&1 && (kill -2 $pgid || kill -2 $pid) && sleep 5 && (kill $pgid || kill $pid) && sleep 5 && (kill -9 $pgid || kill -9 $pid)" &;
+ }
+ verbose "pid is $pid";
+ catch "close -i $shell_id";
+ if [info exists oid] {
+ catch "close $oid";
+ }
+ catch "wait -i $shell_id";
+ unset board_info(${host},fileid);
+ verbose "Shell closed.";
+ }
+ return 0;
+}
+
+#
+# Set the connection into "binary" mode, a.k.a. no processing of input
+# characters.
+#
+proc remote_binary { host } {
+ return [call_remote "" binary "$host"];
+}
+
+proc remote_raw_binary { host } {
+ return [call_remote raw binary "$host"];
+}
+
+
+
+proc remote_reboot { host } {
+ clone_output "\nRebooting ${host}\n";
+ # FIXME: don't close the host connection, or all the remote
+ # procedures will fail.
+ # remote_close $host;
+ set status [call_remote "" reboot "$host"];
+ if [board_info $host exists name] {
+ set host [board_info $host name];
+ }
+ if { [info proc ${host}_init] != "" } {
+ ${host}_init $host;
+ }
+ return $status;
+}
+
+proc standard_reboot { host } {
+ return "";
+}
+#
+# Download file FILE to DEST. If the optional DESTFILE is specified,
+# that file will be used on the destination board. It returns either
+# "" (indicating that the download failed), or the name of the file on
+# the destination machine.
+#
+
+proc remote_download { dest file args } {
+ if { [llength $args] > 0 } {
+ set destfile [lindex $args 0];
+ } else {
+ set destfile [file tail $file];
+ }
+
+ if { ![is_remote $dest] } {
+ if { $destfile == "" || $destfile == $file } {
+ return $file;
+ } else {
+ set result [catch "exec cp -p $file $destfile" output];
+ if [regexp "same file|are identical" $output] {
+ set result 0
+ set output ""
+ } else {
+ # try to make sure we can read it
+ # and write it (in case we copy onto it again)
+ catch {exec chmod u+rw $destfile}
+ }
+ if { $result != 0 || $output != "" } {
+ perror "remote_download to $dest of $file to $destfile: $output"
+ return "";
+ } else {
+ return $destfile;
+ }
+ }
+ }
+
+ return [call_remote "" download $dest $file $destfile];
+}
+
+#
+# The default download procedure. Uses rcp to download to $dest.
+#
+
+proc standard_download {dest file destfile} {
+ return [rsh_download $dest $file $destfile];
+}
+
+proc remote_upload {dest srcfile args} {
+ if { [llength $args] > 0 } {
+ set destfile [lindex $args 0];
+ } else {
+ set destfile [file tail $srcfile];
+ }
+
+ if { ![is_remote $dest] } {
+ if { $destfile == "" || $srcfile == $destfile } {
+ return $srcfile;
+ }
+ set result [catch "exec cp -p $srcfile $destfile" output];
+ return $destfile;
+ }
+
+ return [call_remote "" upload $dest $srcfile $destfile];
+}
+
+proc standard_upload { dest srcfile destfile } {
+ return [rsh_upload $dest $srcfile $destfile];
+}
+
+#
+# A standard procedure to call the appropriate function. It first looks
+# for a board-specific version, then a version specific to the protocol,
+# and then finally it will call standard_$proc.
+#
+
+proc call_remote { type proc dest args } {
+ if [board_info $dest exists name] {
+ set dest [board_info $dest name];
+ }
+
+ if { $dest != "host" && $dest != "build" && $dest != "target" } {
+ if { ![board_info $dest exists name] } {
+ global board;
+
+ if [info exists board] {
+ blooie
+ }
+ load_board_description $dest;
+ }
+ }
+
+ set high_prot ""
+ if { $type != "raw" } {
+ if [board_info $dest exists protocol] {
+ set high_prot "${dest} [board_info $dest protocol]";
+ } else {
+ set high_prot "${dest} [board_info $dest generic_name]";
+ }
+ }
+
+ verbose "call_remote $type $proc $dest $args " 3
+ # Close has to be handled specially.
+ if { $proc == "close" || $proc == "open" } {
+ foreach try "$high_prot [board_info $dest connect] telnet standard" {
+ if { $try != "" } {
+ if { [info proc "${try}_${proc}"] != "" } {
+ verbose "call_remote calling ${try}_${proc}" 3
+ set result [eval ${try}_${proc} \"$dest\" $args];
+ break;
+ }
+ }
+ }
+ set ft "[board_info $dest file_transfer]"
+ if { [info proc "${ft}_${proc}"] != "" } {
+ verbose "calling ${ft}_${proc} $dest $args" 3
+ set result2 [eval ${ft}_${proc} \"$dest\" $args];
+ }
+ if ![info exists result] {
+ if [info exists result2] {
+ set result $result2;
+ } else {
+ set result "";
+ }
+ }
+ return $result;
+ }
+ foreach try "${high_prot} [board_info $dest file_transfer] [board_info $dest connect] telnet standard" {
+ verbose "looking for ${try}_${proc}" 4
+ if { $try != "" } {
+ if { [info proc "${try}_${proc}"] != "" } {
+ verbose "call_remote calling ${try}_${proc}" 3
+ return [eval ${try}_${proc} \"$dest\" $args];
+ }
+ }
+ }
+ if { $proc == "close" } {
+ return ""
+ }
+ error "No procedure for '$proc' in call_remote"
+ return -1;
+}
+
+#
+# Send FILE through the existing session established to DEST.
+#
+proc remote_transmit { dest file } {
+ return [call_remote "" transmit "$dest" "$file"];
+}
+
+proc remote_raw_transmit { dest file } {
+ return [call_remote raw transmit "$dest" "$file"];
+}
+
+#
+# The default transmit procedure if no other exists. This feeds the
+# supplied file directly into the connection.
+#
+proc standard_transmit {dest file} {
+ if [board_info ${dest} exists name] {
+ set dest [board_info ${dest} name];
+ }
+ if [board_info ${dest} exists baud] {
+ set baud [board_info ${dest} baud];
+ } else {
+ set baud 9600;
+ }
+ set shell_id [board_info ${dest} fileid];
+
+ set lines 0
+ set chars 0;
+ set fd [open $file r]
+ while { [gets $fd cur_line] >= 0 } {
+ set errmess ""
+ catch "send -i $shell_id \"$cur_line\r\"" errmess
+ if [string match "write\(spawn_id=\[0-9\]+\):" $errmess] {
+ perror "sent \"$cur_line\" got expect error \"$errmess\""
+ catch "close $fd"
+ return -1
+ }
+ set chars [expr $chars + ([string length $cur_line] * 10)]
+ if { $chars > $baud } {
+ sleep 1;
+ set chars 0
+ }
+ verbose "." 3
+ verbose "Sent $cur_line" 4
+ incr lines
+ }
+ verbose "$lines lines transmitted" 2
+ close $fd
+ return 0
+}
+
+proc remote_send { dest string } {
+ return [call_remote "" send "$dest" "$string"];
+}
+
+proc remote_raw_send { dest string } {
+ return [call_remote raw send "$dest" "$string"];
+}
+
+proc standard_send { dest string } {
+ if ![board_info $dest exists fileid] {
+ perror "no fileid for $dest"
+ return "no fileid for $dest";
+ } else {
+ set shell_id [board_info $dest fileid]
+ verbose "shell_id in standard_send is $shell_id" 3
+ verbose "send -i [board_info $dest fileid] -- {$string}" 3
+ if [catch "send -i [board_info $dest fileid] -- {$string}" errorInfo] {
+ return "$errorInfo";
+ } else {
+ return "";
+ }
+ }
+}
+
+proc file_on_host { op file args } {
+ return [eval remote_file host \"$op\" '\$file\" $args];
+}
+
+proc file_on_build { op file args } {
+ return [eval remote_file build \"$op\" \"$file\" $args];
+}
+
+proc remote_file { dest args } {
+ return [eval call_remote \"\" file \"$dest\" $args];
+}
+
+proc remote_raw_file { dest args } {
+ return [eval call_remote raw file \"$dest\" $args];
+}
+
+#
+# Perform the specified file op on a remote Unix board.
+#
+
+proc standard_file { dest op args } {
+ set file [lindex $args 0];
+ verbose "dest in standard_file is $dest";
+ if { ![is_remote $dest] } {
+ switch $op {
+ cmp {
+ set otherfile [lindex $args 1];
+ if { [file exists $file] && [file exists $otherfile]
+ && [file size $file] == [file size $otherfile] } {
+ set r [remote_exec build cmp "$file $otherfile"];
+ if { [lindex $r 0] == 0 } {
+ return 0;
+ }
+ }
+ return 1;
+ }
+ tail {
+ return [file tail $file];
+ }
+ dirname {
+ if { [file pathtype $file] == "relative" } {
+ set file [remote_file $dest absolute $file];
+ }
+ set result [file dirname $file];
+ if { $result == "" } {
+ return "/";
+ }
+ return $result;
+ }
+ join {
+ return [file join [lindex $args 0] [lindex $args 1]];
+ }
+ absolute {
+ return [unix_clean_filename $dest $file];
+ }
+ exists {
+ return [file exists $file];
+ }
+ delete {
+ foreach x $args {
+ if { [file exists $x] && [file isfile $x] } {
+ exec rm -f $x;
+ }
+ }
+ return;
+ }
+ }
+ }
+ switch $op {
+ exists {
+ # mmmm, quotes.
+ set status [remote_exec $dest "sh -c 'exit `\[ -f $file \]`'"];
+ return [lindex $status 0];
+ }
+ delete {
+ set file ""
+ # Allow multiple files to be deleted at once.
+ foreach x $args {
+ append file " $x";
+ }
+ verbose "remote_file deleting $file"
+ set status [remote_exec $dest "rm -f $file"];
+ return [lindex $status 0];
+ }
+ }
+}
+
+#
+# Return an absolute version of the filename in $file, with . and ..
+# removed.
+#
+proc unix_clean_filename { dest file } {
+ if { [file pathtype $file] == "relative" } {
+ set file [remote_file $dest join [pwd] $file];
+ }
+ set result "";
+ foreach x [split $file "/"] {
+ if { $x == "." || $x == "" } {
+ continue;
+ }
+ if { $x == ".." } {
+ set rlen [expr [llength $result] - 2];
+ if { $rlen >= 0 } {
+ set result [lrange $result 0 $rlen];
+ } else {
+ set result ""
+ }
+ continue;
+ }
+ lappend result $x;
+ }
+ return "/[join $result /]"
+}
+
+#
+# Start COMMANDLINE running on DEST. By default it is not possible to
+# redirect I/O. If the optional keyword "readonly" is specified, input
+# to the command may be redirected. If the optional keyword
+# "writeonly" is specified, output from the command may be redirected.
+#
+# If the command is successfully started, a positive "spawn id" is returned.
+# If the spawn fails, a negative value will be returned.
+#
+# Once the command is spawned, you can interact with it via the remote_expect
+# and remote_wait functions.
+#
+proc remote_spawn { dest commandline args } {
+ global board_info
+
+ if ![is_remote $dest] {
+ if [info exists board_info($dest,fileid)] {
+ unset board_info($dest,fileid);
+ }
+ verbose "remote_spawn is local" 3;
+ if [board_info $dest exists name] {
+ set dest [board_info $dest name];
+ }
+
+ verbose "spawning command $commandline"
+
+ if { [llength $args] > 0 } {
+ if { [lindex $args 0] == "readonly" } {
+ set result [catch { open "| ${commandline} |& cat" "r" } id];
+ if { $result != 0 } {
+ return -1;
+ }
+ } else {
+ set result [catch {open "| ${commandline}" "w"} id] ;
+ if { $result != 0 } {
+ return -1;
+ }
+ }
+ set result [catch "spawn -leaveopen $id" result2];
+ if { $result == 0 && $result2 == 0} {
+ verbose "setting board_info($dest,fileid) to $spawn_id" 3
+ set board_info($dest,fileid) $spawn_id;
+ set board_info($dest,fileid_origid) $id;
+ return $spawn_id;
+ } else {
+ # This shouldn't happen.
+ global errorInfo;
+ if [info exists errorInfo] {
+ set foo $errorInfo;
+ } else {
+ set foo "";
+ }
+ verbose "spawn -open $id failed, $result $result2, $foo";
+ catch "close $id";
+ return -1;
+ }
+ } else {
+ set result [catch "spawn $commandline" pid];
+ if { $result == 0 } {
+ verbose "setting board_info($dest,fileid) to $spawn_id" 3
+ set board_info($dest,fileid) $spawn_id;
+ return $spawn_id;
+ } else {
+ verbose -log "spawn of $commandline failed";
+ return -1;
+ }
+ }
+ }
+
+ # Seems to me there should be a cleaner way to do this.
+ if { "$args" == "" } {
+ return [call_remote "" spawn "$dest" "$commandline"];
+ } else {
+ return [call_remote "" spawn "$dest" "$commandline" $args];
+ }
+}
+
+proc remote_raw_spawn { dest commandline } {
+ return [call_remote raw spawn "$dest" "$commandline"];
+}
+
+#
+# The default spawn procedure. Uses rsh to connect to $dest.
+#
+proc standard_spawn { dest commandline } {
+ global board_info
+
+ if [board_info $dest exists hostname] {
+ set remote [board_info $dest hostname];
+ } else {
+ set remote $dest;
+ }
+ spawn rsh $remote $commandline;
+ set board_info($dest,fileid) $spawn_id;
+ return $spawn_id;
+}
+
+#
+# Run PROG on DEST, with optional arguments, input and output files.
+# It returns a list of two items. The first is ether "pass" if the program
+# loaded, ran and exited with a zero exit status, or "fail" otherwise.
+# The second argument is any output produced by the program while it was
+# running.
+#
+proc remote_load { dest prog args } {
+ global tool
+
+ set dname [board_info $dest name];
+ set cache "[getenv REMOTELOAD_CACHE]/$tool/$dname/[file tail $prog]";
+ set empty [is_remote $dest];
+ if { [board_info $dest exists is_simulator] || [getenv REMOTELOAD_CACHE] == "" } {
+ set empty 0;
+ } else {
+ for { set x 0; } {$x < [llength $args] } {incr x} {
+ if { [lindex $args $x] != "" } {
+ set empty 0;
+ break;
+ }
+ }
+ }
+ if $empty {
+ global sum_program;
+
+ if [info exists sum_program] {
+ if ![target_info exists objcopy] {
+ set_currtarget_info objcopy [find_binutils_prog objcopy];
+ }
+ if [is_remote host] {
+ set dprog [remote_download host $prog "a.out"];
+ } else {
+ set dprog $prog;
+ }
+ set status [remote_exec host "[target_info objcopy]" "-O srec $dprog ${dprog}.sum"];
+ if [is_remote host] {
+ remote_file upload ${dprog}.sum ${prog}.sum;
+ }
+ if { [lindex $status 0] == 0 } {
+ set sumout [remote_exec build "$sum_program" "${prog}.sum"];
+ set sum [lindex $sumout 1];
+ regsub "\[\r\n \t\]+$" "$sum" "" sum;
+ } else {
+ set sumout [remote_exec build "$sum_program" "${prog}"];
+ set sum [lindex $sumout 1];
+ regsub "\[\r\n \t\]+$" "$sum" "" sum;
+ }
+ remote_file build delete ${prog}.sum;
+ }
+ if [file exists $cache] {
+ set same 0;
+ if [info exists sum_program] {
+ set id [open $cache "r"];
+ set oldsum [read $id];
+ close $id;
+ if { $oldsum == $sum } {
+ set same 1;
+ }
+ } else {
+ if { [remote_file build cmp $prog $cache] == 0 } {
+ set same 1;
+ }
+ }
+ if { $same } {
+ set fd [open "${cache}.res" "r"];
+ gets $fd l1;
+ set result [list $l1 [read $fd]];
+ close $fd;
+ }
+ }
+ }
+ if ![info exists result] {
+ set result [eval call_remote \"\" load \"$dname\" \"$prog\" $args];
+ # Not quite happy about the "pass" condition, but it makes sense if
+ # you think about it for a while-- *why* did the test not pass?
+ if { $empty && [lindex $result 0] == "pass" } {
+ if { [getenv LOAD_REMOTECACHE] != "" } {
+ set dir "[getenv REMOTELOAD_CACHE]/$tool/$dname"
+ if ![file exists $dir] {
+ file mkdir $dir
+ }
+ if [file exists $dir] {
+ if [info exists sum_program] {
+ set id [open $cache "w"];
+ puts -nonewline $id "$sum";
+ close $id;
+ } else {
+ remote_exec build cp "$prog $cache";
+ }
+ set id [open "${cache}.res" "w"];
+ puts $id [lindex $result 0];
+ puts -nonewline $id [lindex $result 1];
+ close $id;
+ }
+ }
+ }
+ }
+ return $result;
+}
+
+proc remote_raw_load { dest prog args } {
+ return [eval call_remote raw load \"$dest\" \"$prog\" $args ];
+}
+
+#
+# The default load procedure if no other exists for $dest. It uses
+# remote_download and remote_exec to load and execute the program.
+#
+
+proc standard_load { dest prog args } {
+ if { [llength $args] > 0 } {
+ set pargs [lindex $args 0];
+ } else {
+ set pargs ""
+ }
+
+ if { [llength $args] > 1 } {
+ set inp "[lindex $args 1]";
+ } else {
+ set inp ""
+ }
+
+ if ![file exists $prog] then {
+ # We call both here because this should never happen.
+ perror "$prog does not exist in standard_load."
+ verbose -log "$prog does not exist." 3
+ return "untested"
+ }
+
+ if [is_remote $dest] {
+ set remotefile "/tmp/[file tail $prog].[pid]"
+ set remotefile [remote_download $dest $prog $remotefile];
+ if { $remotefile == "" } {
+ verbose -log "Download of $prog to [board_info $dest name] failed." 3
+ return "unresolved"
+ }
+ if [board_info $dest exists remote_link] {
+ if [[board_info $dest remote_link] $remotefile] {
+ verbose -log "Couldn't do remote link"
+ remote_file target delete $remotefile
+ return "unresolved"
+ }
+ }
+ set status [remote_exec $dest $remotefile $pargs $inp];
+ remote_file $dest delete $remotefile;
+ } else {
+ set status [remote_exec $dest $prog $pargs $inp];
+ }
+ if { [lindex $status 0] < 0 } {
+ verbose -log "Couldn't execute $prog, [lindex $status 1]" 3
+ return "unresolved"
+ }
+ set output [lindex $status 1]
+ set status [lindex $status 0]
+
+ verbose -log "Executed $prog, status $status" 2
+ if ![string match "" $output] {
+ verbose -log -- "$output" 2
+ }
+ if { $status == 0 } {
+ return [list "pass" $output];
+ } else {
+ return [list "fail" $output];
+ }
+}
+
+#
+# Loads PROG into DEST.
+#
+proc remote_ld { dest prog } {
+ return [eval call_remote \"\" ld \"$dest\" \"$prog\"];
+}
+
+proc remote_raw_ld { dest prog } {
+ return [eval call_remote raw ld \"$dest\" \"$prog\"];
+}
+
+# Wait up to TIMEOUT seconds for the last spawned command on DEST to
+# complete. A list of two values is returned; the first is the exit
+# status (-1 if the program timed out), and the second is any output
+# produced by the command.
+
+proc remote_wait { dest timeout } {
+ return [eval call_remote \"\" wait \"$dest\" $timeout];
+}
+
+proc remote_raw_wait { dest timeout } {
+ return [eval call_remote raw wait \"$dest\" $timeout];
+}
+
+# The standard wait procedure, used for commands spawned on the local
+# machine.
+proc standard_wait { dest timeout } {
+ set output "";
+ set status -1;
+
+ if [info exists exp_close_result] {
+ unset exp_close_result;
+ }
+ remote_expect $dest $timeout {
+ -re ".+" {
+ append output $expect_out(buffer);
+ if { [string length $output] > 512000 } {
+ remote_close $dest;
+ set status 1;
+ } else {
+ exp_continue -continue_timer;
+ }
+ }
+ timeout {
+ warning "program timed out.";
+ }
+ eof {
+ if [board_info $dest exists fileid_origid] {
+ global board_info;
+
+ set id [board_info $dest fileid];
+ set oid [board_info $dest fileid_origid];
+ verbose "$id $oid"
+ unset board_info($dest,fileid);
+ unset board_info($dest,fileid_origid);
+ catch "close -i $id";
+ # I don't believe this. You HAVE to do a wait, even tho
+ # it won't work! stupid ()*$%*)(% expect...
+ catch "wait -i $id";
+ set r2 [catch "close $oid" res];
+ if { $r2 != 0 } {
+ verbose "close result is $res";
+ set status 1;
+ } else {
+ set status 0;
+ }
+ } else {
+ set s [wait -i [board_info $dest fileid]];
+ if { [lindex $s 0] != 0 && [lindex $s 2] == 0 } {
+ set status [lindex $s 3];
+ if { [llength $s] > 4 } {
+ if { [lindex $s 4] == "CHILDKILLED" } {
+ set status 1;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ remote_close $dest;
+ return [list $status $output];
+}
+
+# This checks the value cotained in the variable named "variable" in
+# the calling procedure for output from the status wrapper and returns
+# a non-negative value if it exists; otherwise, it returns -1. The
+# output from the wrapper is removed from the variable.
+
+proc check_for_board_status { variable } {
+ upvar $variable output;
+
+ if [regexp "(^|\[\r\n\])\\*\\*\\* EXIT code" $output] {
+ regsub "^.*\\*\\*\\* EXIT code " $output "" result;
+ regsub "\[\r\n\].*$" $result "" result;
+ regsub -all "(^|\[\r\n\])\\*\\*\\* EXIT code \[^\r\n\]*(\[\r\n\]\[\r\n\]?|$)" $output "" output;
+ regsub "^\[^0-9\]*" $result "" result
+ regsub "\[^0-9\]*$" $result "" result
+ verbose "got board status $result" 3
+ verbose "output is $output" 3
+ if { $result == "" } {
+ return -1;
+ } else {
+ return [expr $result];
+ }
+ } else {
+ return -1;
+ }
+}
+
+#
+# remote_expect works basically the same as standard expect, but it
+# also takes care of getting the file descriptor from the specified
+# host and also calling the timeout/eof/default section if there is an
+# error on the expect call.
+#
+
+proc remote_expect { board timeout args } {
+ global errorInfo errorCode;
+ global remote_suppress_flag;
+
+ set spawn_id [board_info $board fileid];
+
+ if { [llength $args] == 1 } {
+ set args "[lindex $args 0]";
+ }
+
+ set res {}
+ set got_re 0;
+ set need_append 1;
+
+ set orig "$args";
+
+ set error_sect "";
+ set save_next 0;
+
+ if { $spawn_id == "" } {
+ # This should be an invalid spawn id.
+ set spawn_id 1000;
+ }
+
+ for { set i 0; } { $i < [llength $args] } { incr i ; } {
+ if { $need_append } {
+ append res "\n-i $spawn_id ";
+ set need_append 0;
+ }
+
+ set x "[lrange $args $i $i]";
+ regsub "^\n*\[ \]*" "$x" "" x;
+
+ if { $x == "-i" || $x == "-timeout" || $x == "-ex" } {
+ append res "$x ";
+ set next [expr ${i}+1];
+ append res "[lrange $args $next $next]";
+ incr i;
+ continue;
+ }
+ if { $x == "-n" || $x == "-notransfer" || $x == "-nocase" || $x == "-indices" } {
+ append res "${x} ";
+ continue;
+ }
+ if { $x == "-re" } {
+ append res "${x} ";
+ set next [expr ${i}+1];
+ set y [lrange $args $next $next];
+ append res "${y} ";
+ set got_re 1;
+ incr i;
+ continue;
+ }
+ if { $got_re } {
+ set need_append 0;
+ append res "$x ";
+ set got_re 0;
+ if { $save_next } {
+ set save_next 0;
+ set error_sect [lindex $args $i];
+ }
+ } else {
+ if { ${x} == "eof" } {
+ set save_next 1;
+ } elseif { ${x} == "default" || ${x} == "timeout" } {
+ if { $error_sect == "" } {
+ set save_next 1;
+ }
+ }
+ append res "${x} ";
+ set got_re 1;
+ }
+ }
+
+ if [info exists remote_suppress_flag] {
+ if { $remote_suppress_flag } {
+ set code 1;
+ }
+ }
+ if ![info exists code] {
+ set res "\n-timeout $timeout $res";
+ set body "expect \{\n-i $spawn_id -timeout $timeout $orig\}";
+ set code [catch {uplevel $body} string];
+ }
+
+ if {$code == 1} {
+ if { $error_sect != "" } {
+ set code [catch {uplevel $error_sect} string];
+ } else {
+ warning "remote_expect statement without a default case?!";
+ return;
+ }
+ }
+
+ if {$code == 1} {
+ return -code error -errorinfo $errorInfo -errorcode $errorCode $string
+ } elseif {$code == 2} {
+ return -code return $string
+ } elseif {$code == 3} {
+ return
+ } elseif {$code > 4} {
+ return -code $code $string
+ }
+}
+
+# Push the current connection to HOST onto a stack.
+proc remote_push_conn { host } {
+ global board_info;
+
+ set name [board_info $host name];
+
+ if { $name == "" } {
+ return "fail";
+ }
+
+ if ![board_info $host exists fileid] {
+ return "fail";
+ }
+
+ set fileid [board_info $host fileid];
+ set conninfo [board_info $host conninfo];
+ if ![info exists board_info($name,fileid_stack)] {
+ set board_info($name,fileid_stack) {}
+ }
+ set board_info($name,fileid_stack) [list $fileid $conninfo $board_info($name,fileid_stack)];
+ unset board_info($name,fileid);
+ if [info exists board_info($name,conninfo)] {
+ unset board_info($name,conninfo);
+ }
+ return "pass";
+}
+
+# Pop a previously-pushed connection from a stack. You should have closed the
+# current connection before doing this.
+proc remote_pop_conn { host } {
+ global board_info;
+
+ set name [board_info $host name];
+
+ if { $name == "" } {
+ return "fail";
+ }
+ if ![info exists board_info($name,fileid_stack)] {
+ return "fail";
+ }
+ set stack $board_info($name,fileid_stack);
+ if { [llength $stack] < 3 } {
+ return "fail";
+ }
+ set board_info($name,fileid) [lindex $stack 0];
+ set board_info($name,conninfo) [lindex $stack 1];
+ set board_info($name,fileid_stack) [lindex $stack 2];
+ return "pass";
+}
+
+#
+# Swap the current connection with the topmost one on the stack.
+#
+proc remote_swap_conn { host } {
+ global board_info;
+ set name [board_info $host name];
+
+ if ![info exists board_info($name,fileid)] {
+ return "fail";
+ }
+
+ set fileid $board_info($name,fileid);
+ if [info exists board_info($name,conninfo)] {
+ set conninfo $board_info($name,conninfo);
+ } else {
+ set conninfo {}
+ }
+ if { [remote_pop_conn $host] != "pass" } {
+ set board_info($name,fileid) $fileid;
+ set board_info($name,conninfo) $conninfo;
+ return "fail";
+ }
+ set newfileid $board_info($name,fileid);
+ set newconninfo $board_info($name,conninfo);
+ set board_info($name,fileid) $fileid;
+ set board_info($name,conninfo) $conninfo;
+ remote_push_conn $host;
+ set board_info($name,fileid) $newfileid;
+ set board_info($name,conninfo) $newconninfo;
+ return "pass";
+}
+
+set sum_program "testcsum";
diff --git a/dejagnu/lib/rlogin.exp b/dejagnu/lib/rlogin.exp
new file mode 100644
index 00000000000..78745ba04a0
--- /dev/null
+++ b/dejagnu/lib/rlogin.exp
@@ -0,0 +1,173 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+#
+# Connect to ARG using rlogin. This is for systems using rlogin to
+# braindead targets. It returns either the spawn_id or a -1.
+#
+
+proc rlogin_open { arg } {
+ global board_info
+
+ set tries 0
+ set result -1
+
+ if [board_info $arg exists fileid] {
+ return [board_info $arg fileid];
+ }
+
+ # get the hostname and port number from the config array
+ if [board_info $arg exists netport] {
+ set hostname [lindex [split [board_info $arg netport] ":"] 0]
+ } else {
+ set hostname $arg
+ }
+
+ if ![board_info $arg exists shell_prompt] {
+ # if no prompt, then set it to something generic
+ set shell_prompt ".*> "
+ } else {
+ set shell_prompt [board_info $arg shell_prompt]
+ }
+
+ if [board_info $arg exists fileid] {
+ unset board_info($arg,fileid);
+ }
+ # get the right version of rlogin
+ if ![board_info $arg exists rlogin_prog] {
+ set RLOGIN rlogin
+ } else {
+ set RLOGIN [board_info $arg rlogin_prog];
+ }
+
+ # start connection and store the spawn_id
+ verbose "Opening a $RLOGIN connection to $hostname" 2
+ spawn $RLOGIN $hostname
+ if { $spawn_id < 0 } {
+ perror "invalid spawn id from rlogin"
+ return
+ }
+ set board_info($arg,fileid) $spawn_id
+
+ # Try to connect to the target. We give up after 3 attempts.
+ while { $tries <= 3 } {
+ expect {
+ -re ".*$shell_prompt.*$" {
+ verbose "Got prompt\n"
+ set result 0
+ break
+ }
+ -re "TERM = .*\\)\[ ]*$" {
+ send "dumb\r\n"
+ expect {
+ "Terminal type is*$" {
+ verbose "rlogin: set the terminal to dumb" 2
+ }
+ default {
+ warning "rlogin: couldn't set terminmal type"
+ }
+ }
+ set result 10
+ break
+ }
+ "unknown host" {
+ perror "rlogin: unknown host"
+ break
+ }
+ "has logged on from" {
+ exp_continue
+ }
+ "Terminal type is" {
+ verbose "rlogin: connected, got terminal prompt" 2
+ set result 0
+ break
+ }
+ -re "Maximum number of users already logged in.*$" {
+ warning "rlogin: maximum number of users already logged in"
+ }
+ -re "Sorry, shell is locked.*Connection closed.*$" {
+ warning "rlogin: lready connected."
+ }
+ -re "Sorry, this system is engaged.*Connection closed.*$" {
+ warning "rlogin: system engaged."
+ }
+ timeout {
+ warning "rlogin: timed out trying to connect."
+ }
+ eof {
+ perror "rlogin: got EOF while trying to connect."
+ break
+ }
+ }
+ incr tries
+ }
+
+ # see if we maxed out on errors
+ if { $result < 0 } {
+ catch "close -i $spawn_id"
+ catch "wait -i $spawn_id"
+ set spawn_id -1
+ } else {
+ verbose "rlogin: connected to $hostname" 2
+ }
+
+ return $spawn_id
+}
+
+#
+# Start CMDLINE running on DEST. Return the shell_id associated with
+# the command.
+#
+proc rlogin_spawn { dest cmdline } {
+ if ![board_info $dest exists shell_prompt] {
+ set shell_prompt "(^|\[\r\n\])\[^\r\n\]*>";
+ } else {
+ set shell_prompt [board_info $dest shell_prompt];
+ }
+ set prefix ""
+ set ok 0;
+ for {set i 0;} {$i <= 2 && ! $ok} {incr i;} {
+ set shell_id [remote_open $dest];
+ if { $shell_id != "" && $shell_id > 0 } {
+ remote_send $dest "echo k\r";
+ remote_expect $dest 20 {
+ -re "\\(gdb\\)" {
+ set shell_prompt "\\(gdb\\)";
+ # gdb uses 'shell command'.
+ set prefix "shell ";
+ set ok 1;
+ }
+ -re ".*$shell_prompt" {
+ set ok 1;
+ }
+ default { }
+ }
+ }
+ if { ! $ok } {
+ remote_close $dest;
+ remote_reboot $dest;
+ }
+ }
+ if { ! $ok } {
+ return "unable to start command"
+ } else {
+ remote_send $dest "${prefix}${cmdline}\n";
+ return [board_info $dest fileid];
+ }
+}
diff --git a/dejagnu/lib/rsh.exp b/dejagnu/lib/rsh.exp
new file mode 100644
index 00000000000..b099fd5e541
--- /dev/null
+++ b/dejagnu/lib/rsh.exp
@@ -0,0 +1,258 @@
+# Copyright (C) 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+#
+# Connect to hostname using rlogin
+#
+proc rsh_open { hostname } {
+ global spawn_id
+
+ set tries 0
+ set result -1
+
+ # get the hostname and port number from the config array
+ if [board_info $hostname exists name] {
+ set hostname [board_info $hostname name];
+ }
+ set hostname [lindex [split [board_info ${hostname} netport] ":"] 0]
+ if [board_info ${hostname} exists shell_prompt] {
+ set shell_prompt [board_info ${hostname} shell_prompt]
+ } else {
+ set shell_prompt ".*> "
+ }
+
+ if [board_info $hostname exists fileid] {
+ unset board_info($hostname,fileid);
+ }
+
+ if ![board_info $hostname exists rsh_prog] {
+ if { [which remsh] != 0 } {
+ set RSH remsh
+ } else {
+ set RSH rsh
+ }
+ } else {
+ set RSH [board_info $hostname rsh_prog];
+ }
+
+ spawn $RSH $hostname
+ if { $spawn_id < 0 } {
+ perror "invalid spawn id from rsh"
+ return -1
+ }
+
+ send "\r\n"
+ while { $tries <= 3 } {
+ expect {
+ -re ".*$shell_prompt.*$" {
+ verbose "Got prompt\n"
+ set result 0
+ break
+ }
+ -re "TERM = .*$" {
+ warning "Setting terminal type to vt100"
+ set result 0
+ send "vt100\n"
+ break
+ }
+ "unknown host" {
+ exp_send "\003"
+ perror "telnet: unknown host"
+ break
+ }
+ "has logged on from" {
+ exp_continue
+ }
+ -re "isn't registered for Kerberos.*service.*$" {
+ warning "rsh: isn't registered for Kerberos, please kinit"
+ catch close
+ catch wait
+ break
+ }
+ -re "Kerberos rcmd failed.*$" {
+ warning "rsh: Kerberos rcmd failed, please kinit"
+ catch close
+ catch wait
+ break
+ }
+ -re "You have no Kerberos tickets.*$" {
+ warning "rsh: No kerberos Tickets, please kinit"
+ catch close
+ catch wait
+ break
+ }
+ "Terminal type is" {
+ verbose "rsh: connected, got terminal prompt" 2
+ set result 0
+ break
+ }
+ -re "trying normal rlogin.*$" {
+ warning "rsh: trying normal rlogin."
+ catch close
+ catch wait
+ break
+ }
+ -re "unencrypted connection.*$" {
+ warning "rsh: unencrypted connection, please kinit"
+ catch close
+ catch wait
+ break
+ }
+ -re "Sorry, shell is locked.*Connection closed.*$" {
+ warning "rsh: already connected."
+ }
+ timeout {
+ warning "rsh: timed out trying to connect."
+ }
+ eof {
+ perror "rsh: got EOF while trying to connect."
+ break
+ }
+ }
+ incr tries
+ }
+
+ if { $result < 0 } {
+# perror "rsh: couldn't connect after $tries tries."
+ close -i $spawn_id
+ set spawn_id -1
+ } else {
+ set board_info($hostname,fileid) $spawn_id
+ }
+
+ return $spawn_id
+}
+
+#
+# Download $srcfile to $destfile on $desthost.
+#
+
+proc rsh_download {desthost srcfile destfile} {
+ if [board_info $desthost exists name] {
+ set desthost [board_info $desthost name];
+ }
+
+ if [board_info $desthost exists hostname] {
+ set desthost [board_info $desthost hostname];
+ }
+
+ if ![board_info $desthost exists rcp_prog] {
+ set RCP rcp
+ } else {
+ set RCP [board_info $desthost rcp_prog];
+ }
+
+ set status [catch "exec $RCP $srcfile $desthost:$destfile |& cat" output]
+ if { $status == 0 } {
+ verbose "Copied $srcfile to $desthost:$destfile" 2
+ return $destfile;
+ } else {
+ verbose "Download to $desthost failed, $output."
+ return ""
+ }
+}
+
+proc rsh_upload {desthost srcfile destfile} {
+ if [board_info $desthost exists name] {
+ set desthost [board_info $desthost name];
+ }
+
+ if [board_info $desthost exists hostname] {
+ set desthost [board_info $desthost hostname];
+ }
+
+ if ![board_info $desthost exists rcp_prog] {
+ set RCP rcp
+ } else {
+ set RCP [board_info $desthost rcp_prog];
+ }
+
+ set status [catch "exec $RCP $desthost:$srcfile $destfile" output];
+ if { $status == 0 } {
+ verbose "Copied $desthost:$srcfile to $destfile" 2
+ return $destfile;
+ } else {
+ verbose "Upload from $desthost failed, $output."
+ return ""
+ }
+}
+
+#
+# Execute "$cmd $args[0]" on $boardname.
+#
+proc rsh_exec { boardname cmd args } {
+ if { [llength $args] > 0 } {
+ set pargs [lindex $args 0];
+ if { [llength $args] > 1 } {
+ set inp [lindex $args 1];
+ } else {
+ set inp "";
+ }
+ } else {
+ set pargs ""
+ set inp ""
+ }
+
+ verbose "Executing $boardname:$cmd $pargs < $inp"
+
+ if [board_info $boardname exists name] {
+ set boardname [board_info $boardname name];
+ }
+
+ if [board_info $boardname exists hostname] {
+ set hostname [board_info $boardname hostname];
+ } else {
+ set hostname $boardname;
+ }
+
+ if ![board_info $hostname exists rsh_prog] {
+ if { [which remsh] != 0 } {
+ set RSH remsh
+ } else {
+ set RSH rsh
+ }
+ } else {
+ set RSH [board_info $hostname rsh_prog];
+ }
+
+ # If CMD sends any output to stderr, exec will think it failed. More often
+ # than not that will be true, but it doesn't catch the case where there is
+ # no output but the exit code is non-zero.
+ if { $inp == "" } {
+ set inp "/dev/null"
+ }
+ set status [catch "exec cat $inp | $RSH $boardname sh -c '$cmd $pargs \\; echo XYZ\\\${?}ZYX' |& cat" output]
+ verbose "rsh output is $output"
+ # `status' doesn't mean much here other than rsh worked ok.
+ # What we want is whether $cmd ran ok.
+ if { $status != 0 } {
+ regsub "XYZ(\[0-9\]*)ZYX\n?" $output "" output
+ return [list -1 "rsh to $boardname failed for $cmd, $output"]
+ }
+ regexp "XYZ(\[0-9\]*)ZYX" $output junk status
+ verbose "rsh_exec: status:$status text:$output" 4
+ if { $status == "" } {
+ return [list -1 "Couldn't parse rsh output, $output."]
+ }
+ regsub "XYZ(\[0-9\]*)ZYX\n?" $output "" output
+ # Delete one trailing \n because that is what `exec' will do and we want
+ # to behave identical to it.
+ regsub "\n$" $output "" output
+ return [list [expr $status != 0] $output]
+}
diff --git a/dejagnu/lib/standard.exp b/dejagnu/lib/standard.exp
new file mode 100644
index 00000000000..f1822e4eeda
--- /dev/null
+++ b/dejagnu/lib/standard.exp
@@ -0,0 +1,42 @@
+# Copyright (C) 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+#
+# A set of standard functions for tools. Calls the
+# target-machine-specific versions.
+#
+
+proc ${tool}_load { program args } {
+ if { [llength $args] > 0 } {
+ set program_args [lindex $args 0];
+ } else {
+ set program_args ""
+ }
+
+ if { [llength $args] > 1 } {
+ set input_file [lindex $args 1];
+ } else {
+ set input_file "";
+ }
+ return [remote_load target $program $program_args $input_file];
+}
+
+proc ${tool}_compile { srcfile destfile compile_type options } {
+ target_compile $srcfile $destfile $compile_type $options
+}
diff --git a/dejagnu/lib/target.exp b/dejagnu/lib/target.exp
new file mode 100644
index 00000000000..1671a076566
--- /dev/null
+++ b/dejagnu/lib/target.exp
@@ -0,0 +1,789 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+# and extensively modified by Bob Manson. (manson@cygnus.com)
+
+# a hairy pattern to recognize text
+set text "\[- A-Za-z0-9\.\;\"\_\:\'\`\(\)\!\#\=\+\?\&\*]"
+
+#
+# this is a collection of support procs for the target data
+# structures. We use a named array, since Tcl has no real data
+# structures. Here's the special index words for the array:
+# Required fields are:
+# name - the name of the target. (mostly for error messages) This
+# should also be the string used for this target's array.
+# It should also be the same as the linker script so we
+# can find them dynamically.
+# Optional fields are:
+# ldflags - the flags required to produce a fully linked executable.
+# config - the target canonical for this target. This is a regexp
+# as passed to istarget or isnative.
+# cflags - the flags required to produce an object file from a
+# source file.
+# connect - the connectmode for this target. This is for both IP and
+# serial connections.
+# hostname - the hostname of the target. This is for TCP/IP based
+# connections, and is also used for versions of tip that
+# use /etc/remote.
+# serial - the serial port. This is typically /dev/tty? or com?:.
+# baud - the baud rate for a serial port connection.
+# netport - the IP port.
+# x10 - parameters for the x10 controller (used to reboot)
+# fileid - the fileid or spawn id of of the connection.
+# prompt - a regexp for matching the prompt.
+# ioport - the port for I/O on dual port systems.
+#
+# there are three main arrays, indexed in with "target", "build", and "host".
+# all other targets are indexed with a name usually based on the linker script
+# like "idp", or "ex93x.ld".
+#
+
+#
+# Set the target connection.
+#
+proc push_target { name } {
+ global target_abbrev
+
+ pop_config target
+ push_config target $name
+}
+
+#
+# Set the host connnection.
+#
+proc push_host { name } {
+ pop_config host
+ push_config host $name
+}
+
+#
+# Set the build connnection.
+#
+proc push_build { name } {
+ pop_config build
+ push_config build $name
+}
+
+#
+# Set the config for the current host or target connection.
+#
+proc push_config { type name } {
+ global target_info
+
+ verbose "pushing config for $type, name is $name"
+ if [info exists target_info($type,name)] {
+ if { $target_info($type,name) == $name } {
+ error "pushing config for $type, '$name' twice"
+ }
+ }
+ set target_info($type,name) $name
+}
+
+#
+# Set the current connection for target or host.
+#
+proc pop_config { type } {
+ global target_info
+
+ if [info exists target_info(${type},name)] {
+ unset target_info(${type},name)
+ }
+}
+
+#
+# Unset the target connection.
+#
+proc pop_target { } {
+ pop_config target
+}
+
+#
+# Unset the host connection.
+#
+proc pop_host { } {
+ pop_config host
+}
+
+#
+# Remove extraneous warnings we don't care about
+#
+proc prune_warnings { text } {
+ global host_triplet;
+
+ # remove the \r part of "\r\n" so we don't break all the patterns
+ # we want to match.
+ regsub -all -- "\r" $text "" text
+
+ # This is from sun4's. Do it for all machines for now.
+ # The "\\1" is to try to preserve a "\n" but only if necessary.
+ if [ishost "sparc-*-sunos*"] {
+ regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
+ }
+
+ # See Brendan for the raison d'etre of this one.
+ if [ishost "alpha*-*-*"] {
+ regsub -all "(^|\n)(/usr/(ucb|bin)/ld.*without exceptions was\[^\n\]+\n?)" $text "\\1" text
+ }
+ if [ishost "hppa*-*-hpux*"] {
+ # Ignore the compiler's warnings about PA incompatibility.
+ regsub -all "(^|\n)\[^\n\]*PA 2.0 object file \[^\n\]* was detected. The linked output may not run on a PA 1.x system." $text "" text
+
+ regsub -all "(^|\n)\[^\n\]*PA 2.0 object file \[^\n\]* was detected. The linked output may not run on a PA 1.x system." $text "" text
+
+ # And the linker's +vcompatwarnings verbage.
+ regsub -all "(^|\n)\[^\n\]*Linker features were used that may not be supported\[^\n\]*.\[^\n\]*." $text "" text
+
+ # Ignore these warnings, which the HP aCC compiler seems to
+ # generate on HP-UX 10.30 and 11.0. (Something is probably
+ # wrong with some system headers, but still...)
+ #
+ # This particular warning always is given with a line of warning
+ # text, followed by a source line, followed by a line with "^^^"
+ # underlining an offending symbol name. Here we slurp up the
+ # warning text and the next two lines, assuming that they are
+ # the source line and underline chars.
+ #
+ regsub -all "Warning .*The linkage directive is ignored for an object or function declared static..\[^\n\]*.\[^\n\]*." $text "" text
+
+ # Ignore these warnings, which I often see from the ANSI C
+ # compiler installed on HP-UX 11.0 machines. (Something is
+ # probably wrong with an installation, or perhaps NLS isn't
+ # quite healthy yet on 11.0. In either case, it's easier to
+ # "fix" this nit here, than it is to track down & fix the
+ # root cause.)
+ #
+ # This particular warning always is given with a line of warning
+ # text, followed by line that says "Using internal messages".
+ #
+ regsub -all "Warning: Unable to open pxdb message catalog.*" $text "" text
+ regsub -all ".* Using internal messages.*" $text "" text
+
+ # Another form of the "unable to find message catalog" warning.
+ #
+ regsub -all "cpp: warning .*Possibly incorrect message catalog." $text "" text
+
+ # Another odd warning on 11.0.
+ #
+ regsub -all "aCC .assigner.: Warning .*Could not find library for -l.*" $text "" text
+
+ # Oh heck, just keep adding 'em here...
+ #
+ regsub -all "aCC .assigner.: Warning .*Could not satisfy instantiation request for \[^\n\]* contained in\[^\n\]*\n\t/lib/pa20_64/lib\[a-zA-Z0-9\]*.sl" $text "" text
+
+ # Remove the lines that are output by the HP F77 compiler to
+ # indicate the functions that are being compiled.
+ upvar compiler_type compiler_type
+ if { [info exists compiler_type] && $compiler_type == "f77" } {
+ regsub -all "\[ \ta-zA-Z_0-9\./\]*:\[\r\n\]+" $text "" text
+ }
+
+ # Ignore the warnings about unknown options
+ regsub -all ".*warning \[0-9\]+: Unknown option.*ignored.*" $text "" text
+
+ }
+
+ # Ignore these.
+ regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text
+ regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text
+
+ # This is from sun4's. Do it for all machines for now.
+ # The "\\1" is to try to preserve a "\n" but only if necessary.
+ regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
+
+ # This happens when compiling on Alpha OSF/1 with cc -g -O.
+ regsub -all "(^|\n)(\n*uopt: Warning: file not optimized; use -g3 if both optimization and debug wanted\n?)+" $text "\\1" text
+
+ # This happens when compiling on Alpha OSF using gas.
+ regsub -all "(^|\n)(/usr/.*/ld:\nWarning: Linking some objects which contain exception information sections\n\tand some which do not. This may cause fatal runtime exception handling\n\tproblems\[^\n\]*\n?)+" $text "\\1" text
+
+ # This happens on SunOS with cc -g -O.
+ regsub -all "(^|\n)(cc: Warning: -O conflicts with -g. -O turned off.\n?)+" $text "\\1" text
+
+ # This happens when assembling code with the native HP assembler
+ regsub -all "(^|\n)(as:\[^\n\]*err#13.\n .warning.\[^\n\]*\n?)+" $text "\\1" text
+
+ # When using the HP assembler, -g isn't supported.
+ regsub -all "(^|\n)(cc1: warning: -g is only supported when using GAS on this processor\[^\n\]*\ncc1: warning:\[^\n\]*\n?)+" $text "\\1" text
+ regsub -all "(^|\n)(cc1plus: warning: -g is only supported when using GAS on this processor\[^\n\]*\ncc1plus: warning:\[^\n\]*\n?)+" $text "\\1" text
+
+ # This happens when testing across NFS.
+ regsub -all "(^|\n)(NFS server \[^\n\]* not responding still trying\[^\n\]*\n?)+" $text "\\1" text
+ regsub -all "(^|\n)(NFS server \[^\n\]* ok\[^\n\]*\n?)+" $text "\\1" text
+
+ # This happens when testing across NFS on osf4.
+ regsub -all "(^|\n)(NFS3 server \[^\n\]* not responding still trying\[^\n\]*\n?)+" $text "\\1" text
+ regsub -all "(^|\n)(NFS3 server \[^\n\]* ok\[^\n\]*\n?)+" $text "\\1" text
+
+ # When using the IRIX 6 o32 assembler, -g isn't supported
+ regsub -all "(^|\n)(cc1: warning: `-g' not supported by this configuration of GCC\[^\n\]*\n?)+" $text "\\1" text
+ regsub -all "(^|\n)(cc1plus: warning: `-g' not supported by this configuration of GCC\[^\n\]*\n?)+" $text "\\1" text
+
+ regsub -all "(^|\n)(cc1: warning: -mabi=32 does not support -g\[^\n\]*\n?)+" $text "\\1" text
+ regsub -all "(^|\n)(cc1plus: warning: -mabi=32 does not support -g\[^\n\]*\n?)+" $text "\\1" text
+
+ # This happens with the o32 assembler on IRIX 6.
+ regsub -all "(^|\n)(as: Warning: -O3 is not supported for assembly compiles for ucode compilers; changing to -O2.\n?)+" $text "\\1" text
+
+ # This happens when using g++ on a DWARF system.
+ regsub -all "(^|\n)(cc1plus: warning: -g option not supported for C\\+\\+ on systems using the DWARF debugging format\n?)+" $text "\\1" text
+
+ # This is from sun4's. Do it for all machines for now.
+ # The "\\1" is to try to preserve a "\n" but only if necessary.
+ regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
+
+ # See Brendan for the raison d'etre of this one.
+ if [string match "alpha*-*-*" $host_triplet] {
+ regsub -all "(^|\n)(/usr/(ucb|bin)/ld.*without exceptions was\[^\n\]+\n?)" $text "\\1" text
+ }
+
+ # Don't pay attention to the AIX4 linker warnings.
+ regsub -all "(^|\n)(ld:.*WARNING: Duplicate.*ld:.*Use the -bload\[^\n\]*\n?)" $text "\\1" text
+
+ # Or the IRIX 6 ones.
+ regsub -all "(^|\n)(ld(|32|64): WARNING \[^\n\]*\n?)+" $text "\\1" text
+ regsub -all "(^|\n)(ld(|32|64): Giving up.*Use -wall\[^\n\]*\n?)+" $text "\\1" text
+
+ # It might be tempting to get carried away and delete blank lines, etc.
+ # Just delete *exactly* what we're ask to, and that's it.
+ return $text
+}
+
+#
+# Invoke the compiler. This gets interesting cause the compiler may
+# not be on the same machine we're running DejaGnu on.
+#
+
+proc target_compile {source destfile type options} {
+ set target [target_info name];
+ if { [info proc ${target}_compile] != "" } {
+ return [${target}_compile $source $destfile $type $options];
+ } else {
+ return [default_target_compile $source $destfile $type $options];
+ }
+}
+
+proc default_target_compile {source destfile type options} {
+ global target_triplet
+ global tool_root_dir
+ global env
+ global CFLAGS_FOR_TARGET
+ global compiler_flags
+
+ if { $destfile == "" && $type != "preprocess" && $type != "none" } {
+ error "Must supply an output filename for the compile to default_target_compile"
+ }
+
+ set add_flags ""
+ set libs ""
+ set compiler_type "c"
+ set compiler ""
+ set ldflags ""
+ set dest [target_info name]
+
+ if [info exists CFLAGS_FOR_TARGET] {
+ append add_flags " $CFLAGS_FOR_TARGET"
+# The top level Makefile sets (and exports) a *FLAGS_FOR_TARGET
+# that may not be applicable to testsuite runs. This conflict
+# needs to be resolved.
+# } elseif [info exists env(CFLAGS_FOR_TARGET)] {
+# append add_flags " $env(CFLAGS_FOR_TARGET)"
+ }
+
+ if [info exists target_info(host,name)] {
+ set host [host_info name];
+ } else {
+ set host "unix";
+ }
+
+ foreach i $options {
+ if { $i == "c++" } {
+ set compiler_type "c++"
+ if [board_info $dest exists cxxflags] {
+ append add_flags " [target_info cxxflags]"
+ }
+ append add_flags " [g++_include_flags]";
+ if [board_info $dest exists c++compiler] {
+ set compiler [target_info c++compiler];
+ } else {
+ set compiler [find_g++];
+ }
+ }
+
+ if { $i == "f77" } {
+ set compiler_type "f77"
+ if [board_info $dest exists f77flags] {
+ append add_flags " [target_info f77flags]"
+ }
+# append add_flags " [f77_include_flags]"
+ if [board_info $dest exists f77compiler] {
+ set compiler [target_info f77compiler]
+ } else {
+ set compiler [find_g77]
+ }
+ }
+
+ if [regexp "^dest=" $i] {
+ regsub "^dest=" $i "" tmp
+ if [board_info $tmp exists name] {
+ set dest [board_info $tmp name];
+ } else {
+ set dest $tmp;
+ }
+ }
+ if [regexp "^compiler=" $i] {
+ regsub "^compiler=" $i "" tmp
+ set compiler $tmp
+ }
+ if [regexp "^additional_flags=" $i] {
+ regsub "^additional_flags=" $i "" tmp
+ append add_flags " $tmp"
+ }
+ if [regexp "^ldflags=" $i] {
+ regsub "^ldflags=" $i "" tmp
+ append ldflags " $tmp"
+ }
+ if [regexp "^libs=" $i] {
+ regsub "^libs=" $i "" tmp
+ append libs " $tmp"
+ }
+ if [regexp "^incdir=" $i] {
+ regsub "^incdir=" $i "-I" tmp
+ append add_flags " $tmp"
+ }
+ if [regexp "^libdir=" $i] {
+ regsub "^libdir=" $i "-L" tmp
+ append add_flags " $tmp"
+ }
+ if [regexp "^ldscript=" $i] {
+ regsub "^ldscript=" $i "" ldscript
+ }
+ if [regexp "^redirect=" $i] {
+ regsub "^redirect=" $i "" redirect
+ }
+ if [regexp "^optimize=" $i] {
+ regsub "^optimize=" $i "" optimize
+ }
+ if [regexp "^timeout=" $i] {
+ regsub "^timeout=" $i "" timeout
+ }
+ }
+
+ if [board_info $host exists cflags_for_target] {
+ append add_flags " [board_info $host cflags_for_target]";
+ }
+
+ global CC_FOR_TARGET
+ global CXX_FOR_TARGET
+ global F77_FOR_TARGET
+
+ if [info exists CC_FOR_TARGET] {
+ if { $compiler == "" } {
+ set compiler $CC_FOR_TARGET
+ }
+# When started from a mid-level directory (eg gdb)
+# the Makefile may export a *_FOR_TARGET that isn't
+# applicable.
+# } elseif [info exists env(CC_FOR_TARGET)] {
+# if { $compiler == "" } {
+# set compiler $env(CC_FOR_TARGET)
+# }
+ } elseif { [info exists env(CC_FOR_TARGET)] && $env(CC_FOR_TARGET) != "" } {
+ if { $compiler == "" } {
+ set compiler $env(CC_FOR_TARGET)
+ }
+ }
+
+ if [info exists CXX_FOR_TARGET] {
+ if { $compiler_type == "c++" } {
+ set compiler $CXX_FOR_TARGET
+ }
+# When started from a mid-level directory (eg gdb)
+# the Makefile may export a *_FOR_TARGET that isn't
+# applicable.
+# } elseif [info exists env(CXX_FOR_TARGET)] {
+# if { $compiler_type == "c++" } {
+# set compiler $env(CXX_FOR_TARGET)
+# }
+ }
+
+ if [info exists F77_FOR_TARGET] {
+ if { $compiler_type == "f77" } {
+ set compiler $F77_FOR_TARGET
+ }
+# When started from a mid-level directory (eg gdb)
+# the Makefile may export a *_FOR_TARGET that isn't
+# applicable.
+# } elseif [info exists env(F77_FOR_TARGET)] {
+# if { $compiler_type == "f77" } {
+# set compiler $env(F77_FOR_TARGET)
+# }
+ }
+
+ if { $compiler == "" } {
+ set compiler [board_info $dest compiler];
+ if { $compiler == "" } {
+ return "default_target_compile: No compiler to compile with";
+ }
+ }
+
+ if ![is_remote host] {
+ if { [which $compiler] == 0 } {
+ return "default_target_compile: Can't find $compiler."
+ }
+ }
+
+ if {$type == "object"} {
+ append add_flags " -c"
+ }
+
+ if { $type == "preprocess" } {
+ append add_flags " -E"
+ }
+
+ if { $type == "assembly" } {
+ append add_flags " -S"
+ }
+
+ if [board_info $dest exists cflags] {
+ append add_flags " [board_info $dest cflags]"
+ }
+
+ if { $type == "executable" } {
+ # This must be added here.
+ # if [board_info $dest exists ldscript] {
+ # append add_flags " [board_info $dest ldscript]"
+ # }
+
+ if [board_info $dest exists ldflags] {
+ append add_flags " [board_info $dest ldflags]"
+ }
+ if { $compiler_type == "c++" } {
+ append add_flags " [g++_link_flags]";
+ }
+ if [isnative] {
+ # This is a lose.
+ catch "glob -nocomplain $tool_root_dir/libstdc++/libstdc++.so* $tool_root_dir/libstdc++/libstdc++.sl" tmp
+ if { ${tmp} != "" } {
+ if [regexp ".*solaris2.*" $target_triplet] {
+ # Solaris 2
+ append add_flags " -R$tool_root_dir/libstdc++"
+ } elseif [regexp ".*(osf|irix5|linux).*" $target_triplet] {
+ # OSF/1 or Irix5
+ append add_flags " -Wl,-rpath,$tool_root_dir/libstdc++"
+ } elseif [regexp ".*hppa.*" $target_triplet] {
+ # HP/UX
+ append add_flags " -Wl,-a,shared_archive"
+ }
+ }
+ }
+ }
+
+ if ![info exists ldscript] {
+ set ldscript [board_info $dest ldscript]
+ }
+
+ foreach i $options {
+ if { $i == "debug" } {
+ if [board_info $dest exists debug_flags] {
+ append add_flags " [board_info $dest debug_flags]";
+ } else {
+ append add_flags " -g"
+ }
+ }
+ }
+
+ if [info exists optimize] {
+ append add_flags " $optimize";
+ }
+
+ if { $type == "executable" } {
+ foreach x $libs {
+ if [file exists $x] {
+ append source " $x"
+ } else {
+ append add_flags " $x";
+ }
+ }
+ append add_flags " $ldflags"
+
+ if [board_info $dest exists libs] {
+ append add_flags " [board_info $dest libs]"
+ }
+
+ # This probably isn't such a good idea, but it avoids nasty
+ # hackiness in the testsuites.
+ # The math library must be linked in before the C library. The C
+ # library is linked in by the linker script, so this must be before
+ # the linker script.
+ if [board_info $dest exists mathlib] {
+ append add_flags " [board_info $dest mathlib]"
+ } else {
+ append add_flags " -lm"
+ }
+
+ # This must be added here.
+ append add_flags " $ldscript";
+
+ if [board_info $dest exists remote_link] {
+ # Relink option.
+ append add_flags " -Wl,-r"
+ }
+ if [board_info $dest exists output_format] {
+ append add_flags " -Wl,-oformat,[board_info $dest output_format]";
+ }
+ }
+
+ if [board_info $dest exists multilib_flags] {
+ append add_flags " [board_info $dest multilib_flags]";
+ }
+
+ verbose "doing compile"
+
+ set sources ""
+ if [is_remote host] {
+ foreach x $source {
+ set file [remote_download host $x];
+ if { $file == "" } {
+ warning "Unable to download $x to host."
+ return "Unable to download $x to host."
+ } else {
+ append sources " $file";
+ }
+ }
+ } else {
+ set sources $source
+ }
+
+ if [is_remote host] {
+ append add_flags " -o a.out"
+ remote_file host delete a.out;
+ } else {
+ if { $destfile != "" } {
+ append add_flags " -o $destfile";
+ }
+ }
+
+ set opts "$sources $add_flags"
+
+ if [is_remote host] {
+ if [host_info exists use_at] {
+ set fid [open "atfile" "w"];
+ puts $fid "$opts";
+ close $fid;
+ set opts "@[remote_download host atfile]"
+ remote_file build delete atfile
+ }
+ }
+
+ verbose "Invoking the compiler as $compiler $opts" 2
+
+ if [info exists redirect] {
+ verbose "Redirecting output to $redirect" 2
+ set status [remote_exec host "$compiler $opts" "" "" $redirect];
+ } else {
+ if [info exists timeout] {
+ verbose "Setting timeout to $timeout" 2
+ set status [remote_exec host "$compiler $opts" "" "" "" $timeout];
+ } else {
+ set status [remote_exec host "$compiler $opts"];
+ }
+ }
+
+ set compiler_flags $opts
+ if [is_remote host] {
+ remote_upload host a.out $destfile;
+ remote_file host delete a.out;
+ }
+ set comp_output [prune_warnings [lindex $status 1]];
+ regsub "^\[\r\n\]+" $comp_output "" comp_output;
+ if { [lindex $status 0] != 0 } {
+ verbose -log "compiler exited with status [lindex $status 0]";
+ }
+ if { [lindex $status 1] != "" } {
+ verbose -log "output is:\n[lindex $status 1]" 2;
+ }
+ if { [lindex $status 0] != 0 && "${comp_output}" == "" } {
+ set comp_output "exit status is [lindex $status 0]";
+ }
+ return ${comp_output};
+}
+
+proc reboot_target { } {
+ set result [remote_reboot target]
+ puts "REBOOT_TARGET: \"$result\""
+ return [remote_reboot target];
+}
+
+#
+# Invoke this if you really want as to be called directly, rather than
+# calling the compiler. FLAGS are any additional flags to pass to the
+# assembler.
+#
+proc target_assemble { source destfile flags } {
+ return [default_target_assemble $source $destfile $flags];
+}
+
+proc default_target_assemble { source destfile flags } {
+ global env
+ global AS_FOR_TARGET;
+ global ASFLAGS_FOR_TARGET;
+
+ if [info exists AS_FOR_TARGET] {
+ set AS "$AS_FOR_TARGET";
+ } elseif [info exists env(AS_FOR_TARGET)] {
+ set AS $env(AS_FOR_TARGET)
+ } else {
+ if ![board_info target exists assembler] {
+ set AS [find_gas];
+ } else {
+ set AS [board_info target assembler];
+ }
+ }
+
+ if [info exists ASFLAGS_FOR_TARGET] {
+ append flags " $ASFLAGS_FOR_TARGET";
+# The top level Makefile sets (and exports) a *FLAGS_FOR_TARGET
+# that may not be applicable to testsuite runs. This conflict
+# needs to be resolved.
+# } elseif [info exists env(ASFLAGS_FOR_TARGET)] {
+# append flags " $env(ASFLAGS_FOR_TARGET)"
+ }
+
+ if [is_remote host] {
+ set source [remote_download host $source];
+ set dest "a.out"
+ } else {
+ set dest $destfile
+ }
+ set status [remote_exec host "$AS $source $flags -o $dest"]
+ if [is_remote host] {
+ remote_upload host $dest $destfile
+ }
+
+ set comp_output [prune_warnings [lindex $status 1]];
+ if { [lindex $status 0] != 0 } {
+ verbose -log "assembler exited with status [lindex $status 0]";
+ }
+ if { [lindex $status 1] != "" } {
+ verbose -log "assembler output is:\n[lindex $status 1]" 2;
+ }
+ return ${comp_output};
+}
+
+#
+# Invoke this if you really want ld to be called directly, rather than
+# calling the compiler. FLAGS are any additional flags to pass to the
+# linker.
+#
+proc target_link { objects destfile flags } {
+ return [default_link target "$objects" "$destfile" $flags];
+}
+
+proc default_link { board objects destfile flags } {
+ global env
+ global LD_FOR_TARGET;
+ global LDFLAGS_FOR_TARGET;
+
+ # return -L's in ldflags
+ proc only--Ls { ldflags } {
+ set result ""
+ set ldflags [split $ldflags]
+ set len [llength $ldflags]
+ for { set i 0 } { $i < $len } { incr i } {
+ # ??? We ignore the situation where a -L is actually the argument
+ # to an option.
+ set arg [lindex $ldflags $i]
+ regsub "^-Wl," $arg "" arg
+ if [regexp "^-L" $arg] {
+ # Is the directory in the next arg, or part of this one?
+ if { "$arg" == "-L" } {
+ if { $i + 1 < $len } {
+ append result " -L [lindex $ldflags $i+1]"
+ incr i
+ }
+ } else {
+ append result " $arg"
+ }
+ }
+ }
+ return $result
+ }
+
+ if [info exists LD_FOR_TARGET] {
+ set LD "$LD_FOR_TARGET";
+ } elseif [info exists env(LD_FOR_TARGET)] {
+ set LD $env(LD_FOR_TARGET)
+ } else {
+ if ![board_info target exists linker] {
+ set LD [find_ld];
+ } else {
+ set LD [board_info target linker];
+ }
+ }
+
+ if [info exists LDFLAGS_FOR_TARGET] {
+ append flags " $LDFLAGS_FOR_TARGET";
+# The top level Makefile sets (and exports) a *FLAGS_FOR_TARGET
+# that may not be applicable to testsuite runs. This conflict
+# needs to be resolved.
+# } elseif [info exists env(LDFLAGS_FOR_TARGET)] {
+# append flags " $env(LDFLAGS_FOR_TARGET)"
+ }
+
+ # `ldflags' consists of arguments to gcc (that are then
+ # passed to ld), not arguments to ld directly.
+ # We need the -L's.
+ if [board_info $board exists ldflags] {
+ set ldflags [board_info $board ldflags]
+ set ldflags [only--Ls $ldflags]
+ append flags " $ldflags"
+ }
+
+ if [board_info $board exists ldscript] {
+ # strip leading -Wl, if present
+ set ldscript [board_info $board ldscript]
+ regsub "^-Wl," $ldscript "" ldscript
+ append flags " $ldscript"
+ }
+
+ if [is_remote host] {
+ foreach x $objects {
+ set nobjects "$nobjects [remote_download host $x]";
+ }
+ set objects "$nobjects";
+ set dest "a.out";
+ } else {
+ set dest $destfile;
+ }
+ set status [remote_exec host "$LD $objects $flags -o $dest"]
+ if [is_remote host] {
+ remote_upload host $dest $destfile;
+ }
+
+ set comp_output [prune_warnings [lindex $status 1]];
+ if { [lindex $status 0] != 0 } {
+ verbose -log "linker exited with status [lindex $status 0]";
+ }
+ if { [lindex $status 1] != "" } {
+ verbose -log "linker output is:\n[lindex $status 1]" 2;
+ }
+ return ${comp_output};
+}
diff --git a/dejagnu/lib/targetdb.exp b/dejagnu/lib/targetdb.exp
new file mode 100644
index 00000000000..b682d045919
--- /dev/null
+++ b/dejagnu/lib/targetdb.exp
@@ -0,0 +1,113 @@
+# Copyright (C) 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+#
+# Searches in the appropriate place (the board_info array) for the specified
+# information.
+#
+proc board_info { machine op args } {
+ global target_info
+ global board_info
+
+ verbose "board_info $machine $op $args" 3
+
+ if [info exists target_info($machine,name)] {
+ set machine $target_info($machine,name);
+ }
+ if { $op == "exists" } {
+ if { [llength $args] == 0 } {
+ if [info exists board_info($machine,name)] {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ if [info exists "board_info($machine,[lindex $args 0])"] {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ }
+ if { [llength $args] == 0 } {
+ verbose "getting $machine $op" 3
+ if [info exists board_info($machine,$op)] {
+ return $board_info($machine,$op);
+ } else {
+ return ""
+ }
+ }
+ return "";
+}
+
+proc target_info { op args } {
+ return [eval "board_info target \"$op\" $args"];
+}
+
+proc host_info { op args } {
+ return [eval "board_info host \"$op\" $args"];
+}
+
+#
+# Fill in ENTRY with VALUE for the current board being defined.
+#
+proc set_board_info { entry value } {
+ global board_info board;
+
+ if ![info exists board_info($board,$entry)] {
+ set board_info($board,$entry) $value;
+ }
+}
+
+#
+# Fill in ENTRY with VALUE for the current target.
+#
+proc set_currtarget_info { entry value } {
+ global board_info;
+
+ set board [target_info name];
+
+ if ![info exists board_info($board,$entry)] {
+ set board_info($board,$entry) $value;
+ }
+}
+
+#
+# Unset ENTRY for the current board being defined.
+#
+proc unset_board_info { entry } {
+ global board_info board;
+
+ if [info exists board_info($board,$entry)] {
+ unset board_info($board,$entry);
+ }
+}
+
+#
+# Unset ENTRY for the current board being defined.
+#
+proc unset_currtarget_info { entry } {
+ global board_info;
+
+ set board [target_info name];
+
+ if [info exists board_info($board,$entry)] {
+ unset board_info($board,$entry);
+ }
+}
diff --git a/dejagnu/lib/telnet.exp b/dejagnu/lib/telnet.exp
new file mode 100644
index 00000000000..48c72aca505
--- /dev/null
+++ b/dejagnu/lib/telnet.exp
@@ -0,0 +1,243 @@
+# Copyright (C) 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+#
+# Connect using telnet. This takes two arguments. The first one is the
+# hostname, and the second is the optional port number. This sets
+# the fileid field in the config array, and returns -1 for error, or the
+# spawn id.
+#
+proc telnet_open { hostname args } {
+ global verbose
+ global connectmode
+ global spawn_id
+ global timeout
+ global board_info
+
+ set raw 0;
+
+ if { [llength $args] > 0 } {
+ if { [lindex $args 0] == "raw" } {
+ set raw 1;
+ }
+ }
+
+ set port 23
+ if [board_info $hostname exists name] {
+ set connhost [board_info $hostname name]
+ } else {
+ set connhost $hostname
+ }
+
+ if [board_info $connhost exists hostname] {
+ set hostname [board_info $connhost hostname];
+ }
+
+ if [file exists /usr/kerberos/bin/telnet] {
+ set telnet /usr/kerberos/bin/telnet;
+ } else {
+ set telnet telnet;
+ }
+
+ # Instead of unsetting it, let's return it. One connection at a
+ # time, please.
+ if [board_info $connhost exists fileid] {
+ return [board_info $connhost fileid];
+ }
+ # get the hostname and port number from the config array
+ if [board_info $connhost exists netport] {
+ set type $hostname
+ set hosttmp [split [board_info $connhost netport] ":"]
+ set hostname [lindex $hosttmp 0]
+ if { [llength $hosttmp] > 1 } {
+ set port [lindex $hosttmp 1]
+ }
+ unset hosttmp
+ } else {
+ set type target
+ }
+ if [board_info $connhost exists shell_prompt] {
+ set shell_prompt [board_info $connhost shell_prompt]
+ }
+ if ![info exists shell_prompt] { # if no prompt, then set it to something generic
+ set shell_prompt ".*> "
+ }
+
+ set tries 0
+ set result -1
+ set need_respawn 1;
+ verbose "Starting a telnet connection to $hostname:$port $shell_prompt" 2
+ while { $result < 0 && $tries <= 3 } {
+ if { $need_respawn } {
+ set need_respawn 0;
+ spawn $telnet $hostname $port;
+ }
+ expect {
+ "Trying " {
+ exp_continue;
+ }
+ -re "$shell_prompt.*$" {
+ verbose "Got prompt\n"
+ set result 0
+ }
+ -re "nt Name:|ogin:" {
+ if [board_info $connhost exists telnet_username] {
+ exp_send "[board_info $connhost telnet_username]\n";
+ exp_continue;
+ }
+ if [board_info $connhost exists username] {
+ exp_send "[board_info $connhost username]\n";
+ exp_continue;
+ }
+ perror "telnet: need to login"
+ break
+ }
+ "assword:" {
+ if [board_info $connhost exists telnet_password] {
+ exp_send "[board_info $connhost telnet_password]\n";
+ exp_continue;
+ }
+ if [board_info $connhost exists password] {
+ exp_send "[board_info $connhost password]\n";
+ exp_continue;
+ }
+ perror "telnet: need a password"
+ break
+ }
+ -re "advance.*y/n.*\\?" {
+ exp_send "n\n";
+ exp_continue;
+ }
+ -re {([Aa]dvanced|[Ss]imple) or ([Ss]imple|[Aa]dvanced)} {
+ exp_send "simple\n";
+ exp_continue;
+ }
+ "Connected to" {
+ exp_continue
+ }
+ "unknown host" {
+ exp_send "\003"
+ perror "telnet: unknown host"
+ break
+ }
+ "VxWorks Boot" {
+ exp_send "@\n";
+ sleep 20;
+ exp_continue;
+ }
+ -re "Escape character is.*\\.\[\r\n\]" {
+ if { $raw || [board_info $connhost exists dont_wait_for_prompt] } {
+ set result 0;
+ } else {
+ if [board_info $connhost exists send_initial_cr] {
+ exp_send "\n"
+ }
+ exp_continue
+ }
+ }
+ "has logged on from" {
+ exp_continue
+ }
+ "You have no Kerberos tickets" {
+ warning "telnet: no kerberos Tickets, please kinit"
+ break
+ }
+ -re "Connection refused.*$" {
+ catch "exp_send \"\003\"" foo;
+ sleep 5;
+ warning "telnet: connection refused."
+ }
+ -re "Sorry, this system is engaged.*" {
+ exp_send "\003"
+ warning "telnet: already connected."
+ }
+ "Connection closed by foreign host.*$" {
+ warning "telnet: connection closed by foreign host."
+ break
+ }
+ -re "\[\r\n\]+" {
+ exp_continue
+ }
+ timeout {
+ exp_send "\n"
+ }
+ eof {
+ warning "telnet: got unexpected EOF from telnet."
+ catch close;
+ catch wait;
+ set need_respawn 1;
+ sleep 5;
+ }
+ }
+ incr tries
+ }
+ # we look for this here again cause it means something went wrong, and
+ # it doesn't always show up in the expect in buffer till the server times out.
+ if [info exists expect_out(buffer)] {
+ if [regexp "assword:|ogin:" $expect_out(buffer)] {
+ perror "telnet: need to supply a login and password."
+ }
+ }
+ if { $result < 0 } {
+ catch close
+ catch wait
+ set spawn_id -1
+ }
+ if { $spawn_id >= 0 } {
+ verbose "setting board_info($connhost,fileid) to $spawn_id" 3
+ set board_info($connhost,fileid) $spawn_id
+ }
+ return $spawn_id
+}
+
+#
+# Put the telnet connection into binary mode.
+#
+proc telnet_binary { hostname } {
+ if [board_info $hostname exists fileid] {
+ remote_send $hostname "";
+ remote_expect $hostname 5 {
+ -re "telnet> *$" {}
+ default {}
+ }
+ remote_send $hostname "set binary\n"
+ remote_expect $hostname 5 {
+ -re "Format is .*telnet> *$" {
+ remote_send $hostname "toggle binary\n";
+ exp_continue;
+ }
+ -re "Negotiating network ascii.*telnet> *$" {
+ remote_send $hostname "toggle binary\n";
+ exp_continue;
+ }
+ -re "Negotiating binary.*\[\r\n\].*$" { }
+ -re "binary.*unknown argument.*telnet> *$" {
+ remote_send $hostname "mode character\n";
+ }
+ -re "Already operating in binary.*\[\r\n\].*$" { }
+ timeout {
+ warning "Never got binary response from telnet."
+ }
+ }
+ }
+}
+
+proc telnet_transmit { dest file args } {
+ return [standard_transmit $dest $file];
+}
diff --git a/dejagnu/lib/tip.exp b/dejagnu/lib/tip.exp
new file mode 100644
index 00000000000..25877a9b345
--- /dev/null
+++ b/dejagnu/lib/tip.exp
@@ -0,0 +1,184 @@
+# Copyright (C) 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+#
+# Connect via tip as part of remote_open.
+# returns -1 if it failed, the spawn_id if it worked; also sets
+# [board_info ${hostname} fileid] with the spawn_id on success.
+#
+proc tip_open { hostname } {
+ global verbose
+ global spawn_id
+
+ set tries 0
+ set result -1
+
+ if [board_info $hostname exists name] {
+ set hostname [board_info ${hostname} name];
+ }
+ set port [board_info ${hostname} tipname]
+ if [board_info ${hostname} exists shell_prompt] {
+ set shell_prompt [board_info ${hostname} shell_prompt]
+ } else {
+ set shell_prompt ".*> " # Pick something reasonably generic.
+ }
+
+ if [board_info ${hostname} exists fileid] {
+ unset board_info(${hostname},fileid);
+ }
+ spawn tip -v $port
+ if { $spawn_id < 0 } {
+ perror "invalid spawn id from tip"
+ return -1
+ }
+ expect {
+ -re ".*connected.*$" {
+ send "\r\n"
+ expect {
+ -re ".*$shell_prompt.*$" {
+ verbose "Got prompt\n"
+ set result 0
+ incr tries
+ }
+ timeout {
+ warning "Never got prompt."
+ set result -1
+ incr tries
+ if $tries<=2 {
+ exp_continue
+ }
+ }
+ }
+ }
+ -re "all ports busy.*$" {
+ set result -1
+ perror "All ports busy."
+ incr tries
+ if { $tries <= 2 } {
+ exp_continue
+ }
+ }
+ -re "Connection Closed.*$" {
+ perror "Never connected."
+ set result -1
+ incr tries
+ if { $tries <= 2 } {
+ exp_continue
+ }
+ }
+ -re ".*: Permission denied.*link down.*$" {
+ perror "Link down."
+ set result -1
+ incr tries
+ }
+ timeout {
+ perror "Timed out trying to connect."
+ set result -1
+ incr tries
+ if { $tries <= 2 } {
+ exp_continue
+ }
+ }
+ eof {
+ perror "Got unexpected EOF from tip."
+ set result -1
+ incr tries
+ }
+ }
+
+ send "\n~s"
+ expect {
+ "~\[set\]*" {
+ verbose "Setting verbose mode" 1
+ send "verbose\n\n\n"
+ }
+ }
+
+ if { $result < 0 } {
+ perror "Couldn't connect after $tries tries."
+ return -1
+ } else {
+ set board_info($hostname,fileid) $spawn_id
+ return $spawn_id
+ }
+}
+
+#
+# Downloads using the ~put command under tip
+# arg - is a full path name to the file to download
+# returns -1 if an error occured, otherwise it returns 0.
+#
+proc tip_download { dest file args } {
+ global verbose
+ global decimal
+ global expect_out
+
+ if [board_info $dest exists shell_prompt] {
+ set shell_prompt [board_info $dest shell_prompt];
+ } else {
+ set shell_prompt ".*>"
+ }
+
+ set result ""
+ if ![board_info $dest exists fileid] {
+ perror "tip_download: no connection to $dest."
+ return $result;
+ }
+ set shell_id [board_info $dest fileid];
+
+ if ![file exists $file] {
+ perror "$file doesn't exist."
+ return $result
+ }
+
+ send -i $shell_id "\n~p"
+ expect {
+ -i $shell_id "~\[put\]*" {
+ verbose "Downloading $file, please wait" 1
+ send -i $shell_id "$file\n"
+ set timeout 50
+ expect {
+ -i $shell_id -re ".*$file.*$" {
+ exp_continue
+ }
+ -i $shell_id -re ".*lines transferred in.*minute.*seconds.*$shell_prompt.*$" {
+ verbose "Download $file successfully" 1
+ set result $file;
+ }
+ -i $shell_id -re ".*Invalid command.*$shell_prompt$" {
+ warning "Got an invalid command to the remote shell."
+ }
+ -i $shell_id -re ".*$decimal\r" {
+ if [info exists expect_out(buffer)] {
+ verbose "$expect_out(buffer)"
+ exp_continue
+ }
+ }
+ -i $shell_id timeout {
+ perror "Timed out trying to download."
+ }
+ }
+ }
+ timeout {
+ perror "Timed out waiting for response to put command."
+ }
+ }
+ set timeout 10
+ return $result
+}
diff --git a/dejagnu/lib/util-defs.exp b/dejagnu/lib/util-defs.exp
new file mode 100644
index 00000000000..6048242905a
--- /dev/null
+++ b/dejagnu/lib/util-defs.exp
@@ -0,0 +1,101 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+#
+# Run a utility and test the result.
+#
+# Parameters:
+# First one is the command
+# Second one is command arguments
+# Third one is the file name
+# Fourth one is the regexp style pattern to match for a PASS
+#
+# Returns:
+# 1 if the test failed,
+# 0 if the test passes,
+# -1 if there was an internal error.
+#
+
+proc util_test { args } {
+ global verbose
+ # get the parameters
+ set cmd [lindex $args 0]
+ verbose "Utility to execute is $cmd" 2
+ set cmd_arg [lindex $args 1]
+ verbose "Command line arguments are $cmd_arg" 2
+ set file [lindex $args 2]
+ verbose "The file name to use is $file" 2
+ set pattern [lindex $args 3]
+ verbose "The pattern to match is \"$pattern\"" 2
+
+ if [info exists file] {
+ if ![string match "" $file] {
+ if ![file exists $file] {
+ perror "$file doesn't exist"
+ return -1
+ }
+ }
+ }
+
+ # Run the utility to be tested and analyze the results.
+
+ set comp_output [util_start $cmd $cmd_arg $file]
+
+ verbose "Output is \"$comp_output\"" 2
+ verbose "Pattern is \"$pattern\"" 2
+
+ if [regexp "$pattern" $comp_output] {
+ verbose "Pattern matches." 2
+ return 0
+ }
+
+ verbose "Pattern does not match." 2
+ return 1
+}
+
+#
+# Run the utility
+#
+# Return NULL or the output.
+#
+
+proc util_start { args } {
+ global verbose
+ set cmd [lindex $args 0]
+ set cmd_arg [lindex $args 1]
+ set file [lindex $args 2]
+
+ if {[which $cmd] == 0} {
+ perror "Can't find $cmd"
+ return ""
+ }
+
+ if { $verbose > 0 } {
+ verbose "Spawning \"$cmd $cmd_arg $file\""
+ } else {
+ send_log "Spawning \"$cmd $cmd_arg $file\"\n"
+ }
+ catch "exec $cmd $cmd_arg $file" comp_output
+ if ![string match "" $comp_output] {
+ send_log "$comp_output\n"
+ }
+ return $comp_output
+}
diff --git a/dejagnu/lib/utils.exp b/dejagnu/lib/utils.exp
new file mode 100644
index 00000000000..565f18ead0d
--- /dev/null
+++ b/dejagnu/lib/utils.exp
@@ -0,0 +1,441 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+#
+# Most of the procedures found here mimic their unix counter-part.
+# This file is sourced by runtest.exp, so they are usable by any test case.
+#
+
+#
+# Gets the directories in a directory
+# args: the first is the dir to look in, the next
+# is the pattern to match. It
+# defaults to *. Patterns are csh style
+# globbing rules
+# returns: a list of dirs or NULL
+#
+proc getdirs { args } {
+ if { [lindex $args 0] == "-all" } {
+ set alldirs 1
+ set args [lrange $args 1 end]
+ } else {
+ set alldirs 0
+ }
+
+ set path [lindex $args 0]
+ if { [llength $args] > 1} {
+ set pattern [lindex $args 1]
+ } else {
+ set pattern "*"
+ }
+ verbose "Looking in ${path} for directories that match \"${pattern}\"" 3
+ catch "glob ${path}/${pattern}" tmp
+ if { ${tmp} != "" } {
+ foreach i ${tmp} {
+ if [file isdirectory $i] {
+ switch -- "[file tail $i]" {
+ "testsuite" -
+ "config" -
+ "lib" -
+ "CVS" -
+ "RCS" -
+ "SCCS" {
+ verbose "Ignoring directory [file tail $i]" 3
+ continue
+ }
+ default {
+ if [file readable $i] {
+ verbose "Found directory [file tail $i]" 3
+ lappend dirs $i
+ if { $alldirs } {
+ eval lappend dirs [getdirs -all $i $pattern]
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ perror "$tmp"
+ return ""
+ }
+
+ if ![info exists dirs] {
+ return ""
+ } else {
+ return $dirs
+ }
+}
+
+#
+# Finds all the files recursively
+# rootdir - this is the directory to start the search
+# from. This is and all subdirectories are search for
+# filenames. Directory names are not included in the
+# list, but the filenames have path information.
+# pattern - this is the pattern to match. Patterns are csh style
+# globbing rules.
+# returns: a list or a NULL.
+#
+proc find { rootdir pattern } {
+ # first find all the directories
+ set dirs "$rootdir "
+ while 1 {
+ set tmp $rootdir
+ set rootdir ""
+ if [string match "" $tmp] {
+ break
+ }
+ foreach i $tmp {
+ set j [getdirs $i]
+ if ![string match "" $j] {
+ append dirs "$j "
+ set rootdir $j
+ unset j
+ } else {
+ set rootdir ""
+ }
+ }
+ set tmp ""
+ }
+
+ # find all the files that match the pattern
+ foreach i $dirs {
+ verbose "Looking in $i" 3
+ set tmp [glob -nocomplain $i/$pattern]
+ if { [llength $tmp] != 0 } {
+ foreach j $tmp {
+ if ![file isdirectory $j] {
+ lappend files $j
+ verbose "Adding $j to file list" 3
+ }
+ }
+ }
+ }
+
+ if ![info exists files] {
+ lappend files ""
+ }
+ return $files
+}
+
+#
+# Search the path for a file. This is basically a version
+# of the BSD-unix which utility. This procedure depends on
+# the shell environment variable $PATH. It returns 0 if $PATH
+# does not exist or the binary is not in the path. If the
+# binary is in the path, it returns the full path to the binary.
+#
+proc which { file } {
+ global env
+
+ # strip off any extraneous arguments (like flags to the compiler)
+ set file [lindex $file 0]
+
+ # if it exists then the path must be OK
+ # ??? What if $file has no path and "." isn't in $PATH?
+ if [file exists $file] {
+ return $file
+ }
+ if [info exists env(PATH)] {
+ set path [split $env(PATH) ":"]
+ } else {
+ return 0
+ }
+
+ foreach i $path {
+ verbose "Checking against $i" 3
+ if [file exists $i/$file] {
+ if [file executable $i/$file] {
+ return $i/$file
+ } else {
+ warning "$i/$file exists but is not an executable"
+ }
+ }
+ }
+ # not in path
+ return 0
+}
+
+#
+# Looks for a string in a file.
+# return:list of lines that matched or NULL if none match.
+# args: first arg is the filename,
+# second is the pattern,
+# third are any options.
+# Options: line - puts line numbers of match in list
+#
+proc grep { args } {
+
+ set file [lindex $args 0]
+ set pattern [lindex $args 1]
+
+ verbose "Grepping $file for the pattern \"$pattern\"" 3
+
+ set argc [llength $args]
+ if { $argc > 2 } {
+ for { set i 2 } { $i < $argc } { incr i } {
+ append options [lindex $args $i]
+ append options " "
+ }
+ } else {
+ set options ""
+ }
+
+ set i 0
+ set fd [open $file r]
+ while { [gets $fd cur_line]>=0 } {
+ incr i
+ if [regexp -- "$pattern" $cur_line match] {
+ if ![string match "" $options] {
+ foreach opt $options {
+ case $opt in {
+ "line" {
+ lappend grep_out [concat $i $match]
+ }
+ }
+ }
+ } else {
+ lappend grep_out $match
+ }
+ }
+ }
+ close $fd
+ unset fd
+ unset i
+ if ![info exists grep_out] {
+ set grep_out ""
+ }
+ return $grep_out
+}
+
+#
+# Remove elements based on patterns. elements are delimited by spaces.
+# pattern is the pattern to look for using glob style matching
+# list is the list to check against
+# returns the new list
+#
+proc prune { list pattern } {
+ set tmp {}
+ foreach i $list {
+ verbose "Checking pattern \"$pattern\" against $i" 3
+ if ![string match $pattern $i] {
+ lappend tmp $i
+ } else {
+ verbose "Removing element $i from list" 3
+ }
+ }
+ return $tmp
+}
+
+#
+# Attempt to kill a process that you started on the local machine.
+#
+proc slay { name } {
+ set in [open [concat "|ps"] r]
+ while {[gets $in line]>-1} {
+ if ![string match "*expect*slay*" $line] {
+ if [string match "*$name*" $line] {
+ set pid [lindex $line 0]
+ catch "exec kill -9 $pid]"
+ verbose "Killing $name, pid = $pid\n"
+ }
+ }
+ }
+ close $in
+}
+
+#
+# Convert a relative path to an absolute one on the local machine.
+#
+proc absolute { path } {
+ if [string match "." $path] {
+ return [pwd]
+ }
+
+ set basedir [pwd]
+ cd $path
+ set path [pwd]
+ cd $basedir
+ return $path
+}
+
+#
+# Source a file and trap any real errors. This ignores extraneous
+# output. returns a 1 if there was an error, otherwise it returns 0.
+#
+proc psource { file } {
+ global errorInfo
+ global errorCode
+
+ unset errorInfo
+ if [file exists $file] {
+ catch "source $file"
+ if [info exists errorInfo] {
+ send_error "ERROR: errors in $file\n"
+ send_error "$errorInfo"
+ return 1
+ }
+ }
+ return 0
+}
+
+#
+# Check if a testcase should be run or not
+#
+# RUNTESTS is a copy of global `runtests'.
+#
+# This proc hides the details of global `runtests' from the test scripts, and
+# implements uniform handling of "script arguments" where those arguments are
+# file names (ie: the "foo" in make check RUNTESTFLAGS="bar.exp=foo").
+# "glob" style expressions are supported as well as multiple files (with
+# spaces between them).
+# Eg: RUNTESTFLAGS="bar.exp=foo1.c foo2.c foo3*.c bar*.c"
+#
+proc runtest_file_p { runtests testcase } {
+ if [string length [lindex $runtests 1]] {
+ set basename [file tail $testcase]
+ foreach ptn [lindex $runtests 1] {
+ if [string match $ptn $basename] {
+ return 1
+ }
+ if [string match $ptn $testcase] {
+ return 1
+ }
+ }
+ return 0
+ }
+ return 1
+}
+
+#
+# Delete various system verbosities from TEXT on SYSTEM
+#
+# An example is:
+# ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
+#
+# SYSTEM is typical $target_triplet or $host_triplet.
+#
+
+#
+# Compares two files line-by-line
+# returns 1 it the files match,
+# returns 0 if there was a file error,
+# returns -1 if they didn't match.
+#
+proc diff { file_1 file_2 } {
+ set eof -1
+ set differences 0
+
+ if [file exists ${file_1}] {
+ set file_a [open ${file_1} r]
+ } else {
+ warning "${file_1} doesn't exist"
+ return 0
+ }
+
+ if [file exists ${file_2}] {
+ set file_b [open ${file_2} r]
+ } else {
+ warning "${file_2} doesn't exist"
+ return 0
+ }
+
+ verbose "# Diff'ing: ${file_1} ${file_2}\n" 1
+
+ set list_a ""
+ while { [gets ${file_a} line] != ${eof} } {
+ if [regexp "^#.*$" ${line}] {
+ continue
+ } else {
+ lappend list_a ${line}
+ }
+ }
+ close ${file_a}
+
+ set list_b ""
+ while { [gets ${file_b} line] != ${eof} } {
+ if [regexp "^#.*$" ${line}] {
+ continue
+ } else {
+ lappend list_b ${line}
+ }
+ }
+ close ${file_b}
+ for { set i 0 } { $i < [llength $list_a] } { incr i } {
+ set line_a [lindex ${list_a} ${i}]
+ set line_b [lindex ${list_b} ${i}]
+
+# verbose "\t${file_1}: ${i}: ${line_a}\n" 3
+# verbose "\t${file_2}: ${i}: ${line_b}\n" 3
+ if [string compare ${line_a} ${line_b}] {
+ verbose "line #${i}\n" 2
+ verbose "\< ${line_a}\n" 2
+ verbose "\> ${line_b}\n" 2
+
+ send_log "line #${i}\n"
+ send_log "\< ${line_a}\n"
+ send_log "\> ${line_b}\n"
+
+ set differences -1
+ }
+ }
+
+ if { $differences == -1 || [llength ${list_a}] != [llength ${list_b}] } {
+ verbose "Files not the same" 2
+ set differences -1
+ } else {
+ verbose "Files are the same" 2
+ set differences 1
+ }
+ return ${differences}
+}
+
+#
+# Set an environment variable
+#
+proc setenv { var val } {
+ global env
+
+ set env($var) $val
+}
+
+#
+# Unset an environment variable
+#
+proc unsetenv { var } {
+ global env
+ unset env($var)
+}
+
+#
+# Get a value from an environment variable
+#
+proc getenv { var } {
+ global env
+
+ if [info exists env($var)] {
+ return $env($var)
+ } else {
+ return ""
+ }
+}
+
diff --git a/dejagnu/lib/xsh.exp b/dejagnu/lib/xsh.exp
new file mode 100644
index 00000000000..694241df14d
--- /dev/null
+++ b/dejagnu/lib/xsh.exp
@@ -0,0 +1,322 @@
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+#
+# Connect to Spectra (VTRX) using xsh
+#
+proc xsh_open { hostname } {
+ global hex
+ global target_triplet
+ global xsh_shell_prompt
+ global board_info
+
+ if [board_info $hostname exists fileid] {
+ unset board_info($hostname,fileid);
+ }
+
+ if ![board_info $hostname exists spectra] {
+ perror "No spectra directory for $hostname";
+ return -1;
+ } else {
+ set spectra [board_info $hostname spectra];
+ }
+
+ if ![board_info $hostname exists xsh_shell_prompt] {
+ set xsh_shell_prompt ".*> "
+ } else {
+ set xsh_shell_prompt [board_info $hostname shell_prompt];
+ }
+
+ set retries 0
+ set result 0
+ if ![board_info $hostname exists xsh_prog] {
+ set xsh xsh;
+ } else {
+ set xsh [board_info $hostname xsh_prog];
+ }
+
+ if {[which $xsh] != 0} {
+ spawn $xsh
+ } else {
+ warning "Can't find xsh in path"
+ return -1
+ }
+
+ set shell_id $spawn_id
+
+ # start the shell
+ expect {
+ "*Spectra Cross-Development Shell version*$xsh_shell_prompt" {
+ verbose "Got prompt"
+ set result 0
+ }
+ timeout {
+ warning "Timed out trying to connect."
+ set result -1
+ incr retries
+ if { $retries <= 2 } {
+ exp_continue
+ }
+ }
+ }
+
+ # connect to the shell
+ set retries 0
+ send "connect $hostname\n"
+ expect {
+ "connect $hostname*$hostname connected \(non-os mode\)*\n" {
+ set xsh_shell_prompt "$hostname> "
+ verbose "Connected to $hostname"
+ }
+ "*connect: not attached*" {
+ warning "Couldn't attach target"
+ set result -1
+ }
+ -re ".* reset on target.*$" {
+ send_user "Spectra was reset\n"
+ exp_continue
+ }
+ -re "\[0-9A-Fa-f\]+\[ 0x\]+\[0-9A-Fa-f\]+.*$" {
+ exp_continue
+ }
+ "$hostname> " {
+ #send "\n"
+ }
+ timeout {
+ warning "Timed out trying to connect after $expect_out(seconds) seconds."
+ set result -1
+ incr retries
+ if { $retries <= 2 } {
+ exp_continue
+ }
+ }
+ }
+
+ send "\n\n\n"
+ expect {
+ "*$hostname*$hostname" {
+ verbose "Cleared reset messages" 1
+ }
+ timeout {
+ warning "Couldn't clear reset messages"
+ set result 1
+ }
+ }
+
+ set board_info($hostname,fileid) $spawn_id;
+ # load to operating system
+ set timeout 20
+ set retries 0
+ if {[xsh_download $hostname $spectra/${target_triplet}-os.o "" {-e sys_start_crt0}]!=0} {
+ perror "Couldn't load Spectra into target"
+ return -1
+ }
+
+ set timeout 10
+ # start the OS running
+ set retries 0
+ send "go\n"
+ expect {
+ -re ".*Multithreading on target darkstar.*$" {
+ verbose "Spectra has been started..." 1
+ set result 0
+ }
+ -re ".*reset on target.*$" {
+ verbose "Spectra was reset"
+ exp_continue
+ }
+ -re "\[0-9A-Fa-f\]+\[ 0x\]+\[0-9A-Fa-f\]+.*$" {
+ #send "\n"
+ exp_continue
+ }
+ -re "go\n" { exp_continue }
+ "$xsh_shell_prompt" { exp_continue }
+ timeout {
+ perror "Spectra wouldn't start"
+ set result -1
+ incr retries
+ if { $retries <= 2 } {
+ send "go\r"
+ exp_continue
+ }
+ }
+ }
+
+ if { $result < 0 } {
+ perror "Couldn't connect after $retries retries.\n"
+ return -1
+ } else {
+ set board_info($hostname,fileid) $spawn_id;
+ return $spawn_id
+ }
+}
+
+#
+# Download an executable using the load command in Spectra.
+# arg[0] - is a full path name to the file to download.
+# arg[1] - optional arguments to the load command.
+# returns 1 if a spectra error occured,
+# -1 if an internal error occured,
+# 0 otherwise.
+#
+proc xsh_download { dest file destfile args } {
+ global verbose
+ global shell_id
+ global decimal
+ global hex
+ global expect_out
+ global board_info
+
+ set result 1
+ set retries 0
+ set shell_id [board_info $dest fileid];
+
+ if { [llength $args] > 1 } {
+ set opts [lindex $args 1]
+ } else {
+ set opts ""
+ }
+
+ if { [llength $args] > 0 } {
+ set destfile [lindex $args 0]
+ }
+
+ if ![file exists $file] {
+ perror "$file doesn't exist."
+ return 1
+ }
+
+ verbose "Downloading $file..."
+
+ send -i $shell_id "load $opts $file\r"
+ set force 0
+ expect {
+ -i $shell_id -re "\[0-9A-Fa-f\]+\[ 0x\]+\[0-9A-Fa-f\]+\r\n" {
+ set timeout 1
+ send "dout\n"
+ while $force<2 {
+ expect {
+ "dout*undefined kernel symbol*$xsh_shell_prompt" {
+ verbose "Attempted to flush I/O buffers" 1
+ }
+ timout {
+ incr force
+ flush stdout
+ }
+ }
+ }
+ set timeout 20
+ exp_continue
+ }
+ -i $shell_id "load $opts $file*\r" {
+ verbose "Loading a.out..."
+ exp_continue
+ }
+ -i $shell_id "Warm reset on target*\n" {
+ verbose "Spectra did a warm reset"
+ exp_continue
+ }
+ -i $shell_id "Cold reset on target*\n" {
+ verbose "Spectra did a cold reset"
+ exp_continue
+ }
+ -i $shell_id "loading a.out*\r" {
+ verbose "Loading a.out..."
+ exp_continue
+ }
+ -i $shell_id "reading symbols*\r" {
+ verbose "Reading symbols..."
+ exp_continue
+ }
+ -i $shell_id "defining symbols*\r" {
+ verbose "defining symbols..."
+ exp_continue
+ }
+ -i $shell_id "*loading image*\r" {
+ verbose "Loading image..."
+ exp_continue
+ }
+ -i $shell_id -re ".*bytes loaded:.*$decimal.*$" {
+ verbose "$expect_out(buffer)"
+ exp_continue
+ }
+ -i $shell_id "*loading done*\r" {
+ verbose "Loading done..."
+ exp_continue
+ }
+ -i $shell_id "*setting PC*\r" {
+ verbose "Setting PC..."
+ exp_continue
+ }
+ -i $shell_id "*resolving symbols*\r" {
+ verbose "Resolving symbols..."
+ exp_continue
+ }
+ -i $shell_id -re ".*load module id = $decimal.*$" {
+ verbose ""
+ }
+ -i $shell_id -re ".*load: undefined symbols.*$" {
+ perror "undefined symbols, make sure os is loaded and running"
+ set result -1
+ }
+ -i $shell_id "$xsh_shell_prompt" {
+ set result 0
+ exp_continue
+ }
+ -i $shell_id "load: no default target" {
+ perror "default target isn't set"
+ return -1
+ }
+ -i $shell_id timeout {
+ perror "Timed out trying to download after $expect_out(seconds) seconds."
+ incr retries
+ set result 1
+ if { $retries <= 2 } {
+ exp_continue
+ }
+ }
+ }
+
+ set timeout 10
+ if [info exists expect_out(buffer)] {
+ send_log $expect_out(buffer)
+ }
+ set board_info($hostname,fileid) $shell_id
+ return $result
+}
+
+#
+# Exit the remote shell
+#
+proc xsh_close { hostname } {
+ global board_info
+
+ if ![board_info $hostname exists fileid] {
+ return;
+ }
+
+ set shell_id [board_info ${hostname} fileid];
+ send -i $shell_id "exit\n"
+ unset board_info(${hostname},fileid);
+
+ verbose "Exiting shell."
+ return 0
+}
diff --git a/dejagnu/mkinstalldirs b/dejagnu/mkinstalldirs
new file mode 100755
index 00000000000..0801ec2c966
--- /dev/null
+++ b/dejagnu/mkinstalldirs
@@ -0,0 +1,32 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d in ${1+"$@"} ; do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+ mkdir "$pathcomp" || errstatus=$?
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/dejagnu/runtest b/dejagnu/runtest
new file mode 100755
index 00000000000..47216f4dec8
--- /dev/null
+++ b/dejagnu/runtest
@@ -0,0 +1,117 @@
+#!/bin/sh
+#
+# runtest -- basically all this script does is find the proper expect
+# shell and then run DejaGnu.
+#
+# Written by Rob Savoye <rob@cygnus.com>
+#
+
+#
+# Get the execution path to this script and the current directory.
+#
+mypath=${0-.}
+if expr ${mypath} : '.*/.*' > /dev/null
+then
+ :
+else
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH
+ do
+ test -z "$dir" && dir=.
+ if test -x $dir/$mypath
+ then
+ mypath=$dir/$mypath
+ break
+ fi
+ done
+ IFS="$save_ifs"
+fi
+execpath=`echo ${mypath} | sed -e 's@/[^/]*$@@'`
+# rootme=`pwd`
+
+#
+# get the name by which runtest was invoked and extract the config triplet
+#
+runtest=`echo ${mypath} | sed -e 's@^.*/@@'`
+target=`echo $runtest | sed -e 's/-runtest$//'`
+if [ "$target" != runtest ] ; then
+ target="--target ${target}"
+else
+ target=""
+fi
+
+#
+# Find the right expect binary to use. If a variable EXPECT exists,
+# it takes precedence over all other tests. Otherwise look for a freshly
+# built one, and then use one in the path.
+#
+if [ x"$EXPECT" != x ] ; then
+ expectbin=$EXPECT
+else
+ if [ -x "$execpath/expect" ] ; then
+ expectbin=$execpath/expect
+ else
+ expectbin=expect
+ fi
+fi
+
+# just to be safe...
+if [ -z "$expectbin" ]; then
+ echo "ERROR: No expect shell found"
+ exit 1
+fi
+
+#
+# Extract a few options from the option list.
+#
+verbose=0
+debug=""
+for a in "$@" ; do
+ case $a in
+ -v|--v|-verb*|--verb*) verbose=`expr $verbose + 1`;;
+ -D0|--D0) debug="-D 0" ;;
+ -D1|--D1) debug="-D 1" ;;
+ esac
+done
+
+if expr $verbose \> 0 > /dev/null ; then
+ echo Expect binary is $expectbin
+fi
+
+#
+# find runtest.exp. First we look in it's installed location, otherwise
+# start if from the source tree.
+#
+# runtest.exp is found in (autoconf-configure-set) @datadir@, but
+# $execpath is @bindir@. We're assuming that
+#
+# @datadir@ == @bindir@/../share
+# or
+# @datadir@ == @bindir@/../../share
+#
+# which is a very weak assumption
+#
+for i in `echo ${execpath} | sed -e 's@/[^/]*$@/share/dejagnu@'` `echo ${execpath} | sed -e 's@/[^/]*/[^/]*$@/share/dejagnu@'` $execpath ; do
+ if expr $verbose \> 1 > /dev/null ; then
+ echo Looking for $i/runtest.exp.
+ fi
+ if [ -f $i/runtest.exp ] ; then
+ runpath=$i
+ if expr $verbose \> 0 > /dev/null ; then
+ echo Using $i/runtest.exp as main test driver
+ fi
+ fi
+done
+# check for an environment variable
+if [ x"$DEJAGNULIBS" != x ] ; then
+ runpath=$DEJAGNULIBS
+ if expr $verbose \> 0 > /dev/null ; then
+ echo Using $DEJAGNULIBS/runtest.exp as main test driver
+ fi
+fi
+if [ x"$runpath" = x ] ; then
+ echo "ERROR: runtest.exp does not exist."
+ exit 1
+fi
+
+exec $expectbin $debug -- $runpath/runtest.exp $target ${1+"$@"}
diff --git a/dejagnu/runtest.exp b/dejagnu/runtest.exp
new file mode 100644
index 00000000000..3821d62eab2
--- /dev/null
+++ b/dejagnu/runtest.exp
@@ -0,0 +1,1809 @@
+# Test Framework Driver
+# Copyright (C) 92, 93, 94, 95, 96, 97, 98, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+set frame_version 1.3.1
+if ![info exists argv0] {
+ send_error "Must use a version of Expect greater than 5.0\n"
+ exit 1
+}
+
+#
+# trap some signals so we know whats happening. These definitions are only
+# temporary until we read in the library stuff
+#
+trap { send_user "\nterminated\n"; exit 1 } SIGTERM
+trap { send_user "\ninterrupted by user\n"; exit 1 } SIGINT
+trap { send_user "\nsigquit\n"; exit 1 } SIGQUIT
+
+#
+# Initialize a few global variables used by all tests.
+# `reset_vars' resets several of these, we define them here to document their
+# existence. In fact, it would be nice if all globals used by some interface
+# of dejagnu proper were documented here.
+#
+# Keep these all lowercase. Interface variables used by the various
+# testsuites (eg: the gcc testsuite) should be in all capitals
+# (eg: TORTURE_OPTIONS).
+#
+set mail_logs 0 ;# flag for mailing of summary and diff logs
+set psum_file "latest" ;# file name of previous summary to diff against
+
+set exit_status 0 ;# exit code returned by this program
+
+set xfail_flag 0
+set xfail_prms 0
+set sum_file "" ;# name of the file that contains the summary log
+set base_dir "" ;# the current working directory
+set logname "" ;# the users login name
+set prms_id 0 ;# GNATS prms id number
+set bug_id 0 ;# optional bug id number
+set dir "" ;# temp variable for directory names
+set srcdir "." ;# source directory containing the test suite
+set ignoretests "" ;# list of tests to not execute
+set objdir "." ;# directory where test case binaries live
+set reboot 0
+set configfile site.exp ;# (local to this file)
+set multipass "" ;# list of passes and var settings
+set errno ""; ;#
+#
+# These describe the host and target environments.
+#
+set build_triplet "" ;# type of architecture to run tests on
+set build_os "" ;# type of os the tests are running on
+set build_vendor "" ;# vendor name of the OS or workstation the test are running on
+set build_cpu "" ;# type of the cpu tests are running on
+set host_triplet "" ;# type of architecture to run tests on, sometimes remotely
+set host_os "" ;# type of os the tests are running on
+set host_vendor "" ;# vendor name of the OS or workstation the test are running on
+set host_cpu "" ;# type of the cpu tests are running on
+set target_triplet "" ;# type of architecture to run tests on, final remote
+set target_os "" ;# type of os the tests are running on
+set target_vendor "" ;# vendor name of the OS or workstation the test are running on
+set target_cpu "" ;# type of the cpu tests are running on
+set target_alias "" ;# standard abbreviation of target
+set compiler_flags "" ;# the flags used by the compiler
+
+#
+# some convenience abbreviations
+#
+if ![info exists hex] {
+ set hex "0x\[0-9A-Fa-f\]+"
+}
+if ![info exists decimal] {
+ set decimal "\[0-9\]+"
+}
+
+#
+# set the base dir (current working directory)
+#
+set base_dir [pwd]
+
+#
+# These are tested in case they are not initialized in $configfile. They are
+# tested here instead of the init module so they can be overridden by command
+# line options.
+#
+if ![info exists all_flag] {
+ set all_flag 0
+}
+if ![info exists binpath] {
+ set binpath ""
+}
+if ![info exists debug] {
+ set debug 0
+}
+if ![info exists options] {
+ set options ""
+}
+if ![info exists outdir] {
+ set outdir "."
+}
+if ![info exists reboot] {
+ set reboot 1
+}
+if ![info exists tracelevel] {
+ set tracelevel 0
+}
+if ![info exists verbose] {
+ set verbose 0
+}
+
+#
+# verbose [-n] [-log] [--] message [level]
+#
+# Print MESSAGE if the verbose level is >= LEVEL.
+# The default value of LEVEL is 1.
+# "-n" says to not print a trailing newline.
+# "-log" says to add the text to the log file even if it won't be printed.
+# Note that the apparent behaviour of `send_user' dictates that if the message
+# is printed it is also added to the log file.
+# Use "--" if MESSAGE begins with "-".
+#
+# This is defined here rather than in framework.exp so we can use it
+# while still loading in the support files.
+#
+proc verbose { args } {
+ global verbose
+ set newline 1
+ set logfile 0
+
+ set i 0
+ if { [string index [lindex $args 0] 0] == "-" } {
+ for { set i 0 } { $i < [llength $args] } { incr i } {
+ if { [lindex $args $i] == "--" } {
+ incr i
+ break
+ } elseif { [lindex $args $i] == "-n" } {
+ set newline 0
+ } elseif { [lindex $args $i] == "-log" } {
+ set logfile 1
+ } elseif { [string index [lindex $args $i] 0] == "-" } {
+ clone_output "ERROR: verbose: illegal argument: [lindex $args $i]"
+ return
+ } else {
+ break
+ }
+ }
+ if { [llength $args] == $i } {
+ clone_output "ERROR: verbose: nothing to print"
+ return
+ }
+ }
+
+ set level 1
+ if { [llength $args] > $i + 1 } {
+ set level [lindex $args [expr $i+1]]
+ }
+ set message [lindex $args $i]
+
+ if { $verbose >= $level } {
+ # There is no need for the "--" argument here, but play it safe.
+ # We assume send_user also sends the text to the log file (which
+ # appears to be the case though the docs aren't clear on this).
+ if { $newline } {
+ send_user -- "$message\n"
+ } else {
+ send_user -- "$message"
+ }
+ } elseif { $logfile } {
+ if { $newline } {
+ send_log "$message\n"
+ } else {
+ send_log "$message"
+ }
+ }
+}
+
+#
+# Transform a tool name to get the installed name.
+# target_triplet is the canonical target name. target_alias is the
+# target name used when configure was run.
+#
+proc transform { name } {
+ global target_triplet
+ global target_alias
+ global host_triplet
+ global board;
+
+ if [string match $target_triplet $host_triplet] {
+ return $name
+ }
+ if [string match "native" $target_triplet] {
+ return $name
+ }
+ if [board_info host exists no_transform_name] {
+ return $name
+ }
+ if [string match "" $target_triplet] {
+ return $name
+ } else {
+ if [info exists board] {
+ if [board_info $board exists target_install] {
+ set target_install [board_info $board target_install];
+ }
+ }
+ if [target_info exists target_install] {
+ set target_install [target_info target_install];
+ }
+ if [info exists target_alias] {
+ set tmp ${target_alias}-${name};
+ } elseif [info exists target_install] {
+ if { [lsearch -exact $target_install $target_alias] >= 0 } {
+ set tmp ${target_alias}-${name};
+ } else {
+ set tmp "[lindex $target_install 0]-${name}";
+ }
+ }
+ verbose "Transforming $name to $tmp";
+ return $tmp;
+ }
+}
+
+#
+# findfile arg0 [arg1] [arg2]
+#
+# Find a file and see if it exists. If you only care about the false
+# condition, then you'll need to pass a null "" for arg1.
+# arg0 is the filename to look for. If the only arg,
+# then that's what gets returned. If this is the
+# only arg, then if it exists, arg0 gets returned.
+# if it doesn't exist, return only the prog name.
+# arg1 is optional, and it's what gets returned if
+# the file exists.
+# arg2 is optional, and it's what gets returned if
+# the file doesn't exist.
+#
+proc findfile { args } {
+ # look for the file
+ verbose "Seeing if [lindex $args 0] exists." 2
+ if [file exists [lindex $args 0]] {
+ if { [llength $args] > 1 } {
+ verbose "Found file, returning [lindex $args 1]"
+ return [lindex $args 1]
+ } else {
+ verbose "Found file, returning [lindex $args 0]"
+ return [lindex $args 0]
+ }
+ } else {
+ if { [llength $args] > 2 } {
+ verbose "Didn't find file [lindex $args 0], returning [lindex $args 2]"
+ return [lindex $args 2]
+ } else {
+ verbose "Didn't find file, returning [file tail [lindex $args 0]]"
+ return [transform [file tail [lindex $args 0]]]
+ }
+ }
+}
+
+#
+# load_file [-1] [--] file1 [ file2 ... ]
+#
+# Utility to source a file. All are sourced in order unless the flag "-1"
+# is given in which case we stop after finding the first one.
+# The result is 1 if a file was found, 0 if not.
+# If a tcl error occurs while sourcing a file, we print an error message
+# and exit.
+#
+# ??? Perhaps add an optional argument of some descriptive text to add to
+# verbose and error messages (eg: -t "library file" ?).
+#
+proc load_file { args } {
+ set i 0
+ set only_one 0
+ if { [lindex $args $i] == "-1" } {
+ set only_one 1
+ incr i
+ }
+ if { [lindex $args $i] == "--" } {
+ incr i
+ }
+
+ set found 0
+ foreach file [lrange $args $i end] {
+ verbose "Looking for $file" 2
+ # In Tcl7.5a2, "file exists" can fail if the filename looks
+ # like ~/FILE and the environment variable HOME does not
+ # exist.
+ if {! [catch {file exists $file} result] && $result} {
+ set found 1
+ verbose "Found $file"
+ if { [catch "uplevel #0 source $file"] == 1 } {
+ send_error "ERROR: tcl error sourcing $file.\n"
+ global errorInfo
+ if [info exists errorInfo] {
+ send_error "$errorInfo\n"
+ }
+ exit 1
+ }
+ if $only_one {
+ break
+ }
+ }
+ }
+ return $found
+}
+
+#
+# search_and_load_file -- search DIRLIST looking for FILELIST.
+# TYPE is used when displaying error and progress messages.
+#
+proc search_and_load_file { type filelist dirlist } {
+ set found 0;
+
+ foreach dir $dirlist {
+ foreach initfile $filelist {
+ verbose "Looking for $type ${dir}/${initfile}" 1
+ if [file exists ${dir}/${initfile}] {
+ set found 1
+ set error ""
+ if { ${type} != "library file" } {
+ send_user "Using ${dir}/${initfile} as ${type}.\n"
+ } else {
+ verbose "Loading ${dir}/${initfile}"
+ }
+ if [catch "uplevel #0 source ${dir}/${initfile}" error]==1 {
+ global errorInfo
+ send_error "ERROR: tcl error sourcing ${type} ${dir}/${initfile}.\n${error}\n"
+ if [info exists errorInfo] {
+ send_error "$errorInfo\n"
+ }
+ exit 1
+ }
+ break
+ }
+ }
+ if $found {
+ break
+ }
+ }
+ return $found;
+}
+
+#
+# Give a usage statement.
+#
+proc usage { } {
+ global tool;
+
+ send_user "USAGE: runtest \[options...\]\n"
+ send_user "\t--all (-a)\t\tPrint all test output to screen\n"
+ send_user "\t--build \[string\]\tThe canonical config name of the build machine\n"
+ send_user "\t--host \[string\]\t\tThe canonical config name of the host machine\n"
+ send_user "\t--host_board \[name\]\tThe host board to use\n"
+ send_user "\t--target \[string\]\tThe canonical config name of the target board\n"
+ send_user "\t--debug (-de)\t\tSet expect debugging ON\n"
+ send_user "\t--help (-he)\t\tPrint help text\n"
+ send_user "\t--ignore \[name(s)\]\tThe names of specific tests to ignore\n"
+ send_user "\t--objdir \[name\]\t\tThe test suite binary directory\n"
+ send_user "\t--outdir \[name\]\t\tThe directory to put logs in\n"
+ send_user "\t--reboot \[name\]\t\tReboot the target (if supported)\n"
+ send_user "\t--srcdir \[name\]\t\tThe test suite source code directory\n"
+ send_user "\t--strace \[number\]\tSet expect tracing ON\n"
+ send_user "\t--target_board \[name(s)\] The list of target boards to run tests on\n"
+ send_user "\t--tool\[name(s)\]\t\tRun tests on these tools\n"
+ send_user "\t--tool_exec \[name\]\tThe path to the tool executable to test\n"
+ send_user "\t--tool_opts \[options\]\tA list of additional options to pass to the tool\n"
+ send_user "\t--directory (-di) name\tRun only the tests in directory 'name'\n"
+ send_user "\t--verbose (-v)\t\tEmit verbose output\n"
+ send_user "\t--version (-V)\t\tEmit all version numbers\n"
+ send_user "\t--D\[0-1\]\t\tTcl debugger\n"
+ send_user "\tscript.exp\[=arg(s)\]\tRun these tests only\n"
+ if { [info exists tool] } {
+ if { [info proc ${tool}_option_help] != "" } {
+ ${tool}_option_help;
+ }
+ }
+}
+
+#
+# Parse the arguments the first time looking for these. We will ultimately
+# parse them twice. Things are complicated because:
+# - we want to parse --verbose early on
+# - we don't want config files to override command line arguments
+# (eg: $base_dir/$configfile vs --host/--target)
+# - we need some command line arguments before we can process some config files
+# (eg: --objdir before $objdir/$configfile, --host/--target before $DEJAGNU)
+# The use of `arg_host_triplet' and `arg_target_triplet' lets us avoid parsing
+# the arguments three times.
+#
+
+set arg_host_triplet ""
+set arg_target_triplet ""
+set arg_build_triplet ""
+set argc [ llength $argv ]
+for { set i 0 } { $i < $argc } { incr i } {
+ set option [lindex $argv $i]
+
+ # make all options have two hyphens
+ switch -glob -- $option {
+ "--*" {
+ }
+ "-*" {
+ set option "-$option"
+ }
+ }
+
+ # split out the argument for options that take them
+ switch -glob -- $option {
+ "--*=*" {
+ regexp {^[^=]*=(.*)$} $option nil optarg
+ }
+ "--bu*" -
+ "--ho*" -
+ "--ig*" -
+ "--m*" -
+ "--n*" -
+ "--ob*" -
+ "--ou*" -
+ "--sr*" -
+ "--st*" -
+ "--ta*" -
+ "--di*" -
+ "--to*" {
+ incr i
+ set optarg [lindex $argv $i]
+ }
+ }
+
+ switch -glob -- $option {
+ "--bu*" { # (--build) the build host configuration
+ set arg_build_triplet $optarg
+ continue
+ }
+
+ "--host_bo*" {
+ set host_board $optarg
+ continue
+ }
+
+ "--ho*" { # (--host) the host configuration
+ set arg_host_triplet $optarg
+ continue
+ }
+
+ "--ob*" { # (--objdir) where the test case object code lives
+ set objdir $optarg
+ continue
+ }
+
+ "--sr*" { # (--srcdir) where the testsuite source code lives
+ set srcdir $optarg
+ continue
+ }
+
+ "--target_bo*" {
+ set target_list $optarg;
+ continue;
+ }
+
+ "--ta*" { # (--target) the target configuration
+ set arg_target_triplet $optarg
+ continue
+ }
+
+ "--tool_opt*" {
+ set TOOL_OPTIONS $optarg
+ continue
+ }
+
+ "--tool_exec*" {
+ set TOOL_EXECUTABLE $optarg
+ continue
+ }
+
+ "--tool_ro*" {
+ set tool_root_dir $optarg
+ continue;
+ }
+
+ "--to*" { # (--tool) specify tool name
+ set tool $optarg
+ set comm_line_tool $optarg;
+ continue
+ }
+
+ "--di*" {
+ set cmdline_dir_to_run $optarg
+ puts "cmdline_dir_to_run = $cmdline_dir_to_run"
+ continue
+ }
+
+ "--v" -
+ "--verb*" { # (--verbose) verbose output
+ incr verbose
+ continue
+ }
+ }
+}
+verbose "Verbose level is $verbose"
+
+#
+# get the users login name
+#
+if [string match "" $logname] {
+ if [info exists env(USER)] {
+ set logname $env(USER)
+ } else {
+ if [info exists env(LOGNAME)] {
+ set logname $env(LOGNAME)
+ } else {
+ # try getting it with whoami
+ catch "set logname [exec whoami]" tmp
+ if [string match "*couldn't find*to execute*" $tmp] {
+ # try getting it with who am i
+ unset tmp
+ catch "set logname [exec who am i]" tmp
+ if [string match "*Command not found*" $tmp] {
+ send_user "ERROR: couldn't get the users login name\n"
+ set logname "Unknown"
+ } else {
+ set logname [lindex [split $logname " !"] 1]
+ }
+ }
+ }
+ }
+}
+
+#
+# lookfor_file -- try to find a file by searching up multiple directory levels
+#
+proc lookfor_file { dir name } {
+ foreach x ".. ../.. ../../.. ../../../.." {
+ verbose "$dir/$name"
+ if [file exists $dir/$name] {
+ return $dir/$name;
+ }
+ set dir [remote_file build dirname $dir];
+ }
+ return ""
+}
+
+#
+# load_lib -- load a library by sourcing it
+#
+# If there a multiple files with the same name, stop after the first one found.
+# The order is first look in the install dir, then in a parallel dir in the
+# source tree, (up one or two levels), then in the current dir.
+#
+proc load_lib { file } {
+ global verbose libdir srcdir base_dir execpath tool
+ global loaded_libs
+
+ if [info exists loaded_libs($file)] {
+ return;
+ }
+
+ set loaded_libs($file) "";
+
+ if { [search_and_load_file "library file" $file [list $libdir $libdir/lib [file dirname [file dirname $srcdir]]/dejagnu/lib $srcdir/lib . [file dirname [file dirname [file dirname $srcdir]]]/dejagnu/lib]] == 0 } {
+ send_error "ERROR: Couldn't find library file $file.\n"
+ exit 1
+ }
+}
+
+verbose "Login name is $logname"
+
+#
+# Begin sourcing the config files.
+# All are sourced in order.
+#
+# Search order:
+# $HOME/.dejagnurc -> $base_dir/$configfile -> $objdir/$configfile
+# -> installed -> $DEJAGNU
+#
+# ??? It might be nice to do $HOME last as it would allow it to be the
+# ultimate override. Though at present there is still $DEJAGNU.
+#
+# For the normal case, we rely on $base_dir/$configfile to set
+# host_triplet and target_triplet.
+#
+
+load_file ~/.dejagnurc $base_dir/$configfile
+
+#
+# If objdir didn't get set in $base_dir/$configfile, set it to $base_dir.
+# Make sure we source $objdir/$configfile in case $base_dir/$configfile doesn't
+# exist and objdir was given on the command line.
+#
+
+if [expr [string match "." $objdir] || [string match $srcdir $objdir]] {
+ set objdir $base_dir
+} else {
+ load_file $objdir/$configfile
+}
+
+# Well, this just demonstrates the real problem...
+if ![info exists tool_root_dir] {
+ set tool_root_dir [file dirname $objdir];
+ if [file exists "$tool_root_dir/testsuite"] {
+ set tool_root_dir [file dirname $tool_root_dir];
+ }
+}
+
+verbose "Using test sources in $srcdir"
+verbose "Using test binaries in $objdir"
+verbose "Tool root directory is $tool_root_dir"
+
+set execpath [file dirname $argv0]
+set libdir [file dirname $execpath]/dejagnu
+if [info exists env(DEJAGNULIBS)] {
+ set libdir $env(DEJAGNULIBS)
+}
+
+verbose "Using $libdir to find libraries"
+
+#
+# If the host or target was given on the command line, override the above
+# config files. We allow $DEJAGNU to massage them though in case it would
+# ever want to do such a thing.
+#
+if { $arg_host_triplet != "" } {
+ set host_triplet $arg_host_triplet
+}
+if { $arg_build_triplet != "" } {
+ set build_triplet $arg_build_triplet
+}
+
+# if we only specify --host, then that must be the build machne too, and we're
+# stuck using the old functionality of a simple cross test
+if [expr { $build_triplet == "" && $host_triplet != "" } ] {
+ set build_triplet $host_triplet
+}
+# if we only specify --build, then we'll use that as the host too
+if [expr { $build_triplet != "" && $host_triplet == "" } ] {
+ set host_triplet $build_triplet
+}
+unset arg_host_triplet arg_build_triplet
+
+#
+# If the build machine type hasn't been specified by now, use config.guess.
+#
+
+if [expr { $build_triplet == "" && $host_triplet == ""} ] {
+ # find config.guess
+ foreach dir "$libdir $libdir/.. $srcdir/.. $srcdir/../.." {
+ verbose "Looking for ${dir}/config.guess" 2
+ if [file exists ${dir}/config.guess] {
+ set config_guess ${dir}/config.guess
+ verbose "Found ${dir}/config.guess"
+ break
+ }
+ }
+
+ # get the canonical config name
+ if ![info exists config_guess] {
+ send_error "ERROR: Couldn't find config.guess program.\n"
+ exit 1
+ }
+ catch "exec $config_guess" build_triplet
+ case $build_triplet in {
+ { "No uname command or uname output not recognized" "Unable to guess system type" } {
+ verbose "WARNING: Uname output not recognized"
+ set build_triplet unknown
+ }
+ }
+ verbose "Assuming build host is $build_triplet"
+ if { $host_triplet == "" } {
+ set host_triplet $build_triplet
+ }
+
+}
+
+#
+# Figure out the target. If the target hasn't been specified, then we have to
+# assume we are native.
+#
+if { $arg_target_triplet != "" } {
+ set target_triplet $arg_target_triplet
+} elseif { $target_triplet == "" } {
+ set target_triplet $build_triplet
+ verbose "Assuming native target is $target_triplet" 2
+}
+unset arg_target_triplet
+#
+# Default target_alias to target_triplet.
+#
+if ![info exists target_alias] {
+ set target_alias $target_triplet
+}
+
+proc get_local_hostname { } {
+ if [catch "info hostname" hb] {
+ set hb ""
+ } else {
+ regsub "\\..*$" $hb "" hb;
+ }
+ verbose "hostname=$hb" 3;
+ return $hb;
+}
+
+#
+# We put these here so that they can be overridden later by site.exp or
+# friends.
+#
+# Set up the target as machine NAME. We also load base-config.exp as a
+# default configuration. The config files are sourced with the global
+# variable $board set to the name of the current target being defined.
+#
+proc setup_target_hook { whole_name name } {
+ global board;
+ global host_board;
+
+ if [info exists host_board] {
+ set hb $host_board;
+ } else {
+ set hb [get_local_hostname];
+ }
+
+ set board $whole_name;
+
+ global board_type;
+ set board_type "target";
+
+ load_config base-config.exp;
+ if ![load_board_description ${name} ${whole_name} ${hb}] {
+ if { $name != "unix" } {
+ perror "couldn't load description file for ${name}";
+ exit 1;
+ } else {
+ load_generic_config "unix"
+ }
+ }
+
+ if [board_info $board exists generic_name] {
+ load_tool_target_config [board_info $board generic_name];
+ }
+
+ unset board;
+ unset board_type;
+
+ push_target $whole_name;
+
+ if { [info procs ${whole_name}_init] != "" } {
+ ${whole_name}_init $whole_name;
+ }
+
+ if { ![isnative] && ![is_remote target] } {
+ global env build_triplet target_triplet
+ if { (![info exists env(DEJAGNU)]) && ($build_triplet != $target_triplet) } {
+ warning "Assuming target board is the local machine (which is probably wrong).\nYou may need to set your DEJAGNU environment variable."
+ }
+ }
+}
+
+#
+# Clean things up afterwards.
+#
+proc cleanup_target_hook { name } {
+ global tool;
+ # Clean up the target board.
+ if { [info procs "${name}_exit"] != "" } {
+ ${name}_exit;
+ }
+ # We also call the tool exit routine here.
+ if [info exists tool] {
+ if { [info procs "${tool}_exit"] != "" } {
+ ${tool}_exit;
+ }
+ }
+ remote_close target;
+ pop_target;
+}
+
+proc setup_host_hook { name } {
+ global board;
+ global board_info;
+ global board_type;
+
+ set board $name;
+ set board_type "host";
+
+ load_board_description $name;
+ unset board;
+ unset board_type;
+ push_host $name;
+ if { [info proc ${name}_init] != "" } {
+ ${name}_init $name;
+ }
+}
+
+proc setup_build_hook { name } {
+ global board;
+ global board_info;
+ global board_type;
+
+ set board $name;
+ set board_type "build";
+
+ load_board_description $name;
+ unset board;
+ unset board_type;
+ push_build $name;
+ if { [info proc ${name}_init] != "" } {
+ ${name}_init $name;
+ }
+}
+
+#
+# Find and load the global config file if it exists.
+# The global config file is used to set the connect mode and other
+# parameters specific to each particular target.
+# These files assume the host and target have been set.
+#
+
+if { [load_file -- $libdir/$configfile] == 0 } {
+ # If $DEJAGNU isn't set either then there isn't any global config file.
+ # Warn the user as there really should be one.
+ if { ! [info exists env(DEJAGNU)] } {
+ send_error "WARNING: Couldn't find the global config file.\n"
+ }
+}
+
+if [info exists env(DEJAGNU)] {
+ if { [load_file -- $env(DEJAGNU)] == 0 } {
+ # It may seem odd to only issue a warning if there isn't a global
+ # config file, but issue an error if $DEJAGNU is erroneously defined.
+ # Since $DEJAGNU is set there is *supposed* to be a global config file,
+ # so the current behaviour seems reasonable.
+ send_error "WARNING: global config file $env(DEJAGNU) not found.\n"
+ }
+ if ![info exists boards_dir] {
+ set boards_dir "[file dirname $env(DEJAGNU)]/boards";
+ }
+}
+
+if ![info exists boards_dir] {
+ set boards_dir ""
+}
+
+#
+# parse out the config parts of the triplet name
+#
+
+# build values
+if { $build_cpu == "" } {
+ regsub -- "-.*-.*" ${build_triplet} "" build_cpu
+}
+if { $build_vendor == "" } {
+ regsub -- "^\[a-z0-9\]*-" ${build_triplet} "" build_vendor
+ regsub -- "-.*" ${build_vendor} "" build_vendor
+}
+if { $build_os == "" } {
+ regsub -- ".*-.*-" ${build_triplet} "" build_os
+}
+
+# host values
+if { $host_cpu == "" } {
+ regsub -- "-.*-.*" ${host_triplet} "" host_cpu
+}
+if { $host_vendor == "" } {
+ regsub -- "^\[a-z0-9\]*-" ${host_triplet} "" host_vendor
+ regsub -- "-.*" ${host_vendor} "" host_vendor
+}
+if { $host_os == "" } {
+ regsub -- ".*-.*-" ${host_triplet} "" host_os
+}
+
+# target values
+if { $target_cpu == "" } {
+ regsub -- "-.*-.*" ${target_triplet} "" target_cpu
+}
+if { $target_vendor == "" } {
+ regsub -- "^\[a-z0-9\]*-" ${target_triplet} "" target_vendor
+ regsub -- "-.*" ${target_vendor} "" target_vendor
+}
+if { $target_os == "" } {
+ regsub -- ".*-.*-" ${target_triplet} "" target_os
+}
+
+#
+# Load the primary tool initialization file.
+#
+
+proc load_tool_init { file } {
+ global srcdir
+ global loaded_libs
+
+ if [info exists loaded_libs($file)] {
+ return;
+ }
+
+ set loaded_libs($file) "";
+
+ if [file exists ${srcdir}/lib/$file] {
+ verbose "Loading library file ${srcdir}/lib/$file"
+ if { [catch "uplevel #0 source ${srcdir}/lib/$file"] == 1 } {
+ send_error "ERROR: tcl error sourcing library file ${srcdir}/lib/$file.\n"
+ global errorInfo
+ if [info exists errorInfo] {
+ send_error "$errorInfo\n"
+ }
+ exit 1
+ }
+ } else {
+ warning "Couldn't find tool init file"
+ }
+}
+
+#
+# load the testing framework libraries
+#
+load_lib utils.exp
+load_lib framework.exp
+load_lib debugger.exp
+load_lib remote.exp
+load_lib target.exp
+load_lib targetdb.exp
+load_lib libgloss.exp
+
+# Initialize the test counters and reset them to 0.
+init_testcounts;
+reset_vars;
+
+#
+# Parse the command line arguments.
+#
+
+# Load the tool initialization file. Allow the --tool option to override
+# what's set in the site.exp file.
+if [info exists comm_line_tool] {
+ set tool $comm_line_tool;
+}
+
+if [info exists tool] {
+ load_tool_init ${tool}.exp;
+}
+
+set argc [ llength $argv ]
+for { set i 0 } { $i < $argc } { incr i } {
+ set option [ lindex $argv $i ]
+
+ # make all options have two hyphens
+ switch -glob -- $option {
+ "--*" {
+ }
+ "-*" {
+ set option "-$option"
+ }
+ }
+
+ # split out the argument for options that take them
+ switch -glob -- $option {
+ "--*=*" {
+ regexp {^[^=]*=(.*)$} $option nil optarg
+ }
+ "--bu*" -
+ "--ho*" -
+ "--ig*" -
+ "--m*" -
+ "--n*" -
+ "--ob*" -
+ "--ou*" -
+ "--sr*" -
+ "--st*" -
+
+ "--ta*" -
+ "--to*" {
+ incr i
+ set optarg [lindex $argv $i]
+ }
+ }
+
+ switch -glob -- $option {
+ "--V*" -
+ "--vers*" { # (--version) version numbers
+ send_user "Expect version is\t[exp_version]\n"
+ send_user "Tcl version is\t\t[ info tclversion ]\n"
+ send_user "Framework version is\t$frame_version\n"
+ exit
+ }
+
+ "--v*" { # (--verbose) verbose output
+ # Already parsed.
+ continue
+ }
+
+ "--bu*" { # (--build) the build host configuration
+ # Already parsed (and don't set again). Let $DEJAGNU rename it.
+ continue
+ }
+
+ "--ho*" { # (--host) the host configuration
+ # Already parsed (and don't set again). Let $DEJAGNU rename it.
+ continue
+ }
+
+ "--target_bo*" {
+ # Set it again, father knows best.
+ set target_list $optarg;
+ continue;
+ }
+
+ "--ta*" { # (--target) the target configuration
+ # Already parsed (and don't set again). Let $DEJAGNU rename it.
+ continue
+ }
+
+ "--a*" { # (--all) print all test output to screen
+ set all_flag 1
+ verbose "Print all test output to screen"
+ continue
+ }
+
+
+ "--d*" { # (--debug) expect internal debugging
+ if [file exists ./dbg.log] {
+ catch "exec rm -f ./dbg.log"
+ }
+ if { $verbose > 2 } {
+ exp_internal -f dbg.log 1
+ } else {
+ exp_internal -f dbg.log 0
+ }
+ verbose "Expect Debugging is ON"
+ continue
+ }
+
+ "--D[01]" { # (-Debug) turn on Tcl debugger
+ verbose "Tcl debugger is ON"
+ continue
+ }
+
+ "--m*" { # (--mail) mail the output
+ set mailing_list $optarg
+ set mail_logs 1
+ verbose "Mail results to $mailing_list"
+ continue
+ }
+
+ "--r*" { # (--reboot) reboot the target
+ set reboot 1
+ verbose "Will reboot the target (if supported)"
+ continue
+ }
+
+ "--ob*" { # (--objdir) where the test case object code lives
+ # Already parsed, but parse again to make sure command line
+ # options override any config file.
+ set objdir $optarg
+ verbose "Using test binaries in $objdir"
+ continue
+ }
+
+ "--ou*" { # (--outdir) where to put the output files
+ set outdir $optarg
+ verbose "Test output put in $outdir"
+ continue
+ }
+
+ "*.exp" { # specify test names to run
+ set all_runtests($option) ""
+ verbose "Running only tests $option"
+ continue
+ }
+
+ "*.exp=*" { # specify test names to run
+ set tmp [split $option "="]
+ set all_runtests([lindex $tmp 0]) [lindex $tmp 1]
+ verbose "Running only tests $option"
+ unset tmp
+ continue
+ }
+
+ "--ig*" { # (--ignore) specify test names to exclude
+ set ignoretests $optarg
+ verbose "Ignoring test $ignoretests"
+ continue
+ }
+
+ "--sr*" { # (--srcdir) where the testsuite source code lives
+ # Already parsed, but parse again to make sure command line
+ # options override any config file.
+
+ set srcdir $optarg
+ continue
+ }
+
+ "--st*" { # (--strace) expect trace level
+ set tracelevel $optarg
+ strace $tracelevel
+ verbose "Source Trace level is now $tracelevel"
+ continue
+ }
+
+ "--tool_opt*" {
+ continue
+ }
+
+ "--tool_exec*" {
+ set TOOL_EXECUTABLE $optarg
+ continue
+ }
+
+ "--tool_ro*" {
+ set tool_root_dir $optarg
+ continue;
+ }
+
+ "--to*" { # (--tool) specify tool name
+ set tool $optarg
+ verbose "Testing $tool"
+ continue
+ }
+
+ "[A-Z0-9_-.]*=*" { # process makefile style args like CC=gcc, etc...
+ if [regexp "^(\[A-Z0-9_-\]+)=(.*)$" $option junk var val] {
+ set $var $val
+ verbose "$var is now $val"
+ append makevars "set $var $val;" ;# FIXME: Used anywhere?
+ unset junk var val
+ } else {
+ send_error "Illegal variable specification:\n"
+ send_error "$option\n"
+ }
+ continue
+ }
+
+ "--he*" { # (--help) help text
+ usage;
+ exit 0
+ }
+
+ default {
+ if [info exists tool] {
+ if { [info proc ${tool}_option_proc] != "" } {
+ if [${tool}_option_proc $option] {
+ continue;
+ }
+ }
+ }
+ send_error "\nIllegal Argument \"$option\"\n"
+ send_error "try \"runtest --help\" for option list\n"
+ exit 1
+ }
+ }
+}
+
+#
+# check for a few crucial variables
+#
+if ![info exists tool] {
+ send_error "WARNING: No tool specified\n"
+ set tool ""
+}
+
+#
+# initialize a few Tcl variables to something other than their default
+#
+if { $verbose > 2 } {
+ log_user 1
+} else {
+ log_user 0
+}
+
+set timeout 10
+
+
+
+#
+# open log files
+#
+open_logs
+
+# print the config info
+clone_output "Test Run By $logname on [timestamp -format %c]"
+if [is3way] {
+ clone_output "Target is $target_triplet"
+ clone_output "Host is $host_triplet"
+ clone_output "Build is $build_triplet"
+} else {
+ if [isnative] {
+ clone_output "Native configuration is $target_triplet"
+ } else {
+ clone_output "Target is $target_triplet"
+ clone_output "Host is $host_triplet"
+ }
+}
+
+clone_output "\n\t\t=== $tool tests ===\n"
+
+#
+# Look for the generic board configuration file. It searches in several
+# places: ${libdir}/config, ${libdir}/../config, and $boards_dir.
+#
+
+proc load_generic_config { name } {
+ global srcdir;
+ global configfile;
+ global libdir;
+ global env;
+ global board;
+ global board_info;
+ global boards_dir;
+ global board_type;
+
+ if [info exists board] {
+ if ![info exists board_info($board,generic_name)] {
+ set board_info($board,generic_name) $name;
+ }
+ }
+
+ if [info exists board_type] {
+ set type "for $board_type";
+ } else {
+ set type ""
+ }
+
+ set dirlist [concat ${libdir}/config [file dirname $libdir]/config $boards_dir];
+ set result [search_and_load_file "generic interface file $type" ${name}.exp $dirlist];
+
+ return $result;
+}
+
+#
+# Load the tool-specific target description.
+#
+proc load_config { args } {
+ global srcdir;
+ global board_type;
+
+ set found 0;
+
+ return [search_and_load_file "tool-and-target-specific interface file" $args [list ${srcdir}/config ${srcdir}/../config ${srcdir}/../../config ${srcdir}/../../../config]];
+}
+
+#
+# Find the files that set up the configuration for the target. There
+# are assumed to be two of them; one defines a basic set of
+# functionality for the target that can be used by all tool
+# testsuites, and the other defines any necessary tool-specific
+# functionality. These files are loaded via load_config.
+#
+# These used to all be named $target_abbrev-$tool.exp, but as the
+# $tool variable goes away, it's now just $target_abbrev.exp. First
+# we look for a file named with both the abbrev and the tool names.
+# Then we look for one named with just the abbrev name. Finally, we
+# look for a file called default, which is the default actions, as
+# some tools could be purely host based. Unknown is mostly for error
+# trapping.
+#
+
+proc load_tool_target_config { name } {
+ global target_os
+
+ set found [load_config "${name}.exp" "${target_os}.exp" "default.exp" "unknown.exp"];
+
+ if { $found == 0 } {
+ send_error "ERROR: Couldn't find tool config file for $name.\n"
+ }
+}
+
+
+#
+# Find the file that describes the machine specified by board_name.
+#
+
+proc load_board_description { board_name args } {
+ global srcdir;
+ global configfile;
+ global libdir;
+ global env;
+ global board;
+ global board_info
+ global boards_dir;
+ global board_type;
+
+ set dejagnu ""
+
+ if { [llength $args] > 0 } {
+ set whole_name [lindex $args 0];
+ } else {
+ set whole_name $board_name;
+ }
+
+ set board_info($whole_name,name) $whole_name;
+ if ![info exists board] {
+ set board $whole_name;
+ set board_set 1;
+ } else {
+ set board_set 0;
+ }
+
+ set dirlist {};
+ if { [llength $args] > 1 } {
+ set suffix [lindex $args 1];
+ if { ${suffix} != "" } {
+ foreach x ${boards_dir} {
+ lappend dirlist ${x}/${suffix}
+ }
+ lappend dirlist ${libdir}/baseboards/${suffix};
+ }
+ }
+ set dirlist [concat $dirlist $boards_dir];
+ lappend dirlist ${libdir}/baseboards;
+ verbose "dirlist is $dirlist"
+ if [info exists board_type] {
+ set type "for $board_type";
+ } else {
+ set type "";
+ }
+ if ![info exists board_info($whole_name,isremote)] {
+ set board_info($whole_name,isremote) 1;
+ if [info exists board_type] {
+ if { $board_type == "build" } {
+ set board_info($whole_name,isremote) 0;
+ }
+ }
+ if { ${board_name} == [get_local_hostname] } {
+ set board_info($whole_name,isremote) 0;
+ }
+ }
+ search_and_load_file "standard board description file $type" standard.exp $dirlist;
+ set found [search_and_load_file "board description file $type" ${board_name}.exp $dirlist];
+ if { $board_set != 0 } {
+ unset board;
+ }
+
+ return $found;
+}
+
+#
+# Find the base-level file that describes the machine specified by args. We
+# only look in one directory, ${libdir}/baseboards.
+#
+
+proc load_base_board_description { board_name } {
+ global srcdir;
+ global configfile;
+ global libdir;
+ global env;
+ global board;
+ global board_info
+ global board_type;
+
+ set board_set 0;
+ set board_info($board_name,name) $board_name;
+ if ![info exists board] {
+ set board $board_name;
+ set board_set 1;
+ }
+ if [info exists board_type] {
+ set type "for $board_type";
+ } else {
+ set type ""
+ };
+ if ![info exists board_info($board_name,isremote)] {
+ set board_info($board_name,isremote) 1;
+ if [info exists board_type] {
+ if { $board_type == "build" } {
+ set board_info($board_name,isremote) 0;
+ }
+ }
+ }
+
+ if { ${board_name} == [get_local_hostname] } {
+ set board_info($board_name,isremote) 0;
+ }
+ set found [search_and_load_file "board description file $type" ${board_name}.exp ${libdir}/baseboards];
+ if { $board_set != 0 } {
+ unset board;
+ }
+
+ return $found;
+}
+
+#
+# Source the testcase in TEST_FILE_NAME.
+#
+
+proc runtest { test_file_name } {
+ global prms_id
+ global bug_id
+ global test_result
+ global errcnt
+ global errorInfo
+ global tool
+
+ clone_output "Running $test_file_name ..."
+ set prms_id 0
+ set bug_id 0
+ set test_result ""
+
+ if [file exists $test_file_name] {
+ set timestart [timestamp];
+
+ if [info exists tool] {
+ if { [info procs "${tool}_init"] != "" } {
+ ${tool}_init $test_file_name;
+ }
+ }
+
+ if { [catch "uplevel #0 source $test_file_name"] == 1 } {
+ # We can't call `perror' here, it resets `errorInfo'
+ # before we want to look at it. Also remember that perror
+ # increments `errcnt'. If we do call perror we'd have to
+ # reset errcnt afterwards.
+ clone_output "ERROR: tcl error sourcing $test_file_name."
+ if [info exists errorInfo] {
+ clone_output "ERROR: $errorInfo"
+ unset errorInfo
+ }
+ }
+
+ if [info exists tool] {
+ if { [info procs "${tool}_finish"] != "" } {
+ ${tool}_finish;
+ }
+ }
+ set timeend [timestamp];
+ set timediff [expr $timeend - $timestart];
+ verbose -log "testcase $test_file_name completed in $timediff seconds" 4
+ } else {
+ # This should never happen, but maybe if the file got removed
+ # between the `find' above and here.
+ perror "$test_file_name does not exist."
+ # ??? This is a hack. We want to send a message to stderr and
+ # to the summary file (just like perror does), but we don't
+ # want the next testcase to get a spurious "unresolved" because
+ # errcnt != 0. Calling `clone_output' is also supposed to be a
+ # no-no (see the comments for clone_output).
+ set errcnt 0
+ }
+}
+
+#
+# Trap some signals so we know what's happening. These replace the previous
+# ones because we've now loaded the library stuff.
+#
+if ![exp_debug] {
+ foreach sig "{SIGTERM {terminated}} \
+ {SIGINT {interrupted by user}} \
+ {SIGQUIT {interrupted by user}} \
+ {SIGSEGV {segmentation violation}}" {
+ set signal [lindex $sig 0];
+ set str [lindex $sig 1];
+ trap "send_error \"got a \[trap -name\] signal, $str \\n\"; log_and_exit;" $signal;
+ verbose "setting trap for $signal to $str" 1
+ }
+ unset signal str sig;
+}
+
+#
+# Given a list of targets, process any iterative lists.
+#
+proc process_target_variants { target_list } {
+ set result {};
+ foreach x $target_list {
+ if [regexp "\\(" $x] {
+ regsub "^.*\\((\[^()\]*)\\)$" "$x" "\\1" variant_list;
+ regsub "\\(\[^(\]*$" "$x" "" x;
+ set list [process_target_variants $x];
+ set result {}
+ foreach x $list {
+ set result [concat $result [iterate_target_variants $x [split $variant_list ","]]];
+ }
+ } elseif [regexp "\{" $x] {
+ regsub "^.*\{(\[^\{\}\]*)\}$" "$x" "\\1" variant_list;
+ regsub "\{\[^\{\]*$" "$x" "" x;
+ set list [process_target_variants $x];
+ foreach x $list {
+ foreach i [split $variant_list ","] {
+ set name $x;
+ if { $i != "" } {
+ append name "/" $i;
+ }
+ lappend result $name;
+ }
+ }
+ } else {
+ lappend result "$x";
+ }
+ }
+ return $result;
+}
+
+proc iterate_target_variants { target variants } {
+ return [iterate_target_variants_two $target $target $variants];
+}
+
+#
+# Given a list of variants, produce the list of all possible combinations.
+#
+proc iterate_target_variants_two { orig_target target variants } {
+
+ if { [llength $variants] == 0 } {
+ return [list $target];
+ } else {
+ if { [llength $variants] > 1 } {
+ set result [iterate_target_variants_two $orig_target $target [lrange $variants 1 end]];
+ } else {
+ if { $target != $orig_target } {
+ set result [list $target];
+ } else {
+ set result {};
+ }
+ }
+ if { [lindex $variants 0] != "" } {
+ append target "/" [lindex $variants 0];
+ return [concat $result [iterate_target_variants_two $orig_target $target [lrange $variants 1 end]]];
+ } else {
+ return [concat $result $target];
+ }
+ }
+}
+
+setup_build_hook [get_local_hostname];
+
+if [info exists host_board] {
+ setup_host_hook $host_board;
+} else {
+ set hb [get_local_hostname];
+ if { $hb != "" } {
+ setup_host_hook $hb;
+ }
+}
+
+#
+# main test execution loop
+#
+
+if [info exists errorInfo] {
+ unset errorInfo
+}
+# make sure we have only single path delimiters
+regsub -all "\(\[^/\]\)//*" $srcdir "\\1/" srcdir
+
+if ![info exists target_list] {
+# Make sure there is at least one target machine. It's probably a Unix box,
+# but that's just a guess.
+ set target_list { "unix" }
+} else {
+ verbose "target list is $target_list"
+}
+
+#
+# Iterate through the list of targets.
+#
+global current_target;
+
+set target_list [process_target_variants $target_list];
+
+set target_count [llength $target_list]
+
+clone_output "Schedule of variations:"
+foreach current_target $target_list {
+ clone_output " $current_target"
+}
+clone_output ""
+
+
+foreach current_target $target_list {
+ verbose "target is $current_target";
+ set current_target_name $current_target;
+ set tlist [split $current_target /];
+ set current_target [lindex $tlist 0];
+ set board_variant_list [lrange $tlist 1 end];
+
+ # Set the counts for this target to 0.
+ reset_vars;
+ clone_output "Running target $current_target_name"
+
+ setup_target_hook $current_target_name $current_target;
+
+# If multiple passes requested, set them up. Otherwise prepare just one.
+# The format of `MULTIPASS' is a list of elements containing
+# "{ name var1=value1 ... }" where `name' is a generic name for the pass and
+# currently has no other meaning.
+
+ global env
+
+ if { [info exists MULTIPASS] } {
+ set multipass $MULTIPASS
+ } elseif {[info exists env(MULTIPASS)]} {
+ set multipass $env(MULTIPASS)
+ }
+ if { $multipass == "" } {
+ set multipass { "" }
+ }
+
+# If PASS is specified, either as a TCL variable or in environment, we
+# want to run only the tests specified. Its value should be a number
+# or a list of numbers that specify the passes that we want to run.
+ if [info exists PASS] {
+ set pass $PASS
+ } elseif [info exists env(PASS)] {
+ set pass $env(PASS)
+ } else {
+ set pass ""
+ }
+
+ if {$pass != ""} {
+ set passes [list]
+ foreach p $pass {
+ foreach multipass_elem $multipass {
+ set multipass_name [lindex $multipass_elem 0]
+ if {$p == $multipass_name} {
+ lappend passes $multipass_elem
+ break;
+ }
+ }
+ }
+ set multipass $passes
+ }
+
+ foreach pass $multipass {
+
+ # multipass_name is set for `record_test' to use (see framework.exp).
+ if { [lindex $pass 0] != "" } {
+ set multipass_name [lindex $pass 0]
+ clone_output "Running pass `$multipass_name' ..."
+ } else {
+ set multipass_name ""
+ }
+ set restore ""
+ foreach varval [lrange $pass 1 end] {
+ set tmp [string first "=" $varval]
+ set var [string range $varval 0 [expr $tmp - 1]]
+ # Save previous value.
+ if [info exists $var] {
+ lappend restore "$var [list [eval concat \$$var]]"
+ } else {
+ lappend restore "$var"
+ }
+ # Handle "CFLAGS=$CFLAGS foo".
+ # FIXME: Do we need to `catch' this?
+ eval set $var \[string range \"$varval\" [expr $tmp + 1] end\]
+ verbose "$var is now [eval concat \$$var]"
+ unset tmp var
+ }
+
+ # look for the top level testsuites. if $tool doesn't
+ # exist and there are no subdirectories in $srcdir, then
+ # we default to srcdir.
+ set test_top_dirs [lsort [getdirs -all ${srcdir} "${tool}*"]]
+ if { ${test_top_dirs} == "" } {
+ set test_top_dirs ${srcdir}
+ }
+ verbose "Top level testsuite dirs are ${test_top_dirs}" 2
+ set testlist "";
+ if [info exists all_runtests] {
+ foreach x [array names all_runtests] {
+ verbose "trying to glob ${srcdir}/${x}" 2
+ set s [glob -nocomplain ${srcdir}/$x];
+ if { $s != "" } {
+ set testlist [concat $testlist $s];
+ }
+ }
+ }
+ #
+ # If we have a list of tests, run all of them.
+ #
+ if { $testlist != "" } {
+ foreach test_name $testlist {
+ if { ${ignoretests} != "" } {
+ if { 0 <= [lsearch ${ignoretests} [file tail ${test_name}]]} {
+ continue
+ }
+ }
+
+ # set subdir to the tail of the dirname after $srcdir,
+ # for the driver files that want it. XXX this is silly.
+ # drivers should get a single var, not "$srcdir/$subdir"
+ set subdir [file dirname $test_name]
+ set p [expr [string length $srcdir]-1]
+ while {0 < $p && [string index $srcdir $p] == "/"} {
+ incr p -1
+ }
+ if {[string range $subdir 0 $p] == $srcdir} {
+ set subdir [string range $subdir [expr $p+1] end];
+ regsub "^/" $subdir "" subdir
+ }
+
+ # XXX not the right thing to do.
+ set runtests [list [file tail $test_name] ""]
+
+ runtest $test_name;
+ }
+ } else {
+ #
+ # Go digging for tests.
+ #
+ foreach dir "${test_top_dirs}" {
+ if { ${dir} != ${srcdir} } {
+ # Ignore this directory if is a directory to be
+ # ignored.
+ if {[info exists ignoredirs] && $ignoredirs != ""} {
+ set found 0
+ foreach directory $ignoredirs {
+ if [string match "*${directory}*" $dir] {
+ set found 1
+ break
+ }
+ }
+ if {$found} {
+ continue
+ }
+ }
+
+ # Run the test if dir_to_run was specified as a
+ # value (for example in MULTIPASS) and the test
+ # directory matches that directory.
+ if {[info exists dir_to_run] && $dir_to_run != ""} {
+ if ![string match "*${dir_to_run}*" $dir] {
+ continue
+ }
+ }
+
+ # Run the test if cmdline_dir_to_run was specified
+ # by the user using --directory and the test
+ # directory matches that directory
+ if {[info exists cmdline_dir_to_run] \
+ && $cmdline_dir_to_run != ""} {
+ if ![string match "*${cmdline_dir_to_run}*" $dir] {
+ continue
+ }
+ }
+
+ foreach test_name [lsort [find ${dir} *.exp]] {
+ if { ${test_name} == "" } {
+ continue
+ }
+ # Ignore this one if asked to.
+ if { ${ignoretests} != "" } {
+ if { 0 <= [lsearch ${ignoretests} [file tail ${test_name}]]} {
+ continue
+ }
+ }
+
+ # Get the path after the $srcdir so we know
+ # the subdir we're in.
+ set subdir [file dirname $test_name]
+ # We used to do
+ # regsub $srcdir [file dirname $test_name] "" subdir
+ # but what if [file dirname $test_name] contains regexp
+ # characters? We lose. Instead...
+ set first [string first $srcdir $subdir]
+ if { $first >= 0 } {
+ set first [expr $first + [string length $srcdir]];
+ set subdir [string range $subdir $first end];
+ regsub "^/" "$subdir" "" subdir;
+ }
+ if { "$srcdir" == "$subdir" || "$srcdir" == "$subdir/" } {
+ set subdir ""
+ }
+ # Check to see if the range of tests is limited,
+ # set `runtests' to a list of two elements: the script name
+ # and any arguments ("" if none).
+ if [info exists all_runtests] {
+ verbose "searching for $test_name in [array names all_runtests]"
+ if { 0 > [lsearch [array names all_runtests] [file tail $test_name]]} {
+ if { 0 > [lsearch [array names all_runtests] $test_name] } {
+ continue
+ }
+ }
+ set runtests [list [file tail $test_name] $all_runtests([file tail $test_name])]
+ } else {
+ set runtests [list [file tail $test_name] ""]
+ }
+ runtest $test_name;
+ }
+ }
+ }
+ # Restore the variables set by this pass.
+ foreach varval $restore {
+ if { [llength $varval] > 1 } {
+ verbose "Restoring [lindex $varval 0] to [lindex $varval 1]" 4;
+ set [lindex $varval 0] [lindex $varval 1];
+ } else {
+ verbose "Restoring [lindex $varval 0] to `unset'" 4;
+ unset [lindex $varval 0];
+ }
+ }
+ }
+ }
+ cleanup_target_hook $current_target;
+ if { $target_count > 1 } {
+ log_summary;
+ }
+}
+
+log_and_exit;
diff --git a/dejagnu/site.tmpl b/dejagnu/site.tmpl
new file mode 100644
index 00000000000..ab8c3b09d81
--- /dev/null
+++ b/dejagnu/site.tmpl
@@ -0,0 +1,48 @@
+#
+# site.tmpl -- Sample template for a global config file.
+# NOTE: This file contains mostly site specific
+# configuration data that is custom to Cygnus
+# Support. You'll have to change most of the
+# values to work at your site.
+# Written by manson@cygnus.com
+#
+
+#
+# transform -- transform a tool name to get the installed name. We only define
+# this if there wasn't one. This was the global config file can
+# override how the tool names are calculated.
+#
+
+#
+# uncomment this if you wish to redefine the transform procedure
+#
+
+#if ![string match "transform" [info procs transform]] then {
+# proc transform { name } {
+# global target_triplet
+#
+# if [string match "" $target_triplet] then {
+# return $name
+# } else {
+# return ${target_triplet}-$name
+# }
+# }
+#}
+
+#
+# Set a default target list for various target triplets.
+#
+case "$target_triplet" in {
+ { "hppa*-*-proelf*" } {
+ set target_list { winbond }
+ }
+ { "i386-*-aout" } {
+ set target_list { i386-aout }
+ }
+ { "m68k-mvme135-*" } { # Motorola MVME135 board running Bug monitor
+ set target_list { "mvme135-bug" }
+ }
+ { "m68k-idp-*" "m68k-rom68k-*" } { # Motorola IDP board running rom68k monitor
+ set target_list "bozo"
+ }
+}
diff --git a/dejagnu/stub-loader.c b/dejagnu/stub-loader.c
new file mode 100644
index 00000000000..d84d41b0c5f
--- /dev/null
+++ b/dejagnu/stub-loader.c
@@ -0,0 +1,7 @@
+/* Bleah!! */
+int remote_debug = 0;
+
+main() {
+ set_debug_traps();
+ breakpoint();
+}
diff --git a/dejagnu/tcl-mode.el b/dejagnu/tcl-mode.el
new file mode 100644
index 00000000000..90b3503d094
--- /dev/null
+++ b/dejagnu/tcl-mode.el
@@ -0,0 +1,2223 @@
+;; tcl.el --- Tcl code editing commands for Emacs
+
+;; Copyright (C) 1994 Free Software Foundation, Inc.
+
+;; Maintainer: Tom Tromey <tromey@busco.lanl.gov>
+;; Author: Tom Tromey <tromey@busco.lanl.gov>
+;; Chris Lindblad <cjl@lcs.mit.edu>
+;; Keywords: languages tcl modes
+;; Version: 1.49
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 1, or (at your option)
+;; any later version.
+
+;; GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to
+;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;; HOW TO INSTALL:
+;; Put the following forms in your .emacs to enable autoloading of Tcl
+;; mode, and auto-recognition of ".tcl" files.
+;;
+;; (autoload 'tcl-mode "tcl" "Tcl mode." t)
+;; (autoload 'inferior-tcl "tcl" "Run inferior Tcl process." t)
+;; (setq auto-mode-alist (append '(("\\.tcl$" . tcl-mode)) auto-mode-alist))
+;;
+;; If you plan to use the interface to the TclX help files, you must
+;; set the variable tcl-help-directory-list to point to the topmost
+;; directories containing the TclX help files. Eg:
+;;
+;; (setq tcl-help-directory-list '("/usr/local/lib/tclx/help"))
+;;
+;; Also you will want to add the following to your .emacs:
+;;
+;; (autoload 'tcl-help-on-word "tcl" "Help on Tcl commands" t)
+;;
+;; FYI a *very* useful thing to do is nroff all the Tk man pages and
+;; put them in a subdir of the help system.
+;;
+
+;;; Commentary:
+
+;; LCD Archive Entry:
+;; tcl|Tom Tromey|tromey@busco.lanl.gov|
+;; Major mode for editing Tcl|
+;; 1995/12/07 18:27:47|1.49|~/modes/tcl.el.Z|
+
+;; CUSTOMIZATION NOTES:
+;; * tcl-proc-list can be used to customize a list of things that
+;; "define" other things. Eg in my project I put "defvar" in this
+;; list.
+;; * tcl-typeword-list is similar, but uses font-lock-type-face.
+;; * tcl-keyword-list is a list of keywords. I've generally used this
+;; for flow-control words. Eg I add "unwind_protect" to this list.
+;; * tcl-type-alist can be used to minimally customize indentation
+;; according to context.
+
+;; Change log:
+;; tcl.el,v
+;; Revision 1.49 1995/12/07 18:27:47 tromey
+;; (add-log-tcl-defun): Don't use tcl-beginning-of-defun; just go to end
+;; of line before searching.
+;;
+;; Revision 1.48 1995/12/07 18:18:21 tromey
+;; (add-log-tcl-defun): Now uses tcl-beginning-of-defun.
+;;
+;; Revision 1.47 1995/08/22 17:49:45 tromey
+;; (tcl-hilit): New function from "Chris Alfeld" <calfeld@math.utah.edu>
+;; (tcl-mode): Call it
+;;
+;; Revision 1.46 1995/08/07 16:02:01 tromey
+;; (tcl-do-auto-fill): Only fill past fill-column; for 19.29.
+;; (tcl-auto-fill-mode): Use force-mode-line-update.
+;;
+;; Revision 1.45 1995/07/23 23:51:25 tromey
+;; (tcl-word-no-props): New function.
+;; (tcl-figure-type): Use it.
+;; (tcl-current-word): Ditto.
+;;
+;; Revision 1.44 1995/07/23 20:26:47 tromey
+;; Doc fixes.
+;;
+;; Revision 1.43 1995/07/17 19:59:49 tromey
+;; (inferior-tcl-mode): Use modeline-process if it exists.
+;;
+;; Revision 1.42 1995/07/17 19:55:25 tromey
+;; XEmacs currently must use tcl-internal-end-of-defun
+;;
+;; Revision 1.41 1995/07/14 21:54:56 tromey
+;; Changes to make menus work in XEmacs.
+;; From Mike Scheidler <c23mts@kocrsv01.delcoelect.com>
+;;
+;; Revision 1.40 1995/07/11 03:13:15 tromey
+;; (tcl-mode): Customize for new dabbrev.
+;;
+;; Revision 1.39 1995/07/09 21:58:03 tromey
+;; (tcl-do-fill-paragraph): New function.
+;; (tcl-mode): Set up for paragraph filling.
+;;
+;; Revision 1.38 1995/07/09 21:30:32 tromey
+;; (tcl-mode): Fixes to 19.29 paragraph variables.
+;;
+;; Revision 1.37 1995/07/09 18:52:16 tromey
+;; (tcl-do-auto-fill): Set fill-prefix.
+;;
+;; Revision 1.36 1995/07/09 01:07:57 tromey
+;; (tcl-imenu-create-index-function): Work with imenu from Emacs 19.29
+;;
+;; Revision 1.35 1995/06/27 20:12:00 tromey
+;; (tcl-type-alist): More itcl changes.
+;;
+;; Revision 1.34 1995/06/27 20:06:05 tromey
+;; More changes for itcl.
+;; Bug fixes for Emacs 19.29.
+;;
+;; Revision 1.33 1995/06/27 20:01:29 tromey
+;; (tcl-set-proc-regexp): Allow leading spaces.
+;; (tcl-proc-list): Changes for itcl.
+;; (tcl-typeword-list): Ditto.
+;; (tcl-keyword-list): Ditto.
+;;
+;; Revision 1.32 1995/05/11 22:12:49 tromey
+;; (tcl-type-alist): Include entry for "proc".
+;;
+;; Revision 1.31 1995/05/10 23:38:12 tromey
+;; (tcl-add-fsf-menu): Use make-lucid-menu-keymap, not
+;; "make-xemacs-menu-keymap".
+;;
+;; Revision 1.30 1995/05/10 18:22:21 tromey
+;; Bug fix in menu code for XEmacs.
+;;
+;; Revision 1.29 1995/05/09 21:36:53 tromey
+;; Changed "Lucid Emacs" to "XEmacs".
+;; Tcl's popup menu now added to existing one, courtesy
+;; dfarmer@evolving.com (Doug Farmer)
+;;
+;; Revision 1.28 1995/04/08 19:52:50 tromey
+;; (tcl-outline-level): New function
+;; (tcl-mode): Added outline-handling stuff.
+;; From Jesper Pedersen <blackie@imada.ou.dk>
+;;
+;; Revision 1.27 1994/10/11 02:01:27 tromey
+;; (tcl-mode): imenu-create-index-function made buffer local.
+;;
+;; Revision 1.26 1994/09/01 18:06:24 tromey
+;; Added filename completion in inferior tcl mode
+;;
+;; Revision 1.25 1994/08/22 15:56:24 tromey
+;; tcl-load-file default to current buffer.
+;;
+;; Revision 1.24 1994/08/21 20:33:05 tromey
+;; Fixed bug in tcl-guess-application.
+;;
+;; Revision 1.23 1994/08/21 03:54:45 tromey
+;; Keybindings don't overshadown comint bindings.
+;;
+;; Revision 1.22 1994/07/26 00:46:07 tromey
+;; Emacs 18 changes from Carl Witty.
+;;
+;; Revision 1.21 1994/07/14 22:49:21 tromey
+;; Added ";;;###autoload" comments where appropriate.
+;;
+; Revision 1.20 1994/06/05 16:57:22 tromey
+; tcl-current-word does the right thing in inferior-tcl-mode.
+;
+; Revision 1.19 1994/06/03 21:09:19 tromey
+; Another menu fix.
+;
+; Revision 1.18 1994/06/03 20:39:14 tromey
+; Fixed menu bug.
+;
+; Revision 1.17 1994/06/03 00:47:15 tromey
+; Fixed bug in bug-reporting code.
+;
+; Revision 1.16 1994/05/26 05:06:14 tromey
+; Menu items now sensitive as appropriate.
+;
+; Revision 1.15 1994/05/22 20:38:11 tromey
+; Added bug-report keybindings and menu entries.
+;
+; Revision 1.14 1994/05/22 20:18:28 tromey
+; Even more compile stuff.
+;
+; Revision 1.13 1994/05/22 20:17:15 tromey
+; Moved emacs version checking code to very beginning.
+;
+; Revision 1.12 1994/05/22 20:14:59 tromey
+; Compile fixes.
+;
+; Revision 1.11 1994/05/22 20:12:44 tromey
+; Fixed mark-defun for 19.23.
+; More menu fixes.
+;
+; Revision 1.10 1994/05/22 20:02:03 tromey
+; Fixed bug with M-;.
+; Wrote bug-reporting code.
+;
+; Revision 1.9 1994/05/22 05:26:51 tromey
+; Fixes for imenu.
+;
+; Revision 1.8 1994/05/22 03:38:07 tromey
+; Fixed menu support.
+;
+; Revision 1.7 1994/05/03 01:23:42 tromey
+; *** empty log message ***
+;
+; Revision 1.6 1994/04/23 16:23:36 tromey
+; Wrote tcl-indent-for-comment
+;
+;;
+;; 18-Mar-1994 Tom Tromey Fourth beta release.
+;; Added {un,}comment-region to menu. Idea from
+;; Mike Scheidler <c23mts@kocrsv01.delcoelect.com>
+;; 17-Mar-1994 Tom Tromey
+;; Fixed tcl-restart-with-file. Bug fix attempt in
+;; tcl-internal-end-of-defun.
+;; 16-Mar-1994 Tom Tromey Third beta release
+;; Added support code for menu (from Tcl mode written by
+;; schmid@fb3-s7.math.TU-Berlin.DE (Gregor Schmid)).
+;; 12-Mar-1994 Tom Tromey
+;; Better documentation for inferior-tcl-buffer. Wrote
+;; tcl-restart-with-file. Wrote Lucid Emacs menu (but no
+;; code to install it).
+;; 12-Mar-1994 Tom Tromey
+;; Wrote tcl-guess-application. Another stab at making
+;; tcl-omit-ws-regexp work.
+;; 10-Mar-1994 Tom Tromey Second beta release
+;; Last Modified: Thu Mar 10 01:24:25 1994 (Tom Tromey)
+;; Wrote perl-mode style line indentation command.
+;; Wrote more documentation. Added tcl-continued-indent-level.
+;; Integrated help code.
+;; 8-Mar-1994 Tom Tromey
+;; Last Modified: Tue Mar 8 11:58:44 1994 (Tom Tromey)
+;; Bug fixes.
+;; 6-Mar-1994 Tom Tromey
+;; Last Modified: Sun Mar 6 18:55:41 1994 (Tom Tromey)
+;; Updated auto-newline support.
+;; 6-Mar-1994 Tom Tromey Beta release
+;; Last Modified: Sat Mar 5 17:24:32 1994 (Tom Tromey)
+;; Wrote tcl-hashify-buffer. Other minor bug fixes.
+;; 5-Mar-1994 Tom Tromey
+;; Last Modified: Sat Mar 5 16:11:20 1994 (Tom Tromey)
+;; Wrote electric-hash code.
+;; 3-Mar-1994 Tom Tromey
+;; Last Modified: Thu Mar 3 02:53:40 1994 (Tom Tromey)
+;; Added code to handle auto-fill in comments.
+;; Added imenu support code.
+;; Cleaned up code.
+;; Better font-lock support.
+;; 28-Feb-1994 Tom Tromey
+;; Last Modified: Mon Feb 28 14:08:05 1994 (Tom Tromey)
+;; Made tcl-figure-type more easily configurable.
+;; 28-Feb-1994 Tom Tromey
+;; Last Modified: Mon Feb 28 01:02:58 1994 (Tom Tromey)
+;; Wrote inferior-tcl mode.
+;; 16-Feb-1994 Tom Tromey
+;; Last Modified: Wed Feb 16 17:05:19 1994 (Tom Tromey)
+;; Added support for font-lock-mode.
+;; 29-Oct-1993 Tom Tromey
+;; Last Modified: Sun Oct 24 17:39:14 1993 (Tom Tromey)
+;; Patches from Guido Bosch to make things work with Lucid Emacs.
+;; 22-Oct-1993 Tom Tromey
+;; Last Modified: Fri Oct 22 15:26:46 1993 (Tom Tromey)
+;; Made many characters have "_" syntax class; suggested by Guido
+;; Bosch <Guido.Bosch@loria.fr>. Note that this includes the "$"
+;; character, which might be a change you'd notice.
+;; 21-Oct-1993 Tom Tromey
+;; Last Modified: Thu Oct 21 20:28:40 1993 (Tom Tromey)
+;; More fixes for tcl-omit-ws-regexp.
+;; 20-Oct-1993 Tom Tromey
+;; Started keeping history. Fixed tcl-{beginning,end}-of-defun.
+;; Added some code to make things work with Emacs 18.
+
+;; THANKS TO:
+;; Guido Bosch <Guido.Bosch@loria.fr>
+;; pgs1002@esc.cam.ac.uk (Dr P.G. Sjoerdsma)
+;; Mike Scheidler <c23mts@kocrsv01.delcoelect.com>
+;; Matt Newman <men@charney.colorado.edu>
+;; rwhitby@research.canon.oz.au (Rod Whitby)
+;; h9118101@hkuxa.hku.hk (Yip Chi Lap [Beta])
+;; Pertti Tapio Kasanen <ptk@delta.hut.fi>
+;; schmid@fb3-s7.math.TU-Berlin.DE (Gregor Schmid)
+;; warsaw@nlm.nih.gov (Barry A. Warsaw)
+;; Carl Witty <cwitty@ai.mit.edu>
+;; T. V. Raman <raman@crl.dec.com>
+;; Jesper Pedersen <blackie@imada.ou.dk>
+;; dfarmer@evolving.com (Doug Farmer)
+;; "Chris Alfeld" <calfeld@math.utah.edu>
+
+;; KNOWN BUGS:
+;; * indent-region should skip blank lines. (It does in v19, so I'm
+;; not motivated to fix it here).
+;; * In Tcl "#" is not always a comment character. This can confuse
+;; tcl.el in certain circumstances. For now the only workaround is
+;; to enclose offending hash characters in quotes or precede it with
+;; a backslash. Note that using braces won't work -- quotes change
+;; the syntax class of characters between them, while braces do not.
+;; The electric-# mode helps alleviate this problem somewhat.
+;; * indent-tcl-exp is untested.
+;; * Doesn't work under Emacs 18 yet.
+;; * There's been a report that font-lock does strange things under
+;; Lucid Emacs 19.6. For instance in "proc foobar", the space
+;; before "foobar" is highlighted.
+
+;; TODO:
+;; * make add-log-tcl-defun smarter. should notice if we are in the
+;; middle of a defun, or between defuns. should notice if point is
+;; on first line of defun (or maybe even in comments before defun).
+;; * Allow continuation lines to be indented under the first argument
+;; of the preceeding line, like this:
+;; [list something \
+;; something-else]
+;; * There is a request that indentation work like this:
+;; button .fred -label Fred \
+;; -command {puts fred}
+;; * Should have tcl-complete-symbol that queries the inferior process.
+;; * Should have describe-symbol that works by sending the magic
+;; command to a tclX process.
+;; * Need C-x C-e binding (tcl-eval-last-exp).
+;; * Write indent-region function that is faster than indenting each
+;; line individually.
+;; * tcl-figure-type should stop at "beginning of line" (only ws
+;; before point, and no "\" on previous line). (see tcl-real-command-p).
+;; * overrides some comint keybindings; fix.
+;; * Trailing \ will eat blank lines. Should deal with this.
+;; (this would help catch some potential bugs).
+;; * Inferior should display in half the screen, not the whole screen.
+;; * Indentation should deal with "switch".
+;; * Consider writing code to find help files automatically (for
+;; common cases).
+;; * `#' shouldn't insert `\#' when point is in string.
+
+
+
+;;; Code:
+
+;; I sure wish Emacs had a package that made it easy to extract this
+;; sort of information.
+(defconst tcl-using-emacs-19 (string-match "19\\." emacs-version)
+ "Nil unless using Emacs 19 (XEmacs or FSF).")
+
+;; FIXME this will break on Emacs 19.100.
+(defconst tcl-using-emacs-19-23
+ (string-match "19\\.\\(2[3-9]\\|[3-9][0-9]\\)" emacs-version)
+ "Nil unless using Emacs 19-23 or later.")
+
+(defconst tcl-using-xemacs-19 (string-match "XEmacs" emacs-version)
+ "Nil unless using XEmacs).")
+
+(require 'comint)
+
+;; When compiling under GNU Emacs, load imenu during compilation. If
+;; you have 19.22 or earlier, comment this out, or get imenu.
+(and (fboundp 'eval-when-compile)
+ (eval-when-compile
+ (if (and (string-match "19\\." emacs-version)
+ (not (string-match "XEmacs" emacs-version)))
+ (require 'imenu))
+ ()))
+
+(defconst tcl-version "1.49")
+(defconst tcl-maintainer "Tom Tromey <tromey@drip.colorado.edu>")
+
+;;
+;; User variables.
+;;
+
+(defvar tcl-indent-level 4
+ "*Indentation of Tcl statements with respect to containing block.")
+
+(defvar tcl-continued-indent-level 4
+ "*Indentation of continuation line relative to first line of command.")
+
+(defvar tcl-auto-newline nil
+ "*Non-nil means automatically newline before and after braces
+inserted in Tcl code.")
+
+(defvar tcl-tab-always-indent t
+ "*Control effect of TAB key.
+If t (the default), always indent current line.
+If nil and point is not in the indentation area at the beginning of
+the line, a TAB is inserted.
+Other values cause the first possible action from the following list
+to take place:
+
+ 1. Move from beginning of line to correct indentation.
+ 2. Delete an empty comment.
+ 3. Move forward to start of comment, indenting if necessary.
+ 4. Move forward to end of line, indenting if necessary.
+ 5. Create an empty comment.
+ 6. Move backward to start of comment, indenting if necessary.")
+
+(defvar tcl-use-hairy-comment-detector t
+ "*If not `nil', the the more complicated, but slower, comment
+detecting function is used. This variable is only used in GNU Emacs
+19 (the fast function is always used elsewhere).")
+
+(defvar tcl-electric-hash-style 'smart
+ "*Style of electric hash insertion to use.
+Possible values are 'backslash, meaning that `\\' quoting should be
+done; 'quote, meaning that `\"' quoting should be done; 'smart,
+meaning that the choice between 'backslash and 'quote should be
+made depending on the number of hashes inserted; or nil, meaning that
+no quoting should be done. Any other value for this variable is
+taken to mean 'smart. The default is 'smart.")
+
+(defvar tcl-help-directory-list nil
+ "*List of topmost directories containing TclX help files")
+
+(defvar tcl-use-smart-word-finder t
+ "*If not nil, use a better way of finding the current word when
+looking up help on a Tcl command.")
+
+(defvar tcl-application "wish"
+ "*Name of Tcl application to run in inferior Tcl mode.")
+
+(defvar tcl-command-switches nil
+ "*Switches to supply to `tcl-application'.")
+
+(defvar tcl-prompt-regexp "^\\(% \\|\\)"
+ "*If not nil, a regexp that will match the prompt in the inferior process.
+If nil, the prompt is the name of the application with \">\" appended.
+
+The default is \"^\\(% \\|\\)\", which will match the default primary
+and secondary prompts for tclsh and wish.")
+
+(defvar inferior-tcl-source-command "source %s\n"
+ "*Format-string for building a Tcl command to load a file.
+This format string should use `%s' to substitute a file name
+and should result in a Tcl expression that will command the
+inferior Tcl to load that file. The filename will be appropriately
+quoted for Tcl.")
+
+;;
+;; Keymaps, abbrevs, syntax tables.
+;;
+
+(defvar tcl-mode-abbrev-table nil
+ "Abbrev table in use in Tcl-mode buffers.")
+(if tcl-mode-abbrev-table
+ ()
+ (define-abbrev-table 'tcl-mode-abbrev-table ()))
+
+(defvar tcl-mode-map ()
+ "Keymap used in Tcl mode.")
+
+(defvar tcl-mode-syntax-table nil
+ "Syntax table in use in Tcl-mode buffers.")
+(if tcl-mode-syntax-table
+ ()
+ (setq tcl-mode-syntax-table (make-syntax-table))
+ (modify-syntax-entry ?% "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?@ "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?& "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?* "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?+ "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?- "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?. "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?: "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?! "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?$ "_" tcl-mode-syntax-table) ; FIXME use "'"?
+ (modify-syntax-entry ?/ "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?~ "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?< "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?= "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?> "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?| "_" tcl-mode-syntax-table)
+ (modify-syntax-entry ?\( "()" tcl-mode-syntax-table)
+ (modify-syntax-entry ?\) ")(" tcl-mode-syntax-table)
+ (modify-syntax-entry ?\; "." tcl-mode-syntax-table)
+ (modify-syntax-entry ?\n "> " tcl-mode-syntax-table)
+ (modify-syntax-entry ?\f "> " tcl-mode-syntax-table)
+ (modify-syntax-entry ?# "< " tcl-mode-syntax-table))
+
+(defvar inferior-tcl-mode-map nil
+ "Keymap used in Inferior Tcl mode.")
+
+;; XEmacs menu.
+(defvar tcl-xemacs-menu
+ '(["Beginning of function" tcl-beginning-of-defun t]
+ ["End of function" tcl-end-of-defun t]
+ ["Mark function" tcl-mark-defun t]
+ ["Indent region" indent-region (tcl-mark)]
+ ["Comment region" comment-region (tcl-mark)]
+ ["Uncomment region" tcl-uncomment-region (tcl-mark)]
+ "----"
+ ["Show Tcl process buffer" inferior-tcl t]
+ ["Send function to Tcl process" tcl-eval-defun
+ (and inferior-tcl-buffer (get-buffer inferior-tcl-buffer))]
+ ["Send region to Tcl process" tcl-eval-region
+ (and inferior-tcl-buffer (get-buffer inferior-tcl-buffer))]
+ ["Send file to Tcl process" tcl-load-file
+ (and inferior-tcl-buffer (get-buffer inferior-tcl-buffer))]
+ ["Restart Tcl process with file" tcl-restart-with-file t]
+ "----"
+ ["Tcl help" tcl-help-on-word tcl-help-directory-list]
+ ["Send bug report" tcl-submit-bug-report t])
+ "XEmacs menu for Tcl mode.")
+
+;; GNU Emacs does menus via keymaps. Do it in a function in case we
+;; later decide to add it to inferior Tcl mode as well.
+(defun tcl-add-fsf-menu (map)
+ (define-key map [menu-bar] (make-sparse-keymap))
+ ;; This fails in Emacs 19.22 and earlier.
+ (require 'lmenu)
+ (let ((menu (make-lucid-menu-keymap "Tcl" tcl-xemacs-menu)))
+ (define-key map [menu-bar tcl] (cons "Tcl" menu))
+ ;; The following is intended to compute the key sequence
+ ;; information for the menu. It doesn't work.
+ (x-popup-menu nil menu)))
+
+(defun tcl-fill-mode-map ()
+ (define-key tcl-mode-map "{" 'tcl-electric-char)
+ (define-key tcl-mode-map "}" 'tcl-electric-brace)
+ (define-key tcl-mode-map "[" 'tcl-electric-char)
+ (define-key tcl-mode-map "]" 'tcl-electric-char)
+ (define-key tcl-mode-map ";" 'tcl-electric-char)
+ (define-key tcl-mode-map "#" 'tcl-electric-hash)
+ ;; FIXME.
+ (define-key tcl-mode-map "\e\C-a" 'tcl-beginning-of-defun)
+ ;; FIXME.
+ (define-key tcl-mode-map "\e\C-e" 'tcl-end-of-defun)
+ ;; FIXME.
+ (define-key tcl-mode-map "\e\C-h" 'tcl-mark-defun)
+ (define-key tcl-mode-map "\e\C-q" 'indent-tcl-exp)
+ (define-key tcl-mode-map "\177" 'backward-delete-char-untabify)
+ (define-key tcl-mode-map "\t" 'tcl-indent-command)
+ (define-key tcl-mode-map "\M-;" 'tcl-indent-for-comment)
+ (define-key tcl-mode-map "\M-\C-x" 'tcl-eval-defun)
+ (define-key tcl-mode-map "\C-c\C-b" 'tcl-submit-bug-report)
+ (and (fboundp 'comment-region)
+ (define-key tcl-mode-map "\C-c\C-c" 'comment-region))
+ (define-key tcl-mode-map "\C-c\C-i" 'tcl-help-on-word)
+ (define-key tcl-mode-map "\C-c\C-v" 'tcl-eval-defun)
+ (define-key tcl-mode-map "\C-c\C-f" 'tcl-load-file)
+ (define-key tcl-mode-map "\C-c\C-t" 'inferior-tcl)
+ (define-key tcl-mode-map "\C-c\C-x" 'tcl-eval-region)
+ (define-key tcl-mode-map "\C-c\C-s" 'switch-to-tcl)
+
+ ;; Make menus.
+ (if (and tcl-using-emacs-19 (not tcl-using-xemacs-19))
+ (progn
+ (tcl-add-fsf-menu tcl-mode-map))))
+
+(defun tcl-fill-inferior-map ()
+ (define-key inferior-tcl-mode-map "\t" 'comint-dynamic-complete)
+ (define-key inferior-tcl-mode-map "\M-?"
+ 'comint-dynamic-list-filename-completions)
+ (define-key inferior-tcl-mode-map "\e\C-a" 'tcl-beginning-of-defun)
+ (define-key inferior-tcl-mode-map "\e\C-e" 'tcl-end-of-defun)
+ (define-key inferior-tcl-mode-map "\177" 'backward-delete-char-untabify)
+ (define-key inferior-tcl-mode-map "\M-\C-x" 'tcl-eval-defun)
+ (define-key inferior-tcl-mode-map "\C-c\C-b" 'tcl-submit-bug-report)
+ (define-key inferior-tcl-mode-map "\C-c\C-i" 'tcl-help-on-word)
+ (define-key inferior-tcl-mode-map "\C-c\C-v" 'tcl-eval-defun)
+ (define-key inferior-tcl-mode-map "\C-c\C-f" 'tcl-load-file)
+ (define-key inferior-tcl-mode-map "\C-c\C-t" 'inferior-tcl)
+ (define-key inferior-tcl-mode-map "\C-c\C-x" 'tcl-eval-region)
+ (define-key inferior-tcl-mode-map "\C-c\C-s" 'switch-to-tcl))
+
+(if tcl-mode-map
+ ()
+ (setq tcl-mode-map (make-sparse-keymap))
+ (tcl-fill-mode-map))
+
+(if inferior-tcl-mode-map
+ ()
+ ;; FIXME Use keymap inheritance here? FIXME we override comint
+ ;; keybindings here. Maybe someone has a better set?
+ (setq inferior-tcl-mode-map (copy-keymap comint-mode-map))
+ (tcl-fill-inferior-map))
+
+
+(defvar inferior-tcl-buffer nil
+ "*The current inferior-tcl process buffer.
+
+MULTIPLE PROCESS SUPPORT
+===========================================================================
+To run multiple Tcl processes, you start the first up with
+\\[inferior-tcl]. It will be in a buffer named `*inferior-tcl*'.
+Rename this buffer with \\[rename-buffer]. You may now start up a new
+process with another \\[inferior-tcl]. It will be in a new buffer,
+named `*inferior-tcl*'. You can switch between the different process
+buffers with \\[switch-to-buffer].
+
+Commands that send text from source buffers to Tcl processes -- like
+`tcl-eval-defun' or `tcl-load-file' -- have to choose a process to
+send to, when you have more than one Tcl process around. This is
+determined by the global variable `inferior-tcl-buffer'. Suppose you
+have three inferior Lisps running:
+ Buffer Process
+ foo inferior-tcl
+ bar inferior-tcl<2>
+ *inferior-tcl* inferior-tcl<3>
+If you do a \\[tcl-eval-defun] command on some Lisp source code, what
+process do you send it to?
+
+- If you're in a process buffer (foo, bar, or *inferior-tcl*),
+ you send it to that process.
+- If you're in some other buffer (e.g., a source file), you
+ send it to the process attached to buffer `inferior-tcl-buffer'.
+This process selection is performed by function `inferior-tcl-proc'.
+
+Whenever \\[inferior-tcl] fires up a new process, it resets
+`inferior-tcl-buffer' to be the new process's buffer. If you only run
+one process, this does the right thing. If you run multiple
+processes, you can change `inferior-tcl-buffer' to another process
+buffer with \\[set-variable].")
+
+;;
+;; Hooks and other customization.
+;;
+
+(defvar tcl-mode-hook nil
+ "Hook run on entry to Tcl mode.
+
+Several functions exist which are useful to run from your
+`tcl-mode-hook' (see each function's documentation for more
+information):
+
+ tcl-guess-application
+ Guesses a default setting for `tcl-application' based on any
+ \"#!\" line at the top of the file.
+ tcl-hashify-buffer
+ Quotes all \"#\" characters that don't correspond to actual
+ Tcl comments. (Useful when editing code not originally created
+ with this mode).
+ tcl-auto-fill-mode
+ Auto-filling of Tcl comments.
+
+Emacs 19 users can add functions to the hook with `add-hook':
+
+ (add-hook 'tcl-mode-hook 'tcl-guess-application)
+
+Emacs 18 users must use `setq':
+
+ (setq tcl-mode-hook (cons 'tcl-guess-application tcl-mode-hook))")
+
+
+(defvar inferior-tcl-mode-hook nil
+ "Hook for customizing Inferior Tcl mode.")
+
+(defvar tcl-proc-list
+ '("proc" "method" "itcl_class")
+ "List of commands whose first argument defines something.
+This exists because some people (eg, me) use \"defvar\" et al.
+Call `tcl-set-proc-regexp' and `tcl-set-font-lock-keywords'
+after changing this list.")
+
+(defvar tcl-proc-regexp nil
+ "Regexp to use when matching proc headers.")
+
+(defvar tcl-typeword-list
+ '("global" "upvar" "inherit" "public" "protected" "common")
+ "List of Tcl keywords denoting \"type\". Used only for highlighting.
+Call `tcl-set-font-lock-keywords' after changing this list.")
+
+;; Generally I've picked control operators to be keywords.
+(defvar tcl-keyword-list
+ '("if" "then" "else" "elseif" "for" "foreach" "break" "continue" "while"
+ "eval" "case" "in" "switch" "default" "exit" "error" "proc" "return"
+ "uplevel" "constructor" "destructor" "itcl_class" "loop" "for_array_keys"
+ "for_recursive_glob" "for_file")
+ "List of Tcl keywords. Used only for highlighting.
+Default list includes some TclX keywords.
+Call `tcl-set-font-lock-keywords' after changing this list.")
+
+(defvar tcl-font-lock-keywords nil
+ "Keywords to highlight for Tcl. See variable `font-lock-keywords'.
+This variable is generally set from `tcl-proc-regexp',
+`tcl-typeword-list', and `tcl-keyword-list' by the function
+`tcl-set-font-lock-keywords'.")
+
+;; FIXME need some way to recognize variables because array refs look
+;; like 2 sexps.
+(defvar tcl-type-alist
+ '(
+ ("proc" nil tcl-expr tcl-commands)
+ ("method" nil tcl-expr tcl-commands)
+ ("destructor" tcl-commands)
+ ("constructor" tcl-commands)
+ ("expr" tcl-expr)
+ ("catch" tcl-commands)
+ ("if" tcl-expr "then" tcl-commands)
+ ("elseif" tcl-expr "then" tcl-commands)
+ ("elseif" tcl-expr tcl-commands)
+ ("if" tcl-expr tcl-commands)
+ ("while" tcl-expr tcl-commands)
+ ("for" tcl-commands tcl-expr tcl-commands tcl-commands)
+ ("foreach" nil nil tcl-commands)
+ ("for_file" nil nil tcl-commands)
+ ("for_array_keys" nil nil tcl-commands)
+ ("for_recursive_glob" nil nil nil tcl-commands)
+ ;; Loop handling is not perfect, because the third argument can be
+ ;; either a command or an expr, and there is no real way to look
+ ;; forward.
+ ("loop" nil tcl-expr tcl-expr tcl-commands)
+ ("loop" nil tcl-expr tcl-commands)
+ )
+ "Alist that controls indentation.
+\(Actually, this really only controls what happens on continuation lines).
+Each entry looks like `(KEYWORD TYPE ...)'.
+Each type entry describes a sexp after the keyword, and can be one of:
+* nil, meaning that this sexp has no particular type.
+* tcl-expr, meaning that this sexp is an arithmetic expression.
+* tcl-commands, meaning that this sexp holds Tcl commands.
+* a string, which must exactly match the string at the corresponding
+ position for a match to be made.
+
+For example, the entry for the \"loop\" command is:
+
+ (\"loop\" nil tcl-expr tcl-commands)
+
+This means that the \"loop\" command has three arguments. The first
+argument is ignored (for indentation purposes). The second argument
+is a Tcl expression, and the last argument is Tcl commands.")
+
+(defvar tcl-explain-indentation nil
+ "If not `nil', debugging message will be printed during indentation.")
+
+
+
+;;
+;; Work around differences between various versions of Emacs.
+;;
+
+;; We use this because Lemacs 19.9 has what we need.
+(defconst tcl-pps-has-arg-6
+ (or tcl-using-emacs-19
+ (and tcl-using-xemacs-19
+ (condition-case nil
+ (progn
+ (parse-partial-sexp (point) (point) nil nil nil t)
+ t)
+ (error nil))))
+ "t if using an emacs which supports sixth (\"commentstop\") argument
+to parse-partial-sexp.")
+
+;; Its pretty bogus to have to do this, but there is no easier way to
+;; say "match not syntax-1 and not syntax-2". Too bad you can't put
+;; \s in [...]. This sickness is used in Emacs 19 to match a defun
+;; starter. (It is used for this in v18 as well).
+;;(defconst tcl-omit-ws-regexp
+;; (concat "^\\(\\s"
+;; (mapconcat 'char-to-string "w_.()\"\\$'/" "\\|\\s")
+;; "\\)\\S(*")
+;; "Regular expression that matches everything except space, comment
+;;starter, and comment ender syntax codes.")
+
+;; FIXME? Instead of using the hairy regexp above, we just use a
+;; simple one.
+;;(defconst tcl-omit-ws-regexp "^[^] \t\n#}]\\S(*"
+;; "Regular expression used in locating function definitions.")
+
+;; Here's another stab. I think this one actually works. Now the
+;; problem seems to be that there is a bug in Emacs 19.22 where
+;; end-of-defun doesn't really use the brace matching the one that
+;; trails defun-prompt-regexp.
+(defconst tcl-omit-ws-regexp "^[^ \t\n#}][^\n}]+}*[ \t]+")
+
+(defun tcl-internal-beginning-of-defun (&optional arg)
+ "Move backward to next beginning-of-defun.
+With argument, do this that many times.
+Returns t unless search stops due to end of buffer."
+ (interactive "p")
+ (if (or (null arg) (= arg 0))
+ (setq arg 1))
+ (let (success)
+ (while (progn
+ (setq arg (1- arg))
+ (and (>= arg 0)
+ (setq success
+ (re-search-backward tcl-omit-ws-regexp nil 'move 1))))
+ (while (and (looking-at "[]#}]")
+ (setq success
+ (re-search-backward tcl-omit-ws-regexp nil 'move 1)))))
+ (beginning-of-line)
+ (not (null success))))
+
+(defun tcl-internal-end-of-defun (&optional arg)
+ "Move forward to next end of defun.
+An end of a defun is found by moving forward from the beginning of one."
+ (interactive "p")
+ (if (or (null arg) (= arg 0)) (setq arg 1))
+ (let ((start (point)))
+ ;; Was forward-char. I think this works a little better.
+ (forward-line)
+ (tcl-beginning-of-defun)
+ (while (> arg 0)
+ (while (and (re-search-forward tcl-omit-ws-regexp nil 'move 1)
+ (progn (beginning-of-line) t)
+ (looking-at "[]#}]")
+ (progn (forward-line) t)))
+ (let ((next-line (save-excursion
+ (forward-line)
+ (point))))
+ (while (< (point) next-line)
+ (forward-sexp)))
+ (forward-line)
+ (if (> (point) start) (setq arg (1- arg))))))
+
+;; In Emacs 19, we can use begining-of-defun as long as we set up a
+;; certain regexp. In Emacs 18, we need our own function.
+(fset 'tcl-beginning-of-defun
+ (if tcl-using-emacs-19
+ 'beginning-of-defun
+ 'tcl-internal-beginning-of-defun))
+
+;; Ditto end-of-defun.
+(fset 'tcl-end-of-defun
+ (if (and tcl-using-emacs-19 (not tcl-using-xemacs-19))
+ 'end-of-defun
+ 'tcl-internal-end-of-defun))
+
+;; Internal mark-defun that is used for losing Emacsen.
+(defun tcl-internal-mark-defun ()
+ "Put mark at end of Tcl function, point at beginning."
+ (interactive)
+ (push-mark (point))
+ (tcl-end-of-defun)
+ (if tcl-using-emacs-19
+ (push-mark (point) nil t)
+ (push-mark (point)))
+ (tcl-beginning-of-defun)
+ (backward-paragraph))
+
+;; In GNU Emacs 19-23 and later, mark-defun works as advertised. I
+;; don't know about XEmacs, so for now it and Emacs 18 just lose.
+(fset 'tcl-mark-defun
+ (if tcl-using-emacs-19-23
+ 'mark-defun
+ 'tcl-internal-mark-defun))
+
+;; In GNU Emacs 19, mark takes an additional "force" argument. I
+;; don't know about XEmacs, so I'm just assuming it is the same.
+;; Emacs 18 doesn't have this argument.
+(defun tcl-mark ()
+ "Return mark, or nil if none."
+ (if tcl-using-emacs-19
+ (mark t)
+ (mark)))
+
+
+
+;;
+;; Some helper functions.
+;;
+
+(defun tcl-set-proc-regexp ()
+ "Set `tcl-proc-regexp' from variable `tcl-proc-list'."
+ (setq tcl-proc-regexp (concat "^\\s-*\\("
+ (mapconcat 'identity tcl-proc-list "\\|")
+ "\\)[ \t]+")))
+
+(defun tcl-set-font-lock-keywords ()
+ "Set `tcl-font-lock-keywords'.
+Uses variables `tcl-proc-regexp' and `tcl-keyword-list'."
+ (setq tcl-font-lock-keywords
+ (list
+ ;; Names of functions (and other "defining things").
+ (list (concat tcl-proc-regexp "\\([^ \t\n]+\\)")
+ 2 'font-lock-function-name-face)
+
+ ;; Names of type-defining things.
+ (list (concat "\\(\\s-\\|^\\)\\("
+ ;; FIXME Use 'regexp-quote?
+ (mapconcat 'identity tcl-typeword-list "\\|")
+ "\\)\\(\\s-\\|$\\)")
+ 2 'font-lock-type-face)
+
+ ;; Keywords. Only recognized if surrounded by whitespace.
+ ;; FIXME consider using "not word or symbol", not
+ ;; "whitespace".
+ (cons (concat "\\(\\s-\\|^\\)\\("
+ ;; FIXME Use regexp-quote?
+ (mapconcat 'identity tcl-keyword-list "\\|")
+ "\\)\\(\\s-\\|$\\)")
+ 2)
+ )))
+
+(if tcl-proc-regexp
+ ()
+ (tcl-set-proc-regexp))
+
+(if tcl-font-lock-keywords
+ ()
+ (tcl-set-font-lock-keywords))
+
+
+
+;;
+;; The mode itself.
+;;
+
+;;;###autoload
+(defun tcl-mode ()
+ "Major mode for editing Tcl code.
+Expression and list commands understand all Tcl brackets.
+Tab indents for Tcl code.
+Paragraphs are separated by blank lines only.
+Delete converts tabs to spaces as it moves back.
+
+Variables controlling indentation style:
+ tcl-indent-level
+ Indentation of Tcl statements within surrounding block.
+ tcl-continued-indent-level
+ Indentation of continuation line relative to first line of command.
+
+Variables controlling user interaction with mode (see variable
+documentation for details):
+ tcl-tab-always-indent
+ Controls action of TAB key.
+ tcl-auto-newline
+ Non-nil means automatically newline before and after braces, brackets,
+ and semicolons inserted in Tcl code.
+ tcl-electric-hash-style
+ Controls action of `#' key.
+ tcl-use-hairy-comment-detector
+ If t, use more complicated, but slower, comment detector.
+ This variable is only used in GNU Emacs 19.
+ tcl-use-smart-word-finder
+ If not nil, use a smarter, Tcl-specific way to find the current
+ word when looking up help on a Tcl command.
+
+Turning on Tcl mode calls the value of the variable `tcl-mode-hook'
+with no args, if that value is non-nil. Read the documentation for
+`tcl-mode-hook' to see what kinds of interesting hook functions
+already exist.
+
+Commands:
+\\{tcl-mode-map}"
+ (interactive)
+ (kill-all-local-variables)
+ (use-local-map tcl-mode-map)
+ (setq major-mode 'tcl-mode)
+ (setq mode-name "Tcl")
+ (setq local-abbrev-table tcl-mode-abbrev-table)
+ (set-syntax-table tcl-mode-syntax-table)
+
+ (make-local-variable 'paragraph-start)
+ (make-local-variable 'paragraph-separate)
+ (if (and tcl-using-emacs-19-23
+ (>= emacs-minor-version 29))
+ (progn
+ ;; In Emacs 19.29, you aren't supposed to start these with a
+ ;; ^.
+ (setq paragraph-start "$\\| ")
+ (setq paragraph-separate paragraph-start))
+ (setq paragraph-start (concat "^$\\|" page-delimiter))
+ (setq paragraph-separate paragraph-start))
+ (make-local-variable 'paragraph-ignore-fill-prefix)
+ (setq paragraph-ignore-fill-prefix t)
+ (make-local-variable 'fill-paragraph-function)
+ (setq fill-paragraph-function 'tcl-do-fill-paragraph)
+
+ (make-local-variable 'indent-line-function)
+ (setq indent-line-function 'tcl-indent-line)
+ ;; Tcl doesn't require a final newline.
+ ;; (make-local-variable 'require-final-newline)
+ ;; (setq require-final-newline t)
+
+ (make-local-variable 'comment-start)
+ (setq comment-start "# ")
+ (make-local-variable 'comment-start-skip)
+ (setq comment-start-skip "#+ *")
+ (make-local-variable 'comment-column)
+ (setq comment-column 40)
+ (make-local-variable 'comment-end)
+ (setq comment-end "")
+
+ (make-local-variable 'outline-regexp)
+ (setq outline-regexp "[^\n\^M]")
+ (make-local-variable 'outline-level)
+ (setq outline-level 'tcl-outline-level)
+
+ (make-local-variable 'font-lock-keywords)
+ (setq font-lock-keywords tcl-font-lock-keywords)
+
+ ;; The following only really makes sense under GNU Emacs 19.
+ (make-local-variable 'imenu-create-index-function)
+ (setq imenu-create-index-function 'tcl-imenu-create-index-function)
+ (make-local-variable 'parse-sexp-ignore-comments)
+
+ ;; Settings for new dabbrev code.
+ (make-local-variable 'dabbrev-case-fold-search)
+ (setq dabbrev-case-fold-search nil)
+ (make-local-variable 'dabbrev-case-replace)
+ (setq dabbrev-case-replace nil)
+ (make-local-variable 'dabbrev-abbrev-skip-leading-regexp)
+ (setq dabbrev-abbrev-skip-leading-regexp "[$!]")
+ (make-local-variable 'dabbrev-abbrev-char-regexp)
+ (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
+
+ (if tcl-using-emacs-19
+ (progn
+ ;; This can only be set to t in Emacs 19 and XEmacs.
+ ;; Emacs 18 and Epoch lose.
+ (setq parse-sexp-ignore-comments t)
+ ;; XEmacs has defun-prompt-regexp, but I don't believe
+ ;; that it works for end-of-defun -- only for
+ ;; beginning-of-defun.
+ (make-local-variable 'defun-prompt-regexp)
+ (setq defun-prompt-regexp tcl-omit-ws-regexp)
+ ;; The following doesn't work in Lucid Emacs 19.6, but maybe
+ ;; it will appear in later versions.
+ (make-local-variable 'add-log-current-defun-function)
+ (setq add-log-current-defun-function 'add-log-tcl-defun))
+ (setq parse-sexp-ignore-comments nil))
+
+ ;; Put Tcl menu into menubar for XEmacs. This happens
+ ;; automatically for GNU Emacs.
+ (if (and tcl-using-xemacs-19
+ current-menubar
+ (not (assoc "Tcl" current-menubar)))
+ (progn
+ (set-buffer-menubar (copy-sequence current-menubar))
+ (add-menu nil "Tcl" tcl-xemacs-menu)))
+ ;; Append Tcl menu to popup menu for XEmacs.
+ (if (and tcl-using-xemacs-19 (boundp 'mode-popup-menu))
+ (setq mode-popup-menu
+ (cons (concat mode-name " Mode Commands") tcl-xemacs-menu)))
+
+ ;; If hilit19 is loaded, add our stuff.
+ (if (featurep 'hilit19)
+ (tcl-hilit))
+
+ (run-hooks 'tcl-mode-hook))
+
+
+
+;; This is used for braces, brackets, and semi (except for closing
+;; braces, which are handled specially).
+(defun tcl-electric-char (arg)
+ "Insert character and correct line's indentation."
+ (interactive "p")
+ ;; Indent line first; this looks better if parens blink.
+ (tcl-indent-line)
+ (self-insert-command arg)
+ (if (and tcl-auto-newline (= last-command-char ?\;))
+ (progn
+ (newline)
+ (tcl-indent-line))))
+
+;; This is used for closing braces. If tcl-auto-newline is set, can
+;; insert a newline both before and after the brace, depending on
+;; context. FIXME should this be configurable? Does anyone use this?
+(defun tcl-electric-brace (arg)
+ "Insert character and correct line's indentation."
+ (interactive "p")
+ ;; If auto-newlining and there is stuff on the same line, insert a
+ ;; newline first.
+ (if tcl-auto-newline
+ (progn
+ (if (save-excursion
+ (skip-chars-backward " \t")
+ (bolp))
+ ()
+ (tcl-indent-line)
+ (newline))
+ ;; In auto-newline case, must insert a newline after each
+ ;; brace. So an explicit loop is needed.
+ (while (> arg 0)
+ (insert last-command-char)
+ (tcl-indent-line)
+ (newline)
+ (setq arg (1- arg))))
+ (self-insert-command arg))
+ (tcl-indent-line))
+
+
+
+(defun tcl-indent-command (&optional arg)
+ "Indent current line as Tcl code, or in some cases insert a tab character.
+If tcl-tab-always-indent is t (the default), always indent current line.
+If tcl-tab-always-indent is nil and point is not in the indentation
+area at the beginning of the line, a TAB is inserted.
+Other values of tcl-tab-always-indent cause the first possible action
+from the following list to take place:
+
+ 1. Move from beginning of line to correct indentation.
+ 2. Delete an empty comment.
+ 3. Move forward to start of comment, indenting if necessary.
+ 4. Move forward to end of line, indenting if necessary.
+ 5. Create an empty comment.
+ 6. Move backward to start of comment, indenting if necessary."
+ (interactive "p")
+ (cond
+ ((not tcl-tab-always-indent)
+ ;; Indent if in indentation area, otherwise insert TAB.
+ (if (<= (current-column) (current-indentation))
+ (tcl-indent-line)
+ (self-insert-command arg)))
+ ((eq tcl-tab-always-indent t)
+ ;; Always indent.
+ (tcl-indent-line))
+ (t
+ ;; "Perl-mode" style TAB command.
+ (let* ((ipoint (point))
+ (eolpoint (progn
+ (end-of-line)
+ (point)))
+ (comment-p (tcl-in-comment)))
+ (cond
+ ((= ipoint (save-excursion
+ (beginning-of-line)
+ (point)))
+ (beginning-of-line)
+ (tcl-indent-line)
+ ;; If indenting didn't leave us in column 0, go to the
+ ;; indentation. Otherwise leave point at end of line. This
+ ;; is a hack.
+ (if (= (point) (save-excursion
+ (beginning-of-line)
+ (point)))
+ (end-of-line)
+ (back-to-indentation)))
+ ((and comment-p (looking-at "[ \t]*$"))
+ ;; Empty comment, so delete it. We also delete any ";"
+ ;; characters at the end of the line. I think this is
+ ;; friendlier, but I don't know how other people will feel.
+ (backward-char)
+ (skip-chars-backward " \t;")
+ (delete-region (point) eolpoint))
+ ((and comment-p (< ipoint (point)))
+ ;; Before comment, so skip to it.
+ (tcl-indent-line)
+ (indent-for-comment))
+ ((/= ipoint eolpoint)
+ ;; Go to end of line (since we're not there yet).
+ (goto-char eolpoint)
+ (tcl-indent-line))
+ ((not comment-p)
+ (tcl-indent-line)
+ (tcl-indent-for-comment))
+ (t
+ ;; Go to start of comment. We don't leave point where it is
+ ;; because we want to skip comment-start-skip.
+ (tcl-indent-line)
+ (indent-for-comment)))))))
+
+(defun tcl-indent-line ()
+ "Indent current line as Tcl code.
+Return the amount the indentation changed by."
+ (let ((indent (calculate-tcl-indent nil))
+ beg shift-amt
+ (case-fold-search nil)
+ (pos (- (point-max) (point))))
+ (beginning-of-line)
+ (setq beg (point))
+ (cond ((eq indent nil)
+ (setq indent (current-indentation)))
+ (t
+ (skip-chars-forward " \t")
+ (if (listp indent) (setq indent (car indent)))
+ (cond ((= (following-char) ?})
+ (setq indent (- indent tcl-indent-level)))
+ ((= (following-char) ?\])
+ (setq indent (- indent 1))))))
+ (skip-chars-forward " \t")
+ (setq shift-amt (- indent (current-column)))
+ (if (zerop shift-amt)
+ (if (> (- (point-max) pos) (point))
+ (goto-char (- (point-max) pos)))
+ (delete-region beg (point))
+ (indent-to indent)
+ ;; If initial point was within line's indentation,
+ ;; position after the indentation. Else stay at same point in text.
+ (if (> (- (point-max) pos) (point))
+ (goto-char (- (point-max) pos))))
+ shift-amt))
+
+(defun tcl-figure-type ()
+ "Determine type of sexp at point.
+This is either 'tcl-expr, 'tcl-commands, or nil. Puts point at start
+of sexp that indicates types.
+
+See documentation for variable `tcl-type-alist' for more information."
+ (let ((count 0)
+ result
+ word-stack)
+ (while (and (< count 5)
+ (not result))
+ (condition-case nil
+ (progn
+ ;; FIXME should use "tcl-backward-sexp", which would skip
+ ;; over entire variables, etc.
+ (backward-sexp)
+ (if (looking-at "[a-zA-Z_]+")
+ (let ((list tcl-type-alist)
+ entry)
+ (setq word-stack (cons (tcl-word-no-props) word-stack))
+ (while (and list (not result))
+ (setq entry (car list))
+ (setq list (cdr list))
+ (let ((index 0))
+ (while (and entry (<= index count))
+ ;; Abort loop if string does not match word on
+ ;; stack.
+ (and (stringp (car entry))
+ (not (string= (car entry)
+ (nth index word-stack)))
+ (setq entry nil))
+ (setq entry (cdr entry))
+ (setq index (1+ index)))
+ (and (> index count)
+ (not (stringp (car entry)))
+ (setq result (car entry)))
+ )))
+ (setq word-stack (cons nil word-stack))))
+ (error nil))
+ (setq count (1+ count)))
+ (and tcl-explain-indentation
+ (message "Indentation type %s" result))
+ result))
+
+(defun calculate-tcl-indent (&optional parse-start)
+ "Return appropriate indentation for current line as Tcl code.
+In usual case returns an integer: the column to indent to.
+Returns nil if line starts inside a string, t if in a comment."
+ (save-excursion
+ (beginning-of-line)
+ (let* ((indent-point (point))
+ (case-fold-search nil)
+ (continued-line
+ (save-excursion
+ (if (bobp)
+ nil
+ (backward-char)
+ (= ?\\ (preceding-char)))))
+ (continued-indent-value (if continued-line
+ tcl-continued-indent-level
+ 0))
+ state
+ containing-sexp
+ found-next-line)
+ (if parse-start
+ (goto-char parse-start)
+ (tcl-beginning-of-defun))
+ (while (< (point) indent-point)
+ (setq parse-start (point))
+ (setq state (parse-partial-sexp (point) indent-point 0))
+ (setq containing-sexp (car (cdr state))))
+ (cond ((or (nth 3 state) (nth 4 state))
+ ;; Inside comment or string. Return nil or t if should
+ ;; not change this line
+ (nth 4 state))
+ ((null containing-sexp)
+ ;; Line is at top level.
+ continued-indent-value)
+ (t
+ ;; Set expr-p if we are looking at the expression part of
+ ;; an "if", "expr", etc statement. Set commands-p if we
+ ;; are looking at the body part of an if, while, etc
+ ;; statement. FIXME Should check for "for" loops here.
+ (goto-char containing-sexp)
+ (let* ((sexpr-type (tcl-figure-type))
+ (expr-p (eq sexpr-type 'tcl-expr))
+ (commands-p (eq sexpr-type 'tcl-commands))
+ (expr-start (point)))
+ ;; Find the first statement in the block and indent
+ ;; like it. The first statement in the block might be
+ ;; on the same line, so what we do is skip all
+ ;; "virtually blank" lines, looking for a non-blank
+ ;; one. A line is virtually blank if it only contains
+ ;; a comment and whitespace. FIXME continued comments
+ ;; aren't supported. They are a wart on Tcl anyway.
+ ;; We do it this funky way because we want to know if
+ ;; we've found a statement on some line _after_ the
+ ;; line holding the sexp opener.
+ (goto-char containing-sexp)
+ (forward-char)
+ (if (and (< (point) indent-point)
+ (looking-at "[ \t]*\\(#.*\\)?$"))
+ (progn
+ (forward-line)
+ (while (and (< (point) indent-point)
+ (looking-at "[ \t]*\\(#.*\\)?$"))
+ (setq found-next-line t)
+ (forward-line))))
+ (if (or continued-line
+ (/= (char-after containing-sexp) ?{)
+ expr-p)
+ (progn
+ ;; Line is continuation line, or the sexp opener
+ ;; is not a curly brace, or we are are looking at
+ ;; an `expr' expression (which must be split
+ ;; specially). So indentation is column of first
+ ;; good spot after sexp opener (with some added
+ ;; in the continued-line case). If there is no
+ ;; nonempty line before the indentation point, we
+ ;; use the column of the character after the sexp
+ ;; opener.
+ (if (>= (point) indent-point)
+ (progn
+ (goto-char containing-sexp)
+ (forward-char))
+ (skip-chars-forward " \t"))
+ (+ (current-column) continued-indent-value))
+ ;; After a curly brace, and not a continuation line.
+ ;; So take indentation from first good line after
+ ;; start of block, unless that line is on the same
+ ;; line as the opening brace. In this case use the
+ ;; indentation of the opening brace's line, plus
+ ;; another indent step. If we are in the body part
+ ;; of an "if" or "while" then the indentation is
+ ;; taken from the line holding the start of the
+ ;; statement.
+ (if (and (< (point) indent-point)
+ found-next-line)
+ (current-indentation)
+ (if commands-p
+ (goto-char expr-start)
+ (goto-char containing-sexp))
+ (+ (current-indentation) tcl-indent-level)))))))))
+
+
+
+(defun indent-tcl-exp ()
+ "Indent each line of the Tcl grouping following point."
+ (interactive)
+ (let ((indent-stack (list nil))
+ (contain-stack (list (point)))
+ (case-fold-search nil)
+ outer-loop-done inner-loop-done state ostate
+ this-indent last-sexp continued-line
+ (next-depth 0)
+ last-depth)
+ (save-excursion
+ (forward-sexp 1))
+ (save-excursion
+ (setq outer-loop-done nil)
+ (while (and (not (eobp)) (not outer-loop-done))
+ (setq last-depth next-depth)
+ ;; Compute how depth changes over this line
+ ;; plus enough other lines to get to one that
+ ;; does not end inside a comment or string.
+ ;; Meanwhile, do appropriate indentation on comment lines.
+ (setq inner-loop-done nil)
+ (while (and (not inner-loop-done)
+ (not (and (eobp) (setq outer-loop-done t))))
+ (setq ostate state)
+ (setq state (parse-partial-sexp (point) (progn (end-of-line) (point))
+ nil nil state))
+ (setq next-depth (car state))
+ (if (and (car (cdr (cdr state)))
+ (>= (car (cdr (cdr state))) 0))
+ (setq last-sexp (car (cdr (cdr state)))))
+ (if (or (nth 4 ostate))
+ (tcl-indent-line))
+ (if (or (nth 3 state))
+ (forward-line 1)
+ (setq inner-loop-done t)))
+ (if (<= next-depth 0)
+ (setq outer-loop-done t))
+ (if outer-loop-done
+ nil
+ ;; If this line had ..))) (((.. in it, pop out of the levels
+ ;; that ended anywhere in this line, even if the final depth
+ ;; doesn't indicate that they ended.
+ (while (> last-depth (nth 6 state))
+ (setq indent-stack (cdr indent-stack)
+ contain-stack (cdr contain-stack)
+ last-depth (1- last-depth)))
+ (if (/= last-depth next-depth)
+ (setq last-sexp nil))
+ ;; Add levels for any parens that were started in this line.
+ (while (< last-depth next-depth)
+ (setq indent-stack (cons nil indent-stack)
+ contain-stack (cons nil contain-stack)
+ last-depth (1+ last-depth)))
+ (if (null (car contain-stack))
+ (setcar contain-stack
+ (or (car (cdr state))
+ (save-excursion
+ (forward-sexp -1)
+ (point)))))
+ (forward-line 1)
+ (setq continued-line
+ (save-excursion
+ (backward-char)
+ (= (preceding-char) ?\\)))
+ (skip-chars-forward " \t")
+ (if (eolp)
+ nil
+ (if (and (car indent-stack)
+ (>= (car indent-stack) 0))
+ ;; Line is on an existing nesting level.
+ (setq this-indent (car indent-stack))
+ ;; Just started a new nesting level.
+ ;; Compute the standard indent for this level.
+ (let ((val (calculate-tcl-indent
+ (if (car indent-stack)
+ (- (car indent-stack))))))
+ (setcar indent-stack
+ (setq this-indent val))
+ (setq continued-line nil)))
+ (cond ((not (numberp this-indent)))
+ ((= (following-char) ?})
+ (setq this-indent (- this-indent tcl-indent-level)))
+ ((= (following-char) ?\])
+ (setq this-indent (- this-indent 1))))
+ ;; Put chosen indentation into effect.
+ (or (null this-indent)
+ (= (current-column)
+ (if continued-line
+ (+ this-indent tcl-indent-level)
+ this-indent))
+ (progn
+ (delete-region (point) (progn (beginning-of-line) (point)))
+ (indent-to
+ (if continued-line
+ (+ this-indent tcl-indent-level)
+ this-indent)))))))))
+ )
+
+
+
+;;
+;; Interfaces to other packages.
+;;
+
+(defun tcl-imenu-create-index-function ()
+ "Generate alist of indices for imenu."
+ (let ((re (concat tcl-proc-regexp "\\([^ \t\n{]+\\)"))
+ alist prev-pos)
+ (goto-char (point-min))
+ (imenu-progress-message prev-pos 0)
+ (save-match-data
+ (while (re-search-forward re nil t)
+ (imenu-progress-message prev-pos)
+ ;; Position on start of proc name, not beginning of line.
+ (setq alist (cons
+ (cons (buffer-substring (match-beginning 2) (match-end 2))
+ (match-beginning 2))
+ alist))))
+ (imenu-progress-message prev-pos 100)
+ (nreverse alist)))
+
+;; FIXME Definition of function is very ad-hoc. Should use
+;; tcl-beginning-of-defun. Also has incestuous knowledge about the
+;; format of tcl-proc-regexp.
+(defun add-log-tcl-defun ()
+ "Return name of Tcl function point is in, or nil."
+ (save-excursion
+ (end-of-line)
+ (if (re-search-backward (concat tcl-proc-regexp "\\([^ \t\n{]+\\)") nil t)
+ (buffer-substring (match-beginning 2)
+ (match-end 2)))))
+
+(defun tcl-outline-level ()
+ (save-excursion
+ (skip-chars-forward " \t")
+ (current-column)))
+
+
+
+;;
+;; Helper functions for inferior Tcl mode.
+;;
+
+;; This exists to let us delete the prompt when commands are sent
+;; directly to the inferior Tcl. See gud.el for an explanation of how
+;; it all works (I took it from there). This stuff doesn't really
+;; work as well as I'd like it to. But I don't believe there is
+;; anything useful that can be done.
+(defvar inferior-tcl-delete-prompt-marker nil)
+
+(defun tcl-filter (proc string)
+ (let ((inhibit-quit t))
+ (save-excursion
+ (set-buffer (process-buffer proc))
+ (goto-char (process-mark proc))
+ ;; Delete prompt if requested.
+ (if (marker-buffer inferior-tcl-delete-prompt-marker)
+ (progn
+ (delete-region (point) inferior-tcl-delete-prompt-marker)
+ (set-marker inferior-tcl-delete-prompt-marker nil)))))
+ (if tcl-using-emacs-19
+ (comint-output-filter proc string)
+ (funcall comint-output-filter string)))
+
+(defun tcl-send-string (proc string)
+ (save-excursion
+ (set-buffer (process-buffer proc))
+ (goto-char (process-mark proc))
+ (beginning-of-line)
+ (if (looking-at comint-prompt-regexp)
+ (set-marker inferior-tcl-delete-prompt-marker (point))))
+ (comint-send-string proc string))
+
+(defun tcl-send-region (proc start end)
+ (save-excursion
+ (set-buffer (process-buffer proc))
+ (goto-char (process-mark proc))
+ (beginning-of-line)
+ (if (looking-at comint-prompt-regexp)
+ (set-marker inferior-tcl-delete-prompt-marker (point))))
+ (comint-send-region proc start end))
+
+(defun switch-to-tcl (eob-p)
+ "Switch to inferior Tcl process buffer.
+With argument, positions cursor at end of buffer."
+ (interactive "P")
+ (if (get-buffer inferior-tcl-buffer)
+ (pop-to-buffer inferior-tcl-buffer)
+ (error "No current inferior Tcl buffer"))
+ (cond (eob-p
+ (push-mark)
+ (goto-char (point-max)))))
+
+(defun inferior-tcl-proc ()
+ "Return current inferior Tcl process.
+See variable `inferior-tcl-buffer'."
+ (let ((proc (get-buffer-process (if (eq major-mode 'inferior-tcl-mode)
+ (current-buffer)
+ inferior-tcl-buffer))))
+ (or proc
+ (error "No Tcl process; see variable `inferior-tcl-buffer'"))))
+
+(defun tcl-eval-region (start end &optional and-go)
+ "Send the current region to the inferior Tcl process.
+Prefix argument means switch to the Tcl buffer afterwards."
+ (interactive "r\nP")
+ (let ((proc (inferior-tcl-proc)))
+ (tcl-send-region proc start end)
+ (tcl-send-string proc "\n")
+ (if and-go (switch-to-tcl t))))
+
+(defun tcl-eval-defun (&optional and-go)
+ "Send the current defun to the inferior Tcl process.
+Prefix argument means switch to the Tcl buffer afterwards."
+ (interactive "P")
+ (save-excursion
+ (tcl-end-of-defun)
+ (let ((end (point)))
+ (tcl-beginning-of-defun)
+ (tcl-eval-region (point) end)))
+ (if and-go (switch-to-tcl t)))
+
+
+
+;;
+;; Inferior Tcl mode itself.
+;;
+
+(defun inferior-tcl-mode ()
+ "Major mode for interacting with Tcl interpreter.
+
+A Tcl process can be started with M-x inferior-tcl.
+
+Entry to this mode runs the hooks comint-mode-hook and
+inferior-tcl-mode-hook, in that order.
+
+You can send text to the inferior Tcl process from other buffers
+containing Tcl source.
+
+Variables controlling Inferior Tcl mode:
+ tcl-application
+ Name of program to run.
+ tcl-command-switches
+ Command line arguments to `tcl-application'.
+ tcl-prompt-regexp
+ Matches prompt.
+ inferior-tcl-source-command
+ Command to use to read Tcl file in running application.
+ inferior-tcl-buffer
+ The current inferior Tcl process buffer. See variable
+ documentation for details on multiple-process support.
+
+The following commands are available:
+\\{inferior-tcl-mode-map}"
+ (interactive)
+ (comint-mode)
+ (setq comint-prompt-regexp (or tcl-prompt-regexp
+ (concat "^"
+ (regexp-quote tcl-application)
+ ">")))
+ (setq major-mode 'inferior-tcl-mode)
+ (setq mode-name "Inferior Tcl")
+ (if (boundp 'modeline-process)
+ (setq modeline-process '(": %s")) ; For XEmacs.
+ (setq mode-line-process '(": %s")))
+ (use-local-map inferior-tcl-mode-map)
+ (setq local-abbrev-table tcl-mode-abbrev-table)
+ (set-syntax-table tcl-mode-syntax-table)
+ (if tcl-using-emacs-19
+ (progn
+ (make-local-variable 'defun-prompt-regexp)
+ (setq defun-prompt-regexp tcl-omit-ws-regexp)))
+ (make-local-variable 'inferior-tcl-delete-prompt-marker)
+ (setq inferior-tcl-delete-prompt-marker (make-marker))
+ (set-process-filter (get-buffer-process (current-buffer)) 'tcl-filter)
+ (run-hooks 'inferior-tcl-mode-hook))
+
+;;;###autoload
+(defun inferior-tcl (cmd)
+ "Run inferior Tcl process.
+Prefix arg means enter program name interactively.
+See documentation for function `inferior-tcl-mode' for more information."
+ (interactive
+ (list (if current-prefix-arg
+ (read-string "Run Tcl: " tcl-application)
+ tcl-application)))
+ (if (not (comint-check-proc "*inferior-tcl*"))
+ (progn
+ (set-buffer (apply (function make-comint) "inferior-tcl" cmd nil
+ tcl-command-switches))
+ (inferior-tcl-mode)))
+ (make-local-variable 'tcl-application)
+ (setq tcl-application cmd)
+ (setq inferior-tcl-buffer "*inferior-tcl*")
+ (switch-to-buffer "*inferior-tcl*"))
+
+(and (fboundp 'defalias)
+ (defalias 'run-tcl 'inferior-tcl))
+
+
+
+;;
+;; Auto-fill support.
+;;
+
+(defun tcl-real-command-p ()
+ "Return nil if point is not at the beginning of a command.
+A command is the first word on an otherwise empty line, or the
+first word following a semicolon, opening brace, or opening bracket."
+ (save-excursion
+ (skip-chars-backward " \t")
+ (cond
+ ((bobp) t)
+ ((bolp)
+ (backward-char)
+ ;; Note -- continued comments are not supported here. I
+ ;; consider those to be a wart on the language.
+ (not (eq ?\\ (preceding-char))))
+ (t
+ (memq (preceding-char) '(?\; ?{ ?\[))))))
+
+;; FIXME doesn't actually return t. See last case.
+(defun tcl-real-comment-p ()
+ "Return t if point is just after the `#' beginning a real comment.
+Does not check to see if previous char is actually `#'.
+A real comment is either at the beginning of the buffer,
+preceeded only by whitespace on the line, or has a preceeding
+semicolon, opening brace, or opening bracket on the same line."
+ (save-excursion
+ (backward-char)
+ (tcl-real-command-p)))
+
+(defun tcl-hairy-scan-for-comment (state end always-stop)
+ "Determine if point is in a comment.
+Returns a list of the form `(FLAG . STATE)'. STATE can be used
+as input to future invocations. FLAG is nil if not in comment,
+t otherwise. If in comment, leaves point at beginning of comment.
+Only works in Emacs 19. See also `tcl-simple-scan-for-comment', a
+simpler version that is often right, and works in Emacs 18."
+ (let ((bol (save-excursion
+ (goto-char end)
+ (beginning-of-line)
+ (point)))
+ real-comment
+ last-cstart)
+ (while (and (not last-cstart) (< (point) end))
+ (setq real-comment nil) ;In case we've looped around and it is
+ ;set.
+ (setq state (parse-partial-sexp (point) end nil nil state t))
+ (if (nth 4 state)
+ (progn
+ ;; If ALWAYS-STOP is set, stop even if we don't have a
+ ;; real comment, or if the comment isn't on the same line
+ ;; as the end.
+ (if always-stop (setq last-cstart (point)))
+ ;; If we have a real comment, then set the comment
+ ;; starting point if we are on the same line as the ending
+ ;; location.
+ (setq real-comment (tcl-real-comment-p))
+ (if real-comment
+ (progn
+ (and (> (point) bol) (setq last-cstart (point)))
+ ;; NOTE Emacs 19 has a misfeature whereby calling
+ ;; parse-partial-sexp with COMMENTSTOP set and with
+ ;; an initial list that says point is in a comment
+ ;; will cause an immediate return. So we must skip
+ ;; over the comment ourselves.
+ (beginning-of-line 2)))
+ ;; Frob the state to make it look like we aren't in a
+ ;; comment.
+ (setcar (nthcdr 4 state) nil))))
+ (and last-cstart
+ (goto-char last-cstart))
+ (cons real-comment state)))
+
+(defun tcl-hairy-in-comment ()
+ "Return t if point is in a comment, and leave point at beginning
+of comment."
+ (let ((save (point)))
+ (tcl-beginning-of-defun)
+ (car (tcl-hairy-scan-for-comment nil save nil))))
+
+(defun tcl-simple-in-comment ()
+ "Return t if point is in comment, and leave point at beginning
+of comment. This is faster that `tcl-hairy-in-comment', but is
+correct less often."
+ (let ((save (point))
+ comment)
+ (beginning-of-line)
+ (while (and (< (point) save) (not comment))
+ (search-forward "#" save 'move)
+ (setq comment (tcl-real-comment-p)))
+ comment))
+
+(defun tcl-in-comment ()
+ "Return t if point is in comment, and leave point at beginning
+of comment."
+ (if (and tcl-pps-has-arg-6
+ tcl-use-hairy-comment-detector)
+ (tcl-hairy-in-comment)
+ (tcl-simple-in-comment)))
+
+(defun tcl-do-fill-paragraph (ignore)
+ "fill-paragraph function for Tcl mode. Only fills in a comment."
+ (let (in-comment col where)
+ (save-excursion
+ (end-of-line)
+ (setq in-comment (tcl-in-comment))
+ (if in-comment
+ (progn
+ (setq where (1+ (point)))
+ (setq col (1- (current-column))))))
+ (and in-comment
+ (save-excursion
+ (back-to-indentation)
+ (= col (current-column)))
+ ;; In a comment. Set the fill prefix, and find the paragraph
+ ;; boundaries by searching for lines that look like
+ ;; comment-only lines.
+ (let ((fill-prefix (buffer-substring (progn
+ (beginning-of-line)
+ (point))
+ where))
+ p-start p-end)
+ ;; Search backwards.
+ (save-excursion
+ (while (looking-at "^[ \t]*#")
+ (forward-line -1))
+ (forward-line)
+ (setq p-start (point)))
+
+ ;; Search forwards.
+ (save-excursion
+ (while (looking-at "^[ \t]*#")
+ (forward-line))
+ (setq p-end (point)))
+
+ ;; Narrow and do the fill.
+ (save-restriction
+ (narrow-to-region p-start p-end)
+ (fill-paragraph ignore)))))
+ t)
+
+(defun tcl-do-auto-fill ()
+ "Auto-fill function for Tcl mode. Only auto-fills in a comment."
+ (if (> (current-column) fill-column)
+ (let ((fill-prefix "# ")
+ in-comment col)
+ (save-excursion
+ (setq in-comment (tcl-in-comment))
+ (if in-comment
+ (setq col (1- (current-column)))))
+ (if in-comment
+ (progn
+ (do-auto-fill)
+ (save-excursion
+ (back-to-indentation)
+ (delete-region (point) (save-excursion
+ (beginning-of-line)
+ (point)))
+ (indent-to-column col)))))))
+
+
+
+;;
+;; Help-related code.
+;;
+
+(defvar tcl-help-saved-dirs nil
+ "Saved help directories.
+If `tcl-help-directory-list' changes, this allows `tcl-help-on-word'
+to update the alist.")
+
+(defvar tcl-help-alist nil
+ "Alist with command names as keys and filenames as values.")
+
+(defun tcl-help-snarf-commands (dirlist)
+ "Build alist of commands and filenames."
+ (while dirlist
+ (let ((files (directory-files (car dirlist) t)))
+ (while files
+ (if (and (file-directory-p (car files))
+ (not
+ (let ((fpart (file-name-nondirectory (car files))))
+ (or (equal fpart ".")
+ (equal fpart "..")))))
+ (let ((matches (directory-files (car files) t)))
+ (while matches
+ (or (file-directory-p (car matches))
+ (setq tcl-help-alist
+ (cons
+ (cons (file-name-nondirectory (car matches))
+ (car matches))
+ tcl-help-alist)))
+ (setq matches (cdr matches)))))
+ (setq files (cdr files))))
+ (setq dirlist (cdr dirlist))))
+
+(defun tcl-reread-help-files ()
+ "Set up to re-read files, and then do it."
+ (interactive)
+ (message "Building Tcl help file index...")
+ (setq tcl-help-saved-dirs tcl-help-directory-list)
+ (setq tcl-help-alist nil)
+ (tcl-help-snarf-commands tcl-help-directory-list)
+ (message "Building Tcl help file index...done"))
+
+(defun tcl-word-no-props ()
+ "Like current-word, but strips properties."
+ (let ((word (current-word)))
+ (and (fboundp 'set-text-properties)
+ (set-text-properties 0 (length word) nil word))
+ word))
+
+(defun tcl-current-word (flag)
+ "Return current command word, or nil.
+If FLAG is nil, just uses `current-word'.
+Otherwise scans backward for most likely Tcl command word."
+ (if (and flag
+ (memq major-mode '(tcl-mode inferior-tcl-mode)))
+ (condition-case nil
+ (save-excursion
+ ;; Look backward for first word actually in alist.
+ (if (bobp)
+ ()
+ (while (and (not (bobp))
+ (not (tcl-real-command-p)))
+ (backward-sexp)))
+ (if (assoc (tcl-word-no-props) tcl-help-alist)
+ (tcl-word-no-props)))
+ (error nil))
+ (tcl-word-no-props)))
+
+;;;###autoload
+(defun tcl-help-on-word (command &optional arg)
+ "Get help on Tcl command. Default is word at point.
+Prefix argument means invert sense of `tcl-use-smart-word-finder'."
+ (interactive
+ (list
+ (progn
+ (if (not (equal tcl-help-directory-list tcl-help-saved-dirs))
+ (tcl-reread-help-files))
+ (let ((word (tcl-current-word
+ (if current-prefix-arg
+ (not tcl-use-smart-word-finder)
+ tcl-use-smart-word-finder))))
+ (completing-read
+ (if (or (null word) (string= word ""))
+ "Help on Tcl command: "
+ (format "Help on Tcl command (default %s): " word))
+ tcl-help-alist nil t)))
+ current-prefix-arg))
+ (if (not (equal tcl-help-directory-list tcl-help-saved-dirs))
+ (tcl-reread-help-files))
+ (if (string= command "")
+ (setq command (tcl-current-word
+ (if arg
+ (not tcl-use-smart-word-finder)
+ tcl-use-smart-word-finder))))
+ (let* ((help (get-buffer-create "*Tcl help*"))
+ (cell (assoc command tcl-help-alist))
+ (file (and cell (cdr cell))))
+ (set-buffer help)
+ (delete-region (point-min) (point-max))
+ (if file
+ (progn
+ (insert "*** " command "\n\n")
+ (insert-file-contents file))
+ (if (string= command "")
+ (insert "Magical Pig!")
+ (insert "Tcl command " command " not in help\n")))
+ (set-buffer-modified-p nil)
+ (goto-char (point-min))
+ (display-buffer help)))
+
+
+
+;;
+;; Other interactive stuff.
+;;
+
+(defvar tcl-previous-dir/file nil
+ "Record last directory and file used in loading.
+This holds a cons cell of the form `(DIRECTORY . FILE)'
+describing the last `tcl-load-file' command.")
+
+(defun tcl-load-file (file &optional and-go)
+ "Load a Tcl file into the inferior Tcl process.
+Prefix argument means switch to the Tcl buffer afterwards."
+ (interactive
+ (list
+ ;; car because comint-get-source returns a list holding the
+ ;; filename.
+ (car (comint-get-source "Load Tcl file: "
+ (or (and
+ (eq major-mode 'tcl-mode)
+ (buffer-file-name))
+ tcl-previous-dir/file)
+ '(tcl-mode) t))
+ current-prefix-arg))
+ (comint-check-source file)
+ (setq tcl-previous-dir/file (cons (file-name-directory file)
+ (file-name-nondirectory file)))
+ (tcl-send-string (inferior-tcl-proc)
+ (format inferior-tcl-source-command (tcl-quote file)))
+ (if and-go (switch-to-tcl t)))
+
+(defun tcl-restart-with-file (file &optional and-go)
+ "Restart inferior Tcl with file.
+If an inferior Tcl process exists, it is killed first.
+Prefix argument means switch to the Tcl buffer afterwards."
+ (interactive
+ (list
+ (car (comint-get-source "Restart with Tcl file: "
+ (or (and
+ (eq major-mode 'tcl-mode)
+ (buffer-file-name))
+ tcl-previous-dir/file)
+ '(tcl-mode) t))
+ current-prefix-arg))
+ (let* ((buf (if (eq major-mode 'inferior-tcl-mode)
+ (current-buffer)
+ inferior-tcl-buffer))
+ (proc (and buf (get-process buf))))
+ (cond
+ ((not (and buf (get-buffer buf)))
+ ;; I think this will be ok.
+ (inferior-tcl tcl-application)
+ (tcl-load-file file and-go))
+ ((or
+ (not (comint-check-proc buf))
+ (yes-or-no-p
+ "A Tcl process is running, are you sure you want to reset it? "))
+ (save-excursion
+ (comint-check-source file)
+ (setq tcl-previous-dir/file (cons (file-name-directory file)
+ (file-name-nondirectory file)))
+ (comint-exec (get-buffer-create buf)
+ (if proc
+ (process-name proc)
+ "inferior-tcl")
+ tcl-application file tcl-command-switches)
+ (if and-go (switch-to-tcl t)))))))
+
+;; FIXME I imagine you can do this under Emacs 18. I just don't know
+;; how.
+(defun tcl-auto-fill-mode (&optional arg)
+ "Like `auto-fill-mode', but controls filling of Tcl comments."
+ (interactive "P")
+ (and (not tcl-using-emacs-19)
+ (error "You must use Emacs 19 to get this feature."))
+ ;; Following code taken from "auto-fill-mode" (simple.el).
+ (prog1
+ (setq auto-fill-function
+ (if (if (null arg)
+ (not auto-fill-function)
+ (> (prefix-numeric-value arg) 0))
+ 'tcl-do-auto-fill
+ nil))
+ (force-mode-line-update)))
+
+;; hilit19 support from "Chris Alfeld" <calfeld@math.utah.edu>
+(defun tcl-hilit ()
+ (hilit-set-mode-patterns
+ '(tcl-mode)
+ '(
+ ("\\(^ *\\|\; *\\)#.*$" nil comment)
+ ("[^\\]\\(\\$[A-Za-z0-9\\-\\_./\\(\\)]+\\)" 1 label)
+ ("[^_]\\<\\(append\\|array\\|auto_execok\\|auto_load\\|auto_mkindex\\|auto_reset\\|break\\|case\\|catch\\|cd\\|close\\|concat\\|continue\\|eof\\|error\\|eval\\|exec\\|exit\\|expr\\|file\\|flush\\|for\\|foreach\\|format\\|gets\\|glob\\|global\\|history\\|if\\|incr\\|info\\|join\\|lappend\\|lindex\\|linsert\\|list\\|llength\\|lrange\\|lreplace\\|lsearch\\|lsort\\|open\\|pid\\|proc\\|puts\\|pwd\\|read\\|regexp\\|regsub\\|rename\\|return\\|scan\\|seek\\|set\\|source\\|split\\|string\\|switch\\|tell\\|time\\|trace\\|unknown\\|unset\\|uplevel\\|upvar\\|while\\)\\>[^_]" 1 keyword) ; tcl keywords
+ ("[^_]\\<\\(after\\|bell\\|bind\\|bindtags\\|clipboard\\|destroy\\|fileevent\\|focus\\|grab\\|image\\|lower\\|option\\|pack\\|place\\|raise\\|scale\\|selection\\|send\\|subst\\|tk\\|tk_popup\\|tkwait\\|update\\|winfo\\|wm\\)\\>[^_]" 1 define) ; tk keywords
+ ("[^_]\\<\\(button\\|canvas\\|checkbutton\\|entry\\|frame\\|label\\|listbox\\|menu\\|menubutton\\|message\\|radiobutton\\|scrollbar\\|text\\|toplevel\\)\\>[^_]" 1 decl) ; tk widgets
+ ("[^_]\\<\\(tix\\((ButtonBox\\|Baloon\\|Control\\|DirList\\|ExFileSelectBox\\|ExFileSelectDialog\\|FileEntry\\|HList\\|LabelEntry\\|LabelFrame\\|NoteBook\\|OptionMenu\\|PanedWindow\\|PopupMenu\\|ScrolledHList\\|ScrolledText\\|ScrolledWindow\\|Select\\|StdButtonBox\\)\\)\\>[^_]" 1 defun) ; tix widgets
+ ("[{}\\\"\\(\\)]" nil include) ; misc punctuation
+ )))
+
+(defun tcl-electric-hash (&optional count)
+ "Insert a `#' and quote if it does not start a real comment.
+Prefix arg is number of `#'s to insert.
+See variable `tcl-electric-hash-style' for description of quoting
+styles."
+ (interactive "p")
+ (or count (setq count 1))
+ (if (> count 0)
+ (let ((type
+ (if (eq tcl-electric-hash-style 'smart)
+ (if (> count 3) ; FIXME what is "smart"?
+ 'quote
+ 'backslash)
+ tcl-electric-hash-style))
+ comment)
+ (if type
+ (progn
+ (save-excursion
+ (insert "#")
+ (setq comment (tcl-in-comment)))
+ (delete-char 1)
+ (and tcl-explain-indentation (message "comment: %s" comment))
+ (cond
+ ((eq type 'quote)
+ (if (not comment)
+ (insert "\"")))
+ ((eq type 'backslash)
+ ;; The following will set count to 0, so the
+ ;; insert-char can still be run.
+ (if (not comment)
+ (while (> count 0)
+ (insert "\\#")
+ (setq count (1- count)))))
+ (t nil))))
+ (insert-char ?# count))))
+
+(defun tcl-hashify-buffer ()
+ "Quote all `#'s in current buffer that aren't Tcl comments."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (if (and tcl-pps-has-arg-6 tcl-use-hairy-comment-detector)
+ (let (state
+ result)
+ (while (< (point) (point-max))
+ (setq result (tcl-hairy-scan-for-comment state (point-max) t))
+ (if (car result)
+ (beginning-of-line 2)
+ (backward-char)
+ (if (eq ?# (following-char))
+ (insert "\\"))
+ (forward-char))
+ (setq state (cdr result))))
+ (while (and (< (point) (point-max))
+ (search-forward "#" nil 'move))
+ (if (tcl-real-comment-p)
+ (beginning-of-line 2)
+ ;; There's really no good way for the simple converter to
+ ;; work. So we just quote # if it isn't already quoted.
+ ;; Bogus, but it works.
+ (backward-char)
+ (if (not (eq ?\\ (preceding-char)))
+ (insert "\\"))
+ (forward-char))))))
+
+(defun tcl-indent-for-comment ()
+ "Indent this line's comment to comment column, or insert an empty comment.
+Is smart about syntax of Tcl comments.
+Parts of this were taken from indent-for-comment (simple.el)."
+ (interactive "*")
+ (end-of-line)
+ (or (tcl-in-comment)
+ (progn
+ ;; Not in a comment, so we have to insert one. Create an
+ ;; empty comment (since there isn't one on this line). If
+ ;; line is not blank, make sure we insert a ";" first.
+ (skip-chars-backward " \t")
+ (let ((eolpoint (point)))
+ (beginning-of-line)
+ (if (/= (point) eolpoint)
+ (progn
+ (goto-char eolpoint)
+ (insert
+ (if (tcl-real-command-p) "" ";")
+ "# ")
+ (backward-char))))))
+ ;; Point is just after the "#" starting a comment. Move it as
+ ;; appropriate.
+ (let* ((indent (if comment-indent-hook
+ (funcall comment-indent-hook)
+ (funcall comment-indent-function)))
+ (begpos (progn
+ (backward-char)
+ (point))))
+ (if (/= begpos indent)
+ (progn
+ (skip-chars-backward " \t" (save-excursion
+ (beginning-of-line)
+ (point)))
+ (delete-region (point) begpos)
+ (indent-to indent)))
+ (looking-at comment-start-skip) ; Always true.
+ (goto-char (match-end 0))
+ ;; I don't like the effect of the next two.
+ ;;(skip-chars-backward " \t" (match-beginning 0))
+ ;;(skip-chars-backward "^ \t" (match-beginning 0))
+ ))
+
+;; The following was inspired by the Tcl editing mode written by
+;; Gregor Schmid <schmid@fb3-s7.math.TU-Berlin.DE>. His version also
+;; attempts to snarf the command line options from the command line,
+;; but I didn't think that would really be that helpful (doesn't seem
+;; like it owould be right enough. His version also looks for the
+;; "#!/bin/csh ... exec" hack, but that seemed even less useful.
+;; FIXME should make sure that the application mentioned actually
+;; exists.
+(defun tcl-guess-application ()
+ "Attempt to guess Tcl application by looking at first line.
+The first line is assumed to look like \"#!.../program ...\"."
+ (save-excursion
+ (goto-char (point-min))
+ (if (looking-at "#![^ \t]*/\\([^ \t\n/]+\\)\\([ \t]\\|$\\)")
+ (progn
+ (make-local-variable 'tcl-application)
+ (setq tcl-application (buffer-substring (match-beginning 1)
+ (match-end 1)))))))
+
+;; This only exists to put on the menubar. I couldn't figure out any
+;; other way to do it. FIXME should take "number of #-marks"
+;; argument.
+(defun tcl-uncomment-region (beg end)
+ "Uncomment region."
+ (interactive "r")
+ (comment-region beg end -1))
+
+
+
+;;
+;; XEmacs menu support.
+;; Taken from schmid@fb3-s7.math.TU-Berlin.DE (Gregor Schmid),
+;; who wrote a different Tcl mode.
+;; We also have support for menus in FSF. We do this by
+;; loading the XEmacs menu emulation code.
+;;
+
+(defun tcl-popup-menu (e)
+ (interactive "@e")
+ (and tcl-using-emacs-19
+ (not tcl-using-xemacs-19)
+ (if tcl-using-emacs-19-23
+ (require 'lmenu)
+ ;; CAVEATS:
+ ;; * lmenu.el provides 'menubar, which is bogus.
+ ;; * lmenu.el causes menubars to be turned on everywhere.
+ ;; Doubly bogus!
+ ;; Both of these problems are fixed in Emacs 19.23. People
+ ;; using an Emacs before that just suffer.
+ (require 'menubar "lmenu"))) ;; This is annoying
+ ;; IMHO popup-menu should be autoloaded in FSF Emacs. Oh well.
+ (popup-menu tcl-xemacs-menu))
+
+
+
+;;
+;; Quoting and unquoting functions.
+;;
+
+;; This quoting is sufficient to protect eg a filename from any sort
+;; of expansion or splitting. Tcl quoting sure sucks.
+(defun tcl-quote (string)
+ "Quote STRING according to Tcl rules."
+ (mapconcat (function (lambda (char)
+ (if (memq char '(?[ ?] ?{ ?} ?\\ ?\" ?$ ? ?\;))
+ (concat "\\" (char-to-string char))
+ (char-to-string char))))
+ string ""))
+
+
+
+;;
+;; Bug reporting.
+;;
+
+(and (fboundp 'eval-when-compile)
+ (eval-when-compile
+ (require 'reporter)))
+
+(defun tcl-submit-bug-report ()
+ "Submit via mail a bug report on Tcl mode."
+ (interactive)
+ (require 'reporter)
+ (and
+ (y-or-n-p "Do you really want to submit a bug report on Tcl mode? ")
+ (reporter-submit-bug-report
+ tcl-maintainer
+ (concat "Tcl mode " tcl-version)
+ '(tcl-indent-level
+ tcl-continued-indent-level
+ tcl-auto-newline
+ tcl-tab-always-indent
+ tcl-use-hairy-comment-detector
+ tcl-electric-hash-style
+ tcl-help-directory-list
+ tcl-use-smart-word-finder
+ tcl-application
+ tcl-command-switches
+ tcl-prompt-regexp
+ inferior-tcl-source-command
+ tcl-using-emacs-19
+ tcl-using-emacs-19-23
+ tcl-using-xemacs-19
+ tcl-proc-list
+ tcl-proc-regexp
+ tcl-typeword-list
+ tcl-keyword-list
+ tcl-font-lock-keywords
+ tcl-pps-has-arg-6))))
+
+
+
+(provide 'tcl)
+
+;;; tcl.el ends here
diff --git a/dejagnu/testglue.c b/dejagnu/testglue.c
new file mode 100644
index 00000000000..3d2b272976e
--- /dev/null
+++ b/dejagnu/testglue.c
@@ -0,0 +1,147 @@
+#include <stdio.h>
+#include <string.h>
+#ifndef NO_UNISTD_H
+#include <sys/unistd.h>
+#endif
+
+/* A simple glue file for embedded targets so we can get the real exit
+ status from the program. This assumes we're using GNU ld and can use
+ the -wrap option, and that write(1, ...) does something useful. */
+
+/* There is a bunch of weird cruft with #ifdef UNDERSCORES. This is needed
+ because currently GNU ld doesn't deal well with a.out targets and
+ the -wrap option. When GNU ld is fixed, this should definitely be
+ removed. Note that we actually wrap __exit, not _exit on a target
+ that has UNDERSCORES defined. */
+
+#ifdef WRAP_M68K_AOUT
+#define REAL_EXIT(code) asm ( "trap %0" : : "i" (0) );
+#define REAL_ABORT() REAL_EXIT(6)
+#define ORIG_EXIT _exit
+#define ORIG_ABORT abort
+#else
+#ifdef UNDERSCORES
+#define REAL_EXIT _real___exit
+#define REAL_MAIN _real__main
+#define REAL_ABORT _real__abort
+#define ORIG_EXIT _wrap___exit
+#define ORIG_ABORT _wrap__abort
+#define ORIG_MAIN _wrap__main
+#else
+#define REAL_EXIT __real_exit
+#define REAL_MAIN __real_main
+#define REAL_ABORT __real_abort
+#define ORIG_EXIT __wrap_exit
+#define ORIG_ABORT __wrap_abort
+#define ORIG_MAIN __wrap_main
+#endif
+#endif
+
+#ifdef REAL_MAIN
+extern void REAL_EXIT ();
+extern void REAL_ABORT ();
+extern int REAL_MAIN (int argc, char **argv, char **envp);
+#endif
+
+int ___constval = 1;
+
+#ifdef VXWORKS
+static void __runexit();
+#endif
+
+static char *
+write_int(val, ptr)
+ int val;
+ char *ptr;
+{
+ char c;
+ if (val<0) {
+ *(ptr++) = '-';
+ val = -val;
+ }
+ if (val>9) {
+ ptr = write_int (val/10, ptr);
+ }
+ c = (val%10)+'0';
+ *(ptr++) = c;
+ return ptr;
+}
+
+void
+ORIG_EXIT (code)
+ int code;
+{
+ char buf[30];
+ char *ptr;
+
+#ifdef VXWORKS
+ __runexit ();
+#endif
+ strcpy (buf, "\n*** EXIT code ");
+ ptr = write_int (code, buf + strlen(buf));
+ *(ptr++) = '\n';
+ write (1, buf, ptr-buf);
+ REAL_EXIT (code);
+ while (___constval);
+}
+
+void
+ORIG_ABORT ()
+{
+ write (1, "\n*** EXIT code 4242\n", 20);
+ REAL_ABORT ();
+ while (___constval);
+ abort ();
+}
+
+#ifdef REAL_MAIN
+int
+ORIG_MAIN (argc, argv, envp)
+ int argc;
+ char **argv;
+ char **envp;
+{
+#ifdef WRAP_FILE_ARGS
+ extern int __argc;
+ extern char *__args[];
+
+ exit (REAL_MAIN (__argc,__args,envp));
+#else
+ exit (REAL_MAIN (argc, argv, envp));
+#endif
+ while (___constval);
+}
+#endif
+
+#ifdef VXWORKS
+void
+_exit (status)
+ int status;
+{
+ REAL_EXIT (status);
+}
+
+typedef (*PFV)(void);
+
+static PFV __list[32];
+static int __listcnt = 0;
+static int __running = 0;
+
+int
+atexit (PFV func)
+{
+ __list[__listcnt++] = func;
+}
+
+static void
+__runexit ()
+{
+ int i;
+ if (__running++)
+ return;
+
+ for (i = 0; i < __listcnt; i++)
+ __list[i]();
+ __running = 0;
+}
+#endif
diff --git a/dejagnu/testsuite/Makefile.am b/dejagnu/testsuite/Makefile.am
new file mode 100644
index 00000000000..88dab63fee7
--- /dev/null
+++ b/dejagnu/testsuite/Makefile.am
@@ -0,0 +1,5 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus dejagnu
+
+DEJATOOL = runtest
diff --git a/dejagnu/testsuite/Makefile.in b/dejagnu/testsuite/Makefile.in
new file mode 100644
index 00000000000..544f45f5a55
--- /dev/null
+++ b/dejagnu/testsuite/Makefile.in
@@ -0,0 +1,207 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 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.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+BOARDS = @BOARDS@
+CC = @CC@
+CONFIG = @CONFIG@
+EXEEXT = @EXEEXT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+AUTOMAKE_OPTIONS = cygnus dejagnu
+
+DEJATOOL = runtest
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_CLEAN_FILES =
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+EXPECT = `if test -f $(top_builddir)/../expect/expect; then echo $(top_builddir)/../expect/expect; else echo expect; fi`
+RUNTEST = `if test -f $(top_srcdir)/../dejagnu/runtest; then echo $(top_srcdir)/../dejagnu/runtest; else echo runtest; fi`
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus testsuite/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = testsuite
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+RUNTESTFLAGS =
+
+RUNTESTDEFAULTFLAGS = --tool $(DEJATOOL) --srcdir $$srcdir
+
+check-DEJAGNU: site.exp
+ srcdir=`cd $(srcdir) && pwd`; export srcdir; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+site.exp: Makefile
+ @echo 'Making a new site.exp file...'
+ @test ! -f site.bak || rm -f site.bak
+ @echo '## these variables are automatically generated by make ##' > $@-t
+ @echo '# Do not edit here. If you wish to override these values' >> $@-t
+ @echo '# edit the last section' >> $@-t
+ @echo 'set tool $(DEJATOOL)' >> $@-t
+ @echo 'set srcdir $(srcdir)' >> $@-t
+ @echo 'set objdir' `pwd` >> $@-t
+ @echo '## All variables above are generated by configure. Do Not Edit ##' >> $@-t
+ @test ! -f site.exp || sed '1,/^## All variables above are.*##/ d' site.exp >> $@-t
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv $@-t site.exp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am:
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-info-am:
+install-info: install-info-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir check-DEJAGNU info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-info-am install-info \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# 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/dejagnu/testsuite/config/default.exp b/dejagnu/testsuite/config/default.exp
new file mode 100644
index 00000000000..0d427d0fcae
--- /dev/null
+++ b/dejagnu/testsuite/config/default.exp
@@ -0,0 +1,79 @@
+# Copyright (C) 1988, 90-93, 1995, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+global RUNTEST
+if ![info exists RUNTEST] then {
+ set RUNTEST [transform runtest]
+}
+
+if ![info exists EXPECT] {
+ set EXPECT [findfile $base_dir/../../expect/expect "$base_dir/../../expect/expect" expect]
+ verbose "EXPECT defaulting to $EXPECT" 2
+}
+
+global RUNTESTFLAGS
+if ![info exists RUNTESTFLAGS] then {
+ set RUNTESTFLAGS "-v -v -a"
+}
+
+#
+# runtest_version -- extract and print the version number
+#
+proc runtest_version { } {
+ global RUNTEST
+
+ catch {exec $RUNTEST -V} tmp
+ if [info exists tmp] then {
+ clone_output "$tmp\n"
+ }
+}
+
+#
+# runtest_load -- loads the program. For runtest, this is just a stub
+#
+proc runtest_load { arg } {
+}
+
+#
+# runtest_exit -- exit the test driver for expect
+#
+proc runtest_exit { } {
+ close
+}
+
+#
+# runtest_start -- start everything
+#
+proc runtest_start { } {
+ global verbose
+ global spawn_id
+ global subdir
+ global srcdir
+ global objdir
+ global RUNTEST
+ global RUNTESTFLAGS
+
+ if {[which $RUNTEST] != 0} then {
+ perror "Can't find $RUNTEST"
+ }
+
+# return [open [concat "$RUNTEST $RUNTESTFLAGS"] r]
+}
diff --git a/dejagnu/testsuite/lib/libsup.exp b/dejagnu/testsuite/lib/libsup.exp
new file mode 100644
index 00000000000..eecf5f7f61f
--- /dev/null
+++ b/dejagnu/testsuite/lib/libsup.exp
@@ -0,0 +1,220 @@
+# Copyright (C) 92, 93, 94, 95, 1996 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+#
+# Setup an environment so we can execute library procs without DejaGnu
+#
+
+#
+# Create a default environment and start expect.
+#
+proc make_defaults_file { defs } {
+ global srcdir
+ global objdir
+ global subdir
+ global build_triplet
+ global host_triplet
+ global target_triplet
+ global target_os
+ global target_cpu
+
+ # We need to setup default values and a few default procs so we
+ # can execute library code without DejaGnu
+ set fd [open $defs w]
+ puts ${fd} "set tool foobar"
+ puts ${fd} "set srcdir ${srcdir}"
+ puts ${fd} "set objdir ${objdir}"
+ puts ${fd} "set subdir ${subdir}"
+ puts ${fd} "set build_triplet ${build_triplet}"
+ puts ${fd} "set host_triplet ${host_triplet}"
+ puts ${fd} "set target_triplet ${target_triplet}"
+ puts ${fd} "set target_os ${target_os}"
+ puts ${fd} "set target_cpu ${target_cpu}"
+ puts ${fd} "set tool foobar"
+ puts ${fd} "set testcnt 0"
+ puts ${fd} "set warncnt 0"
+ puts ${fd} "set errcnt 0"
+ puts ${fd} "set passcnt 0"
+ puts ${fd} "set xpasscnt 0"
+ puts ${fd} "set failcnt 0"
+ puts ${fd} "set xfailcnt 0"
+ puts ${fd} "set prms_id 0"
+ puts ${fd} "set bug_id 0"
+ puts ${fd} "set exit_status 0"
+ puts ${fd} "set untestedcnt 0"
+ puts ${fd} "set unresolvedcnt 0"
+ puts ${fd} "set unsupportedcnt 0"
+ puts ${fd} "set xfail_flag 0"
+ puts ${fd} "set xfail_prms 0"
+ puts ${fd} "set mail_logs 0"
+ puts ${fd} "set multipass_name 0"
+ catch "close $fd"
+}
+
+proc start_expect { } {
+ global spawn_id
+ global base_dir
+
+ # We need to setup default values and a few default procs so we
+ # can execute library code without DejaGnu
+ set defaults_file setval.tmp
+ make_defaults_file $defaults_file
+ set fd [open ${defaults_file} w]
+
+ # look for expect
+ if ![info exists EXPECT] {
+ set EXPECT [findfile $base_dir/../../expect/expect "$base_dir/../../expect/expect" expect]
+ verbose "EXPECT defaulting to $EXPECT" 2
+ }
+
+# catch close
+# catch wait
+
+ # Start expect runing
+ spawn "$EXPECT"
+ expect {
+ -re "expect.*> " {
+ verbose "Started the child expect shell" 2
+ }
+ timeout {
+ perror "Timed out starting the child expect shell."
+ return -1
+ }
+ }
+
+ # Load the defaults file
+ exp_send "source ${defaults_file}\n"
+ expect {
+ "expect*> " {
+ verbose "Loaded testing defaults file." 2
+ return 1
+ }
+ timeout {
+ perror "Couldn't load the testing defaults file."
+ return -1
+ }
+ }
+}
+
+#
+# Stop the runing expect process
+#
+proc stop_expect { } {
+ global spawn_id
+
+ # make expect exit
+ exp_send "exit\n"
+ catch "close -i $spawn_id"
+ catch "wait -i $spawn_id"
+}
+
+#
+# Load the library to test
+#
+proc load_test_lib { lib } {
+ global spawn_id
+ exp_send "source ${lib}\n"
+ expect {
+ "expect*> " {
+ verbose "Testing ${lib}" 2
+ }
+ timeout {
+ perror "Couldn't load the libraries to test"
+ return -1
+ }
+ }
+}
+
+#
+# test a library proc that emits patterns
+#
+proc exp_test { cmd pattern msg } {
+ global spawn_id
+
+ exp_send "puts ACK ; $cmd ; puts NAK\r\n"
+ expect {
+ "puts ACK*puts NAK" {
+ verbose "Got command echo" 3
+ }
+ timeout {
+ warning "Never got command echo"
+ }
+ }
+
+ expect {
+ "ACK" {
+ exp_continue
+ }
+ -re "\r\n1\r\n" {
+ warning "$msg, 1 was returned"
+ exp_continue
+ }
+ -re "\r\n0\r\n" {
+ warning "$msg, 0 was returned"
+ exp_continue
+ }
+ "$pattern" {
+ pass "$msg"
+ }
+ timeout {
+ fail "$msg"
+ }
+ }
+}
+
+# test a config proc that only returns a code
+# ex... config_test "isbuild $build_triplet" "pass" "fail" "isbuild, native"
+# args are: command, true condition, false condition, message to print
+proc config_test { cmd true false msg } {
+ global spawn_id
+
+ set timeout 20
+ exp_send "puts ACK ; puts \[$cmd\] ; puts NAK\r\n"
+ expect {
+ "puts ACK*$cmd*puts NAK" {
+ verbose "Got command echo" 3
+ }
+ timeout {
+ warning "Never got command echo"
+ }
+ }
+
+ expect {
+ -re "Checking pattern*with*\[\r\n\]" {
+ exp_continue
+ }
+ -re "\r\n1\r\n" {
+ $true "$msg"
+ }
+ -re "\r\n0\r\n" {
+ $false "$msg"
+ }
+ timeout {
+ perror "$msg (timed out)"
+ }
+ }
+}
+
+
+
+
+
+
diff --git a/dejagnu/testsuite/runtest.all/clone_output.test b/dejagnu/testsuite/runtest.all/clone_output.test
new file mode 100644
index 00000000000..e1d1cd2bb06
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/clone_output.test
@@ -0,0 +1,68 @@
+# test clone_output
+
+set srcdir [lindex $argv 0]
+set subdir [lindex $argv 1]
+set objdir [lindex $argv 2]
+
+if [ file exists $objdir/setval.tmp ] {
+ source $objdir/setval.tmp
+} else {
+ puts "ERROR: $objdir/setval.tmp doesn't exist"
+}
+if [ file exists $srcdir/$subdir/default_procs.tcl ] {
+ source "$srcdir/$subdir/default_procs.tcl"
+} else {
+ puts "ERROR: $srcdir/$subdir/default_procs.tcl doesn't exist"
+}
+if [ file exists $srcdir/../lib/framework.exp] {
+ source $srcdir/../lib/framework.exp
+} else {
+ puts "ERROR: $srcdir/../lib/framework.exp doesn't exist"
+}
+
+set all_flag 0
+global all_flag
+set errno ""
+
+# stuff that shouldn't print anything without all_flag set
+set all_flag 0
+set tests {
+ { "lib_pat_test" "clone_output" "PASS: Foo" "" "clone_output(pass) without all_flag set" }
+ { "lib_pat_test" "clone_output" "UNRESOLVED: Foo" "" "clone_output(unresolved) without all_flag set" }
+ { "lib_pat_test" "clone_output" "UNSUPPORTED: Foo" "" "clone_output(unsupported) without all_flag set" }
+ { "lib_pat_test" "clone_output" "UNTESTED: Foo" "" "clone_output(untested) without all_flag set" }
+ { "lib_pat_test" "clone_output" "ERROR: Bar" "ERROR: Bar" "clone_output(error) without all_flag set" }
+ { "lib_pat_test" "clone_output" "WARNING: Bar" "WARNING: Bar" "clone_output(warning) without all_flag set" }
+ { "lib_pat_test" "clone_output" "NOTE: Bar" "NOTE: Bar" "clone_output(note) without all_flag set" }
+}
+
+run_tests $tests
+
+# tests for all_flag set to 1
+set all_flag 1
+set tests {
+ { "lib_pat_test" "clone_output" "PASS: Foo" "PASS: Foo" "clone_output(pass) with all_flag set" }
+ { "lib_pat_test" "clone_output" "XFAIL: Foo" "XFAIL: Foo" "clone_output(xfail) with all_flag set" }
+ { "lib_pat_test" "clone_output" "UNRESOLVED: Foo" "UNRESOLVED: Foo" "clone_output(unresolved) with all_flag set" }
+ { "lib_pat_test" "clone_output" "UNSUPPORTED: Foo" "UNSUPPORTED: Foo" "clone_output(unsupported) with all_flag set" }
+ { "lib_pat_test" "clone_output" "UNTESTED: Foo" "UNTESTED: Foo" "clone_output(untested) with all_flag set" }
+ { "lib_pat_test" "clone_output" "ERROR: Foo" "ERROR: Foo" "clone_output(error) with all_flag set" }
+ { "lib_pat_test" "clone_output" "WARNING: Foo" "WARNING: Foo" "clone_output(warning) with all_flag set" }
+ { "lib_pat_test" "clone_output" "NOTE: Foo" "NOTE: Foo" "clone_output(note) with all_flag set" }
+}
+
+run_tests $tests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dejagnu/testsuite/runtest.all/config.test b/dejagnu/testsuite/runtest.all/config.test
new file mode 100644
index 00000000000..a85095d7767
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/config.test
@@ -0,0 +1,138 @@
+# test clone_output
+
+set srcdir [lindex $argv 0]
+set subdir [lindex $argv 1]
+set objdir [lindex $argv 2]
+
+if [ file exists $objdir/setval.tmp ] {
+ source $objdir/setval.tmp
+} else {
+ puts "ERROR: $objdir/setval.tmp doesn't exist"
+}
+if [ file exists $srcdir/$subdir/default_procs.tcl ] {
+ source "$srcdir/$subdir/default_procs.tcl"
+} else {
+ puts "ERROR: $srcdir/$subdir/default_procs.tcl doesn't exist"
+}
+if [ file exists $srcdir/../lib/framework.exp] {
+ source $srcdir/../lib/framework.exp
+} else {
+ puts "ERROR: $srcdir/../lib/framework.exp doesn't exist"
+}
+
+set all_flag 1
+
+set host_triplet i586-unknown-linux
+set target_triplet i586-unknown-linux
+set target_cpu i586
+set target_os linux
+set build_triplet i586-unknown-linux
+
+# FIXME: should use run_tests here, but due to Tcl's weird scoping rules, I get
+# problems.
+
+#
+# Tests for a native configuration
+#
+if [isbuild $build_triplet] {
+ puts "PASSED: isbuild, native"
+} else {
+ puts "FAILED: isbuild, native"
+}
+
+if [isbuild $target_cpu-*-$target_os ] {
+ puts "PASSED: isbuild, native regexp"
+} else {
+ puts "FAILED: isbuild, native regexp"
+}
+
+if [isbuild hppa-ibm-macos ] {
+ puts "FAILED: isbuild, native bogus config string"
+} else {
+ puts "PASSED: isbuild, native bogus config string"
+}
+
+# ishost tests
+if [ishost $host_triplet] {
+ puts "PASSED: ishost, native"
+} else {
+ puts "FAILED: ishost, native"
+}
+
+if [ishost $target_cpu-*-$target_os] {
+ puts "PASSED: ishost, native regexp"
+} else {
+ puts "FAILED: ishost, native regexp"
+}
+
+if [ishost hppa-ibm-macos] {
+ puts "FAILED: ishost, native bogus config string"
+} else {
+ puts "PASSED: ishost, native bogus config string"
+}
+
+# istarget tests
+if [istarget $target_triplet] {
+ puts "PASSED: istarget, native"
+} else {
+ puts "FAILED: istarget, native"
+}
+
+if [istarget $target_cpu-*-$target_os] {
+ puts "PASSED: istarget, native regexp"
+} else {
+ puts "FAILED: istarget, native regexp"
+}
+
+if [istarget hppa-ibm-macos] {
+ puts "FAILED: istarget, native bogus config string"
+} else {
+ puts "PASSED: istarget, native bogus config string"
+}
+
+# native tests
+if [isnative] {
+ puts "PASSED: isnative, native"
+} else {
+ puts "FAILED: isnative, native"
+}
+
+if [is3way] {
+ puts "FAILED: is3way, native"
+} else {
+ puts "PASSED: is3way, native"
+}
+
+#
+# Tests for a normal cross configuration
+#
+set target_triplet m68k-unknown-elf
+if [isnative] {
+ puts "FAILED: isnative, cross"
+} else {
+ puts "PASSED: isnative, cross"
+}
+
+if [is3way] {
+ puts "FAILED: is3way, cross"
+} else {
+ puts "PASSED: is3way, cross"
+}
+
+#
+# Tests for a canadian cross configuration
+#
+set host_triplet i386-unknown-winnt
+if [isnative] {
+ puts "FAILED: isnative, canadian cross"
+} else {
+ puts "PASSED: isnative, canadian cross"
+}
+
+if [is3way] {
+ puts "PASSED: is3way, canadian cross"
+} else {
+ puts "FAILED: is3way, canadian cross"
+}
+
+
diff --git a/dejagnu/testsuite/runtest.all/default_procs.tcl b/dejagnu/testsuite/runtest.all/default_procs.tcl
new file mode 100644
index 00000000000..a0e6f88fa48
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/default_procs.tcl
@@ -0,0 +1,94 @@
+set sum_file [open .tmp w]
+set reboot 0
+set errno ""
+
+# this tests a proc for a returned pattern
+proc lib_pat_test { cmd arg pattern } {
+ catch "$cmd \"$arg\"" result
+ puts "CMD(lib_pat_test) was: $cmd \"$arg\""
+ puts "RESULT(lib_pat_test) was: \"${result}\" for pattern \"$pattern\"."
+ if [ regexp -- "with too many" $result ] {
+ return -1
+ }
+ if [ string match "$pattern" $result ] {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+# this tests a proc for a returned value
+proc lib_ret_test { cmd arg val } {
+ catch "$cmd \"$arg\"" result
+# catch "set result [$cmd $arg]" output
+# set result "$cmd [eval $arg]
+ puts "CMD(lib_ret_test) was: $cmd $arg"
+ puts "RESULT(lib_ret_test) was: $result"
+# puts "OUTPUT(lib_ret_test) was: $output"
+
+ if { $result == $val } {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+#
+# This runs a standard test for a proc. The list is set up as:
+# |test proc|proc being tested|args|pattern|message|
+# test proc is something like lib_pat_test or lib_ret_test.
+#
+proc run_tests { tests } {
+ foreach i "$tests" {
+ set result [ [lindex $i 0] "[lindex $i 1]" "[lindex $i 2]" "[lindex $i 3]" ]
+ switch -- $result {
+ "-1" {
+ puts "ERRORED: [lindex $i 4]"
+ }
+ "1" {
+ puts "PASSED: [lindex $i 4]"
+ }
+ "0" {
+ puts "FAILED: [lindex $i 4]"
+ }
+ default {
+ puts "BAD VALUE: [lindex $i 4]"
+ }
+ }
+ }
+}
+
+proc send_log { msg } {
+ # this is just a stub for testing
+}
+
+proc pass { msg } {
+ puts "PASSED: $msg"
+}
+
+proc fail { msg } {
+ puts "FAILED: $msg"
+}
+
+proc perror { msg } {
+ global errno
+ puts "ERRORED: $msg"
+ set errno "$msg"
+}
+
+proc warning { msg } {
+ global errno
+ puts "WARNED: $msg"
+ set errno "$msg"
+}
+
+proc untested { msg } {
+ puts "NOTTESTED: $msg"
+}
+
+proc unsupported { msg } {
+ puts "NOTSUPPORTED: $msg"
+}
+proc verbose { args } {
+ puts "[lindex $args 0]"
+}
diff --git a/dejagnu/testsuite/runtest.all/libs.exp b/dejagnu/testsuite/runtest.all/libs.exp
new file mode 100644
index 00000000000..eb5e1af4fae
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/libs.exp
@@ -0,0 +1,92 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+load_lib libsup.exp
+
+proc process_test { test } {
+ global srcdir
+ global subdir
+ global objdir
+ global EXPECT
+
+ verbose "Executing test case $test"
+ set text "\[- A-Za-z0-9\,\.\;\"\_\:\'\`\(\)\!\#\=\+\?\&\*]*"
+
+ set timeout 150
+
+ if [file exists $test] {
+ verbose "Processing test $test" 2
+ spawn -open [open "|$EXPECT $test $srcdir $subdir [pwd]" r]
+ expect {
+ "No such file or directory" {
+ perror "$test wouldn't run" 0
+ }
+ -re "\[\r\n\]*NOTSUPPORTED: $text\[\r\n\]*" {
+ unsupported "[lrange $expect_out(0,string) 1 end]"
+ exp_continue
+ }
+ -re "\[\r\n\]*NOTTESTED: $text\[\r\n\]*" {
+ untested "[lrange $expect_out(0,string) 1 end]"
+ exp_continue
+ }
+ -re "\[\r\n\]*PASSED: $text\[\r\n\]*" {
+ pass "[lrange $expect_out(0,string) 1 end]"
+ exp_continue
+ }
+ -re "\[\r\n\]*FAILED: $text\[\r\n\]*" {
+ fail "[lrange $expect_out(0,string) 1 end]"
+ exp_continue
+ }
+ -re "\[\r\n\]*WARNED: $text\[\r\n\]*" {
+ verbose "$expect_out(0,string)" 2
+ exp_continue
+ }
+ -re "\[\r\n\]*ERRORED: $text\[\r\n\]*" {
+ verbose "$expect_out(0,string)" 2
+ exp_continue
+ }
+ timeout {
+ perror "$test timed out" 0
+ exp_continue
+ }
+ eof {
+ verbose "All Done" 3
+ }
+ }
+ } else {
+ perror "$test doesn't exist" 0
+ }
+}
+
+if ![info exists EXPECT] {
+ set EXPECT [findfile $base_dir/../../expect/expect "$base_dir/../../expect/expect" expect]
+ verbose "EXPECT defaulting to $EXPECT" 2
+}
+
+make_defaults_file [pwd]/setval.tmp
+
+foreach i [glob $srcdir/$subdir/*.test] {
+ process_test $i
+}
+
+
+
+
+
+
diff --git a/dejagnu/testsuite/runtest.all/options.exp b/dejagnu/testsuite/runtest.all/options.exp
new file mode 100644
index 00000000000..0c396ced64b
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/options.exp
@@ -0,0 +1,93 @@
+# Copyright (C) 1988, 90-92, 1994, 1995, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+load_lib util-defs.exp
+
+# move the site.exp file so we have no default to confuse us.
+#if [file exists $objdir/site.exp] {
+# catch "exec mv -f $objdir/site.exp $objdir/site.ignore"
+#}
+set fd [open site.exp w]
+puts ${fd} "set host_triplet $host_triplet"
+puts ${fd} "set srcdir $srcdir/.."
+puts ${fd} "set objdir $objdir/.."
+puts ${fd} "set tmpdir $objdir/../tmpdir"
+close $fd
+
+#
+# Set up the list.
+# 1st field is the command line option.
+# 2nd field is the pattern to match.
+# NOTE - No variable substitutions can be used.
+# 3rd field is an optional message to print with PASS/FAIL.
+#
+
+
+set tests {
+ { "" "WARNING: No tool specified" "No arguments" }
+ { "-v --tool xXx" "Found.*site\..*Loading.*utils\.exp" "Loading library files" }
+ { "-v --tool xXx" "Expect binary is.*Using.*main test driver" "Loading basic packages" }
+ { "--F --tool x" "Illegal Argument \"--F\"" "Bad argument" }
+ { "--tool x" "Couldn't find tool init file" "Bad tool name" }
+ { "--help" "USAGE:*" "Display help" }
+ { "-v -v -v" "Verbose level is 3" "Verbose set correctly" }
+ { "-V" "Expect version is.*Tcl version is.*Framework version is*" "--version" }
+ { "-v --target m68k-vxworks" "Target is m68k-vxworks" "--target option" }
+ { "-v --host sparc-sun-sunos4.1.9" "Native configuration is sparc-sun-sunos4.1.9" "--host option" }
+ { "-v -a" "Print all test output to screen" "--all option" }
+ { "-v --objdir xXx" "Using test binaries in xXx" "--objdir option" }
+ { "-v --tool xXx" "Testing xXx" "--tool option" }
+ { "-v --debug" "Expect Debugging is ON" "--debug option" }
+ { "-v --D0" "Tcl debugger is ON" "--D0 option" }
+}
+
+# Commented out for now--this is failing because of a TCL8 strace interaction.
+# { "-v --strace 1" "Source Trace level is now 1.* 1 if" "--strace option" }
+
+
+# Old tests not used anymore
+# { "-v --build sparc-sun-sunos4.1.9" "Native configuration is sparc-sun-sunos4.1.9" "--build option" }
+# { "-v --srcdir xXx" "Using test sources in xXx" "--srcdir option" }
+
+foreach i $tests {
+ if [util_test "$RUNTEST" "[lindex $i 0] -srcdir ${srcdir}/runtest.all" "" "[lindex $i 1]"] {
+ fail "[lindex $i 2]"
+ } else {
+ pass "[lindex $i 2]"
+ }
+}
+
+
+set fd [open site.exp w]
+puts ${fd} "set host_triplet $host_triplet"
+puts ${fd} "set tool runtest"
+puts ${fd} "set srcdir $srcdir"
+puts ${fd} "set objdir $objdir"
+puts ${fd} "set tmpdir $objdir/tmpdir"
+close $fd
+
+# clean up log files left by the child runtest
+if [file exists $objdir/x.sum] {
+ exec rm -f $objdir/x.*
+}
+if [file exists $objdir/xXx.sum] {
+ exec rm -f $objdir/xXx.*
+}
diff --git a/dejagnu/testsuite/runtest.all/remote.test b/dejagnu/testsuite/runtest.all/remote.test
new file mode 100644
index 00000000000..03f16fcf63d
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/remote.test
@@ -0,0 +1,217 @@
+set srcdir [lindex $argv 0]
+set subdir [lindex $argv 1]
+set objdir [lindex $argv 2]
+
+if [ file exists $objdir/setval.tmp ] {
+ source $objdir/setval.tmp
+} else {
+ puts "ERROR: $objdir/setval.tmp doesn't exist"
+}
+if [ file exists $srcdir/$subdir/default_procs.tcl ] {
+ source "$srcdir/$subdir/default_procs.tcl"
+} else {
+ puts "ERROR: $srcdir/$subdir/default_procs.tcl doesn't exist"
+}
+
+set file $srcdir/../lib/remote.exp
+if [ file exists $file] {
+ source $file
+} else {
+ puts "ERROR: $file doesn't exist"
+}
+
+global errno ""
+
+#
+# Create a false target config array
+#
+set target_info(idp,name) "idp"
+set target_info(idp,ldflags) "-Tidp.ld"
+set target_info(idp,config) m68k-unknown-aout
+set target_info(idp,cflags) ""
+set target_info(idp,connect) telnet
+set target_info(idp,target) "s12"
+set target_info(idp,serial) "tstty12"
+set target_info(idp,netport) "localhost:23"
+set target_info(idp,baud) "9600"
+# MVME target
+set target_info(mvme,name) "mvme"
+set target_info(mvme,ldflags) "-Tmvme.ld"
+set target_info(mvme,config) m68k-unknown-aout
+set target_info(mvme,cflags) ""
+set target_info(mvme,connect) telnet
+set target_info(mvme,target) "s12"
+set target_info(mvme,serial) "tstty8"
+set target_info(mvme,netport) "localhost:23"
+set target_info(mvme,baud) "9600"
+
+# Test remote open. We try not to use any of the support procs in
+# target.exp to for isolation testing. "target" is the name of the
+# default array setup by the procs in target.exp.
+
+set timeout 100
+set errno ""
+
+#
+# Force connection errors
+#
+
+# force an rlogin error
+if { [rlogin foobar.barfoo.com] < 0 } {
+ puts "PASSED: rlogin bogus host"
+} else {
+ puts "FAILED: rlogin bogus"
+}
+
+# force an rsh error
+if { [rsh foobar.barfoo.com] < 0 } {
+ puts "PASSED: rsh bogus host"
+} else {
+ puts "FAILED: rsh bogus"
+}
+
+# force a telnet error
+if { [telnet foobar.barfoo.com] < 0 } {
+ puts "PASSED: telnet bogus host"
+} else {
+ puts "FAILED: telnet bogus"
+}
+
+#
+# Connect to localhost
+#
+
+# localhost rlogin test
+if { [rlogin localhost] < 0 } {
+ if [string match "*unencrypted connection" $errno] {
+ NOTTESTED "rlogin localhost"
+ } else {
+ puts "FAILED: rlogin localhost"
+ }
+} else {
+ puts "PASSED: rlogin localhost"
+}
+catch "exp_send exit\n"
+catch "close -i $spawn_id"
+catch "wait -i $spawn_id"
+
+# localhost rsh test
+if { [rsh localhost] < 0 } {
+ if [string match "*kinit" $errno] {
+ puts "NOTTESTED: rsh localhost"
+ } else {
+ puts "FAILED: rsh localhost"
+ }
+} else {
+ puts "PASSED: rsh localhost"
+}
+catch "exp_send exit\n"
+catch "close -i $spawn_id"
+catch "wait -i $spawn_id"
+
+# localhost telnet test. In this case it will return
+# an error cause we get prompted for a password or login. For
+# now this is considered an error, as we usually only
+# telnet to a terminal server.
+if { [telnet localhost] < 0 } {
+ if [string match "*password." $errno] {
+ puts "NOTTESTED: telnet localhost"
+ } else {
+ puts "FAILED: telnet localhost"
+ }
+} else {
+ puts "PASSED: telnet localhost"
+}
+catch "exp_send exit\n"
+catch "close -i $spawn_id"
+catch "wait -i $spawn_id"
+
+#
+# Connect to the configured target
+#
+set target_info(target,netport) $target_info(idp,netport)
+set target_info(target,target) localhost
+set target_info(target,connect) rlogin
+if { [rlogin target] < 0 } {
+ if [ string match "*kinit" $errno] {
+ puts "NOTTESTED: rlogin target"
+ } else {
+ puts "FAILED: rlogin target"
+ }
+} else {
+ puts "PASSED: rlogin target"
+}
+catch "exp_send exit\n"
+catch "close -i $spawn_id"
+catch "wait -i $spawn_id"
+
+# test remote_open
+if { [rsh target] < 0 } {
+ if [ string match "*kinit" $errno] {
+ puts "NOTTESTED: rsh target"
+ } else {
+ puts "FAILED: rsh target"
+ }
+} else {
+ puts "PASSED: rsh target"
+}
+catch "exp_send exit\n"
+catch "close -i $spawn_id"
+catch "wait -i $spawn_id"
+
+# telnet to host
+# FIXME: This won't work till we figure out how to telnet and
+# not get a password prompt.
+
+#
+# Connect to the configured host
+#
+set target_info(host,connect) rlogin
+set target_info(host,netport) $target_info(idp,netport)
+set target_info(host,target) localhost
+
+# rlogin to host
+if { [rlogin host] < 0 } {
+ if [ string match "*kinit*" $errno] {
+ puts "NOTTESTED: rlogin host"
+ } else {
+ puts "FAILED: rlogin host"
+ }
+} else {
+ puts "PASSED: rlogin host"
+}
+catch "exp_send exit\n"
+catch "close -i $spawn_id"
+catch "wait -i $spawn_id"
+
+# rsh to host
+if { [rsh host] < 0 } {
+ if [ string match "*kinit*" $errno] {
+ puts "NOTTESTED: rsh host"
+ } else {
+ puts "FAILED: rsh host"
+ }
+} else {
+ puts "PASSED: rsh host"
+}
+catch "exp_send exit\n"
+catch "close -i $spawn_id"
+catch "wait -i $spawn_id"
+
+# telnet to host
+# FIXME: This won't work till we figure out how to telnet and
+# not get a password prompt.
+
+# tip port
+# remote_close args
+# rcp_download src dest
+# tip_download shell_id file
+# kermit args
+# download args
+
+
+
+
+
+
+
diff --git a/dejagnu/testsuite/runtest.all/stats-sub.exp b/dejagnu/testsuite/runtest.all/stats-sub.exp
new file mode 100644
index 00000000000..deb52f82e36
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/stats-sub.exp
@@ -0,0 +1,35 @@
+# Copyright (C) 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Subordinate to stats.exp.
+
+# If not called by stats.exp, quit now.
+if { ![info exists STATS_TEST] } {
+ return
+}
+
+switch $STATS_TEST {
+ pass { pass "pass test" }
+ fail { fail "fail test" }
+ xpass { xpass "xpass test" }
+ xfail { xfail "xfail test" }
+ untested { untested "untested test" }
+ unresolved { unresolved "unresolved test" }
+ unsupported { unsupported "unsupported test" }
+}
diff --git a/dejagnu/testsuite/runtest.all/stats.exp b/dejagnu/testsuite/runtest.all/stats.exp
new file mode 100644
index 00000000000..157cb273983
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/stats.exp
@@ -0,0 +1,53 @@
+# Copyright (C) 1995, 1996, 1997, 1999 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file tests pass/fail/etc.
+# The way we do this is to recursively invoke ourselves on a small testsuite
+# and analyze the results.
+
+load_lib util-defs.exp
+
+if ![info exists tmpdir] {
+ set tmpdir $objdir/tmpdir
+}
+
+if ![file isdirectory $tmpdir] {
+ catch "exec mkdir $tmpdir"
+}
+
+set tests {
+ { pass "expected passes\[ \t\]+1\n" }
+ { fail "unexpected failures\[ \t\]+1\n" }
+ { xpass "unexpected successes\[ \t\]+1\n" }
+ { xfail "expected failures\[ \t\]+1\n" }
+ { untested "untested testcases\[ \t\]+1\n" }
+ { unresolved "unresolved testcases\[ \t\]+1\n" }
+ { unsupported "unsupported tests\[ \t\]+1\n" }
+}
+
+foreach t $tests {
+ if [util_test "$RUNTEST" \
+ "--outdir $tmpdir STATS_TEST=[lindex $t 0] stats-sub.exp" \
+ "" \
+ [lindex $t 1]] {
+ fail [lindex $t 0]
+ } else {
+ pass [lindex $t 0]
+ }
+}
diff --git a/dejagnu/testsuite/runtest.all/target.test b/dejagnu/testsuite/runtest.all/target.test
new file mode 100644
index 00000000000..19aba4a768e
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/target.test
@@ -0,0 +1,247 @@
+set srcdir [lindex $argv 0]
+set subdir [lindex $argv 1]
+set objdir [lindex $argv 2]
+
+if [ file exists $objdir/setval.tmp ] {
+ source $objdir/setval.tmp
+} else {
+ puts "ERROR: $objdir/setval.tmp doesn't exist"
+}
+if [ file exists $srcdir/$subdir/default_procs.tcl ] {
+ source "$srcdir/$subdir/default_procs.tcl"
+} else {
+ puts "ERROR: $srcdir/$subdir/default_procs.tcl doesn't exist"
+}
+
+set file $srcdir/../lib/target.exp
+if [ file exists $file] {
+ source $file
+} else {
+ puts "ERROR: $file doesn't exist"
+}
+# we load framework so we can use stuff like is3way
+set file $srcdir/../lib/framework.exp
+if [ file exists $file] {
+ source $file
+} else {
+ puts "ERROR: $file doesn't exist"
+}
+# we load the remote stuff so we can test execute_anywhere
+set file $srcdir/../lib/remote.exp
+if [ file exists $file] {
+ source $file
+} else {
+ puts "ERROR: $file doesn't exist"
+}
+
+#
+# Create a false target config array
+#
+set target_info(idp,name) "idp"
+set target_info(idp,ldflags) "-Tidp.ld"
+set target_info(idp,config) m68k-unknown-aout
+set target_info(idp,cflags) ""
+set target_info(idp,connect) "telnet"
+set target_info(idp,target) "s12"
+set target_info(idp,serial) "tstty12"
+set target_info(idp,netport) "localhost:23"
+set target_info(idp,baud) "9600"
+# MVME target
+set target_info(mvme,name) "mvme"
+set target_info(mvme,ldflags) "-Tmvme.ld"
+set target_info(mvme,config) m68k-unknown-aout
+set target_info(mvme,cflags) ""
+set target_info(mvme,connect) "telnet"
+set target_info(mvme,target) "s12"
+set target_info(mvme,serial) "tstty8"
+set target_info(mvme,netport) "localhost:23"
+set target_info(mvme,baud) "9600"
+
+# Test remote open. We try not to use any of the support procs in
+# target.exp to for isolation testing. "target" is the name of the
+# default array setup by the procs in target.exp.
+
+set timeout 100
+
+# test list_target
+
+if { [list_targets] == "idp mvme" } {
+ puts "PASSED: list_targets"
+} else {
+ puts "FAILED: list_targets"
+}
+push_config target idp
+set matches 0
+if { $target_info(target,name) == "idp" } {
+ incr matches
+}
+if { $target_info(target,ldflags) == "-Tidp.ld" } {
+ incr matches
+}
+if { $target_info(target,config) == "m68k-unknown-aout" } {
+ incr matches
+}
+if { $target_info(target,cflags) == "" } {
+ incr matches
+}
+if { $target_info(target,connect) == "telnet" } {
+ incr matches
+}
+if { $target_info(target,target) == "s12" } {
+ incr matches
+}
+if { $target_info(target,serial) == "tstty12" } {
+ incr matches
+}
+if { $target_info(target,netport) == "localhost:23" } {
+ incr matches
+}
+if { $target_info(target,baud) == "9600" } {
+ incr matches
+}
+if { $matches == 9 } {
+ puts "PASSED: push_config target"
+} else {
+ puts "FAILED: push_config target"
+}
+
+# test pop_config target
+pop_config target
+set matches 0
+if { $target_info(target,name) == "" } {
+ incr matches
+}
+if { $target_info(target,ldflags) == "" } {
+ incr matches
+}
+if { $target_info(target,config) == "" } {
+ incr matches
+}
+if { $target_info(target,cflags) == "" } {
+ incr matches
+}
+if { $target_info(target,connect) == "" } {
+ incr matches
+}
+if { $target_info(target,target) == "" } {
+ incr matches
+}
+if { $target_info(target,serial) == "" } {
+ incr matches
+}
+if { $target_info(target,netport) == "" } {
+ incr matches
+}
+if { $target_info(target,baud) == "" } {
+ incr matches
+}
+if { $matches == 9 } {
+ puts "PASSED: pop_config target"
+} else {
+ puts "FAILED: pop_config target"
+}
+
+push_config host idp
+set matches 0
+if { $target_info(host,name) == "idp" } {
+ incr matches
+}
+if { $target_info(host,ldflags) == "-Tidp.ld" } {
+ incr matches
+}
+if { $target_info(host,config) == "m68k-unknown-aout" } {
+ incr matches
+}
+if { $target_info(host,cflags) == "" } {
+ incr matches
+}
+if { $target_info(host,connect) == "telnet" } {
+ incr matches
+}
+if { $target_info(host,target) == "s12" } {
+ incr matches
+}
+if { $target_info(host,serial) == "tstty12" } {
+ incr matches
+}
+if { $target_info(host,netport) == "localhost:23" } {
+ incr matches
+}
+if { $target_info(host,baud) == "9600" } {
+ incr matches
+}
+if { $matches == 9 } {
+ puts "PASSED: push_config target"
+} else {
+ puts "FAILED: push_config target"
+}
+
+# test pop_config host
+pop_config host
+set matches 0
+if { $target_info(host,name) == "" } {
+ incr matches
+}
+if { $target_info(host,ldflags) == "" } {
+ incr matches
+}
+if { $target_info(host,config) == "" } {
+ incr matches
+}
+if { $target_info(host,cflags) == "" } {
+ incr matches
+}
+if { $target_info(host,connect) == "" } {
+ incr matches
+}
+if { $target_info(host,target) == "" } {
+ incr matches
+}
+if { $target_info(host,serial) == "" } {
+ incr matches
+}
+if { $target_info(host,netport) == "" } {
+ incr matches
+}
+if { $target_info(host,baud) == "" } {
+ incr matches
+}
+if { $matches == 9 } {
+ puts "PASSED: pop_config host"
+} else {
+ puts "FAILED: pop_config host"
+}
+
+# test execute_anywhere for a native environment
+set host_triplet i586-unknown-linux
+set target_triplet i586-unknown-linux
+set build_triplet i586-unknown-linux
+if { [string match "*setval.tmp*" [execute_anywhere "ls"]] } {
+ puts "PASSED: execute_anywhere, native"
+} else {
+ puts "FAILED: execute_anywhere, native"
+}
+
+# test execute_anywhere for a normal cross
+set target_triplet m68k-unknown-coff
+if { [string match "*testsuite" [execute_anywhere "pwd"]] } {
+ puts "PASSED: execute_anywhere, normal cross"
+} else {
+ puts "FAILED: execute_anywhere, normal cross"
+}
+
+# test execute_anywhere for a canadian cross
+set build_triplet m68k-test-test
+set target_info(host,connect) rlogin
+set target_info(host,netport) $target_info(idp,netport)
+set target_info(host,target) localhost
+if { [string match "*FooBar*" [execute_anywhere "echo FooBar"]] } {
+ puts "PASSED: execute_anywhere, canadian cross"
+} else {
+ puts "FAILED: execute_anywhere, canadian cross"
+}
+
+# compile arg
+# archive arg
+# ranlib arg
+# link_objects arg
diff --git a/dejagnu/testsuite/runtest.all/topdir/subdir1/subfile1 b/dejagnu/testsuite/runtest.all/topdir/subdir1/subfile1
new file mode 100644
index 00000000000..8397fe3953d
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/topdir/subdir1/subfile1
@@ -0,0 +1 @@
+# just so we don't look empty.
diff --git a/dejagnu/testsuite/runtest.all/topdir/subdir1/subfile2 b/dejagnu/testsuite/runtest.all/topdir/subdir1/subfile2
new file mode 100644
index 00000000000..7d1d836f555
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/topdir/subdir1/subfile2
@@ -0,0 +1,2 @@
+# just so we don't look empty.
+
diff --git a/dejagnu/testsuite/runtest.all/topdir/subdir1/subsubdir1/subsubfile1 b/dejagnu/testsuite/runtest.all/topdir/subdir1/subsubdir1/subsubfile1
new file mode 100644
index 00000000000..7d1d836f555
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/topdir/subdir1/subsubdir1/subsubfile1
@@ -0,0 +1,2 @@
+# just so we don't look empty.
+
diff --git a/dejagnu/testsuite/runtest.all/topdir/subdir2/subfile2 b/dejagnu/testsuite/runtest.all/topdir/subdir2/subfile2
new file mode 100644
index 00000000000..7d1d836f555
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/topdir/subdir2/subfile2
@@ -0,0 +1,2 @@
+# just so we don't look empty.
+
diff --git a/dejagnu/testsuite/runtest.all/utils.test b/dejagnu/testsuite/runtest.all/utils.test
new file mode 100644
index 00000000000..f9459d85e92
--- /dev/null
+++ b/dejagnu/testsuite/runtest.all/utils.test
@@ -0,0 +1,118 @@
+set srcdir [lindex $argv 0]
+set subdir [lindex $argv 1]
+set objdir [lindex $argv 2]
+
+if [ file exists $objdir/setval.tmp ] {
+ source $objdir/setval.tmp
+} else {
+ puts "ERROR: $objdir/setval.tmp doesn't exist"
+}
+if [ file exists $srcdir/$subdir/default_procs.tcl ] {
+ source "$srcdir/$subdir/default_procs.tcl"
+} else {
+ puts "ERROR: $srcdir$subdir/default_procs.tcl doesn't exist"
+}
+
+set file $srcdir/../lib/utils.exp
+if [ file exists $file] {
+ source $file
+} else {
+ puts "ERROR: $file doesn't exist"
+}
+
+#
+# getdirs tests
+#
+if [lib_pat_test "getdirs" "${srcdir}/runtest.all" "runtest.all/topdir" ] {
+ puts "FAILED: getdirs toplevel, no arguments"
+} else {
+ puts "PASSED: getdirs toplevel, no arguments"
+}
+
+if [lib_pat_test "getdirs" "${srcdir}/runtest.all top*" "runtest.all/topdir" ] {
+ puts "FAILED: getdirs toplevel, one subdir"
+} else {
+ puts "PASSED: getdirs toplevel, one subdir"
+}
+
+if [lib_pat_test "getdirs" "${srcdir}/runtest.all/topdir" "subdir1*subdir2" ] {
+ puts "FAILED: getdirs toplevel, two subdirs"
+} else {
+ puts "PASSED: getdirs toplevel, two subdirs"
+}
+
+#
+# find tests
+#
+if [string match "*/subdir2/subfile2" "[find ${srcdir}/runtest.all/topdir/subdir2 sub*]"] {
+ puts "PASSED: find, only one level deep"
+} else {
+ puts "FAILED: find, only one level deep"
+}
+
+#set path ${srcdir}/runtest.all/topdir/subdir1
+#exp_test "find ${path} sub*" "Adding */subdir1/subsubdir1/subsubfile1" "find, two levels deep"
+
+if [string match "*/subdir1/subsubdir1/subsubfile1" "[find ${srcdir}/runtest.all/topdir/subdir1 sub*]"] {
+ puts "PASSED: find, two levels deep"
+} else {
+ puts "FAILED: find, two levels deep"
+}
+
+#
+# environment varible utility tests
+#
+
+if [info exists env(TESTRUN)] {
+ unset env(TESTRUN)
+}
+
+# test setenv
+setenv TESTRUN FooBar
+if [info exists env(TESTRUN)] {
+ if { $env(TESTRUN) == "FooBar" } {
+ pass "setenv, set an environment variable"
+ } else {
+ fail "setenv, set an environment variable
+ }
+} else {
+ fail "setenv, set an environment variable"
+}
+# test getenv
+if [info exists env(TESTRUN)] {
+ if { [getenv TESTRUN] == "FooBar" } {
+ pass "getenv, get an environment variable"
+ } else {
+ fail "getenv, get an environment variable"
+ }
+} else {
+ untested "getenv, get an environment variable"
+}
+
+# test unsetenv
+if [info exists env(TESTRUN)] {
+ unsetenv TESTRUN
+ if [info exists env(TESTRUN)] {
+ fail "unsetenv, unset an environment variable"
+ } else {
+ pass "unsetenv, unset an environment variable"
+ }
+} else {
+ untested "unsetenv, unset an environment variable"
+}
+
+# which file
+# grep args
+# prune list pattern
+# slay name
+# absolute path
+# psource file
+# diff file_1 file_2
+
+
+
+
+
+
+
+
diff --git a/expect/CHANGES.2to3 b/expect/CHANGES.2to3
new file mode 100644
index 00000000000..c43e54a1613
--- /dev/null
+++ b/expect/CHANGES.2to3
@@ -0,0 +1,58 @@
+If you used to use Expect version 2 (any version written before
+September '91) you will find that the current version of Expect (3)
+introduced minor but significant incompatibilities.
+
+The HISTORY file describes these briefly. They are described at
+length in the man page.
+
+I'm sorry if you feel annoyed at the incompatibilities, but Expect has
+been out for a year and a half, Tcl even longer. Both Tcl and Expect
+are using this as a last chance to make significant changes, so that
+we will not disturb even more users in the future.
+
+There is no automated conversion procedure (although see note below)
+for Expect or even raw Tcl. For now, I suggest that you not bother
+fixing things that already work - just keep the old Expect around.
+The binary isn't very big after all. If you do write a translation
+script, let me know. Thanks.
+
+Of course, I felt obligated to convert the examples distributed with
+expect. I did this by hand while writing the new version itself,
+partly as an aid but mostly to test lots of variations. In 90% of the
+scripts, all I had to do was change:
+
+(changes due to Tcl)
+ 'index' to 'lindex'
+ 'range' to 'lrange'
+ 'length' to 'llength'
+ 'print' to 'send_user' or 'puts' depending on how you use it
+ 'function .... c' with '[join [function [split string ""]] ""]'
+(changes due to Expect)
+ 'expect_match' to 'expect_out(buffer)'
+ 'set match_max' to 'match_max' (perhaps with -d flag)
+ '*' to '-re .+'
+
+If anyone wants to write a script to do this, note the pitfalls:
+
+1) functions and variables do not share the same namespace, so it is a
+inappropriate to just globally rename things.
+
+A number of optimizations can be made:
+
+1) If you are doing multiple split/joins, you should probably cache the
+split string.
+
+2) Virtually all uses of scan are unnecessary now, due to exec's automatic
+stripping of terminating newlines, and expect's support of regexps.
+
+3) String manipulation can be reduced or avoided entirely if you use
+expect -re.
+
+4) exec is no longer necessary to retrieve environment variables, since
+they can now be retrieved from $env.
+
+5) If you have been really anal about testing for timeout and eof, you
+can dramatically reduce the size of your scripts by using expect_before
+and expect_after. This is more efficient, as well, since those actions
+are only parsed once.
+
diff --git a/expect/CHANGES.3to4 b/expect/CHANGES.3to4
new file mode 100644
index 00000000000..cf8f4b13dec
--- /dev/null
+++ b/expect/CHANGES.3to4
@@ -0,0 +1,115 @@
+This file describes the changes from Expect 3 to Expect 4.
+
+The improvements that people will find most interesting are:
+
+1) Expect version 4 is designed to work with Tcl 6.7 and Tk 3.2.
+ (Earlier versions of Expect will not work with Tcl 6.7)
+ Expect can now be layered in with any Tcl program.
+ Note that in Tk, Expect's send command is called "exp_send".
+ (It used to be called "send_spawn" but this bit the dust.)
+2) A debugger is provided.
+3) The interact command has been totally rewritten and supports regular
+ expressions, timeout/eof patterns, and a number of other new things.
+4) The default behavior of ^C (SIGINT) is exit whether or not you are in
+ a read.
+5) Expect uses "sane" terminal parameters by default, allowing scripts
+ to work the same whether inside emacs shell mode or not. (See man
+ page on "spawn" for more info.)
+6) All the hard parts of the installation process are automated. This
+ was done primarily by Rob Savoye at Cygnus. Thank you, Rob!
+7) It is now possible to buy a support contract for Expect from Cygnus.
+
+The changes that people will find most annoying are:
+
+1) send now only sends a single string. (It used to send any number of
+ strings with spaces jammed in between.)
+2) getpid was renamed pid.
+3) interact's -flush was renamed -nobuffer (much more descriptive).
+4) interact now runs all actions in raw mode unless the flag -reset
+ is used. -f and -F are ignored. send automatically understands
+ how to do the right thing. The most likely thing to watch out for
+ are actions like "exec kill -STOP 0" which almost certainly need
+ the -reset flag.
+5) argv0 is initialized to script name. argv no longer contains it.
+ argc is initialized [llength $argv]. This follows new Tcl style.
+
+All differences are described in the man page. Some of the less
+significant differences are described in the HISTORY file. The
+debugger is described in a separate document (see the README).
+
+This version also introduces one incompatibility that may require
+changes to scripts. While this may initially annoy you, the final
+result will simplify the process of writing scripts. Namely:
+
+In version 3, the expect command accepted lists of glob-style patterns
+such as:
+
+ expect "a\ b c" action
+
+where "a b" or "c" would cause action to be executed. The problem
+with this is that the pattern list is hard to write and hard to read.
+Patterns with control-characters, backslashes and dollar signs were
+very difficult to deal with.
+
+Regular-expression patterns provide a much simpler solution. Via the
+alternation feature (using a "|") the above pattern can be written as:
+
+ expect -re "a b|c" action
+
+I was concerned about people having a significant investment in code
+that depended on the old syntax but responders to a comp.lang.tcl poll
+about such a change in pattern handling were 100% in favor of it. (I
+even proposed hooks for backward compatibility, but there was no
+interest in it.)
+
+Fortunately, most simple things will work as before including:
+
+ expect foobar
+ expect {foobar}
+ expect "foobar"
+ expect "foo\ bar"
+
+However, some things won't work as before. For example, the following
+will behave differently - now the braces will be considered as part of
+the pattern.
+
+ expect "{foo bar}"
+
+Here are examples of patterns in my own code that I had to change:
+
+ was changed to
+ Version 3 pattern list Version 4 pattern
+
+ {Whois:\ } "Whois: "
+ {No\ match} "No match"
+ {250*ftp>* 200*ftp>*} -re "2(5|0)0.*ftp>.*"
+ {{Press Return to continue*}} "Press Return to continue*"
+ {*\r\n*\\\\\r\n} "\r\n*\\\r\n"
+
+
+
+Future Change Alert
+
+John Ousterhout has pre-announced a future change in Tcl that may
+affect you. In particular, backslash sequences other than those
+explicitly listed in the Tcl documentation will be handled as if the
+backslash was not present.
+
+The likely place this arises is when quoting characters that are
+special to the pattern matcher but not to Tcl.
+
+For example in Tcl 6.7, the following command matches a period.
+
+ expect -re "\."
+
+In Tcl 7.0, it will match any character, because Tcl will throw away
+the backslash. If you want to match a period, you will have to say:
+
+ expect -re "\\."
+or
+ expect -re {\.}
+
+The following command will find occurrences of this. (It may find
+other things, but it will at least find the problem cases.)
+
+ egrep '(\\$)|(\\[^][bfnrtv\0-9{}$ ;"])' *.exp
diff --git a/expect/CHANGES.4to5 b/expect/CHANGES.4to5
new file mode 100644
index 00000000000..ca344a4f162
--- /dev/null
+++ b/expect/CHANGES.4to5
@@ -0,0 +1,263 @@
+This file describes the changes from Expect 4 to Expect 5.
+
+The changes that people will find most interesting or annoying are as
+follows. Some of them may seem rather arbitrary but fix inconsistencies
+leading to much cleaner coding both internally and externally.
+
+
+-- Expect version 5.20 and above is designed to work with Tcl 7.5 and
+Tk 4.1. Expect 5.20 and above will not work with earlier versions.
+
+-- Glob-style patterns do longest-possible matches (from the earliest
+possible position) just like regexps. Previously, they matched the
+shortest-possible strings. However, the documentation didn't actually
+say this (it didn't say anything)
+
+-- Exact patterns are now supported from expect. Use the "-ex" flag.
+Exact patterns work just like those in interact. No special handling
+is made of *, ^, etc.
+
+-- The new command "expect_background" registers patterns that are to
+be tested against spawned process output whenever it appears (i.e.,
+asynchronously). This only works in the Tk environment. The
+arguments are the same as the expect command.
+
+-- expect_before and expect_after now handle their arguments like
+expect_background. Previously, a command such as "expect_before"
+with no arguments deleted patterns for all spawn ids. Now, it only
+deletes patterns for the current spawn id. Similarly with the "-i"
+form.
+
+-- expect_background/before/after support an -info flag to query what
+the current patterns are. The results are returned in such a way that
+they can be re-used by a new expect command.
+
+The -info flag must be the first flag in the command. With no other
+arguments, it returns the setting for the current spawn id. With a -i
+descriptor, information is returned for that spawn id. The argument
+-noindirect may be used to suppress indirects which also match a
+direct spawn id. Only a single -i specification may be given with
+-info. With the argument "-all", all spawn id specifications are
+reported.
+
+-- There is now a sleep command. It understands decimal values such as
+
+ sleep .5
+
+Interrupts and other asynchronous events are processed while Expect sleeps.
+
+-- Traps now use Tcl's "Async" support. This has advantages and
+disadvantages. One advantage is that traps have no chance of screwing
+up the Tcl internals. One disadvantage is that trap handlers are
+delayed at certain specific times and places. For example, a handler
+cannot occur inside another handler. While one handler is running,
+all other handlers are blocked. This is probably the most noticable
+place where handlers are blocked. Others are generally small windows,
+so you shouldn't notice the delay in executing the handlers.
+
+Several traps are initially defined:
+
+ trap exit {SIGINT SIGTERM}
+
+If you use the -D flag to start the debugger, the following trap is
+defined:
+
+ trap {exp_debug 1} SIGINT
+
+You can, of course, override these. In particular, if you have your
+own "trap exit SIGINT", this will override the debugger trap. Because
+SIGINT is tied to exit (see above) by default anyway, you should
+remove your own "trap exit SIGINT" unless you specifically do not want
+to be able to get to the debugger by ^C.
+
+If you want to define your own trap on SIGINT but still trap to the
+debugger when it is running, use:
+
+ if ![exp_debug] {trap mystuff SIGINT}
+
+Alternatively, you can trap to the debugger using some other signal.
+
+The ONEXIT trap is no longer available. Instead, say "exit -onexit ..."
+
+Traps are now deleted by using the empty ({}) handler. The current
+handler is returned if no action is supplied. With no arguments, trap
+returns the signal number of the trap command currently being executed.
+
+-- The wait command now returns a four element list if a valid child
+was waited on.
+Element 1: pid
+Element 2: spawn id
+Element 3: 0 (or -1 if there was an OS error)
+Element 4: status (or errno if element 3 == -1)
+
+-- expect and interact notes:
+
+The timeout and eof patterns were initially named "-timeout" and
+"-eof" but have been renamed "timeout" and "eof" to match those of
+expect. The ability to define default timeout/eof actions has been
+removed. (You can do this more easily by grouping spawn ids.)
+
+expect and interact now support a "null" keyword to match an ASCII 0.
+send supports -null and -break keywords.
+
+Since a large number of special keywords have been added to interact,
+a new keyword "-ex" for "exact" was added descriptive of its default
+treatment of patterns. This protects the next token from being
+misinterpreted as a keyword. The expect command provides "-gl" for
+"glob" for analogous reasons.
+
+Any string starting with "-" should be protected by the "-ex" or "-gl"
+flag, even those that are not keywords currently. (All strings
+starting with "-" are reserved for future options.)
+
+String start/end indices are no longer written to expect_out and
+interact_out unless the -indices flag is given.
+
+expect_out(spawn_id) is set to the spawn id associated with the spawn
+id that produced the last output in an expect command. For example,
+you can use this to delete files that have closed, by removing this
+element from an indirect spawn ids spec. The same effect is
+reproducable with interact (and interact_out(spawn_id)) but for
+efficiency reasons, it requires the -iwrite flag before each pattern.
+
+Expect's -i and interact's -i, -u, -input, and -output flags can now
+describe a list of spawn ids. So you can say things like:
+
+ interact -input "$id1 $id2 $id3" .... -output "$id1 $id2" ...
+
+In this case, id1, 2, 3 would be sent to id1, and 2.
+
+The spawn id may be given as a global variable name (called an
+"indirect spawn id specification"), in which case, the variable
+contains the list of spawn ids. Whenever the variable is changed, the
+new list of spawn ids is automatically used. This is particularly
+useful with any long running expect command such as expect_before,
+expect_after, expect_background, and interact.
+
+The -update flag was removed. Use indirect spawn ids (see previous
+paragraph).
+
+-- interact notes:
+
+Interact now support -input and -output flags that provide very
+flexible means of moving data from/to multiple spawn ids in complex
+ways (but very quickly). It is possible to write most expect loops
+using a simple interact statement. For instance, the three way
+interaction inside kibitz (between two users and a process) is written
+this way:
+
+ interact {
+ -output $shell
+ -input $userin eof { . . . } -output $shell
+ -input $shell -output "$user_spawn_id $userout"
+ }
+
+-- send command notes:
+
+It is possible to send a break by using the "-break" flag.
+
+Any string starting with "-" should be protected by preceding it with
+the "--" flag, even those that are not keywords currently. (All
+strings starting "-" are reserved for future options.)
+
+-- The spawn command now takes an "-open" flag which in turns takes a
+Tcl file as an argument. This lets you treat raw devices, files, and
+pipelines as spawned processes without using a pty.
+
+This was actually in Expect 4, but I forgot to document it. Oops!
+
+-- The old "debug" command (which describes what Expect is doing
+internally) was renamed "exp_internal". "debug" (and "exp_debug") now
+invoke the interactive debugger.
+
+-- The new command "stty" now takes over the job of "system stty". It
+works much better, allowing POSIX-style redirection to affect other
+ttys. It otherwise takes arguments as "system stty" did.
+
+-- The "-tcl" option to "return" has gone away. (This was dangerous
+to anyone that actually happened to return the value "-tcl".)
+Instead, use inter_return.
+
+-- Added exp_timestamp command to produce very fast timestamps.
+
+-- Added exp_pid command to return pid of given spawn id.
+
+-- The close command now takes an argument of "-onexec" with a following
+0 or non-zero value. For example, the follow command stops the
+current spawn id from being closed when another process is exec'd or
+spawn'd.
+
+ close -onexec 0
+
+While "-onexec 1" returns it to the default condition where it will be
+closed upon exec or spawn.
+
+-- log_user now returns previous value. It is acceptable to call now,
+without arguments just to get the value.
+
+-- The following forms are deprecated. They will be allowed
+indefinitely but not advertised or supported if they break.
+
+ -eof, -timeout in interact (reason: didn't match expect.
+ Instead, use eof or timeout.)
+
+ -- in expect or interact (reason: no easier to read.
+ Instead, use -gl in expect or -ex in interact.)
+
+ continue -expect (reason: when mixing in extensions, you have
+ to use exp_continue, so -expect becomes irrelevant.
+ Instead, use exp_continue.)
+
+ getpid (reason: Tcl now supplies same functionality as "pid".
+ Instead, use pid.)
+
+ expect_version and expect_library (reason: the name implies
+ they have something to do with the expect command,
+ which they doesn't.
+ Instead, use exp_version and exp_library.)
+
+ -timestamp for obtaining tm and ctime in expect and interact
+ (reason: separate command now exists for this purpose.
+ Instead, use exp_timestamp.)
+
+ system stty (reason: bad interaction with redirection.
+ Instead, use stty.)
+
+-- New examples have been added:
+
+"dislocate" lets you disconnect and reconnect to processes.
+
+"tkpasswd" illustrates passwd embedded in a GUI.
+
+They may not be overwhelmingly useful, but run them once to see what
+they do. If you ever need to do anything similar, you can look back
+at them.
+
+"tknewsbiff" pops up a window or plays a audio clip when you have
+unread news.
+
+-- Changes to the Expect libraries:
+
+The expect-tcl library (libexpectcl.a) has been integrated with the
+expect library (libexpect.a). So references to libexpectcl.a should
+be removed.
+
+The Expect C library now supports buffering, multiplexing, null
+matching, full buffer matching. Basically, all of the features in
+Expect are now in the library.
+
+Buffering and multiplexing has caused the biggest change to the
+library. Previously, exp_match contained the entire buffer that
+matched. Now exp_match just points to where in the buffer the match
+started. exp_buffer points to the beginning of the buffer.
+Previously, the previous buffer was thrown away at the beginning of
+each expect function call. Now, previously unmatched characters are
+eligible for matching.
+
+To match on different file descriptors, exp_match, exp_match_end,
+exp_buffer_end must be restored to their previous values. Initially,
+they should be zero.
+
+The meaning of timeout == 0 in the Expect library has been changed.
+See the man page for more info.
+
diff --git a/expect/ChangeLog b/expect/ChangeLog
new file mode 100644
index 00000000000..13cf1fb512b
--- /dev/null
+++ b/expect/ChangeLog
@@ -0,0 +1,887 @@
+1999-10-29 Frank Ch. Eigler <fche@cygnus.com>
+
+ * configure.in: For cygwin host, also override TCL_LIB_SPEC.
+ * configure: Regenerated.
+
+1999-10-27 DJ Delorie <dj@cygnus.com>
+
+ * configure.in: Use $host, not results of build, to detect
+ cygwin-specific tcl library
+
+1999-10-26 DJ Delorie <dj@cygnus.com>
+
+ * configure.in: If we detect a cygwin-specific version of tcl,
+ use it.
+ * exp_event.c: don't need the extra functions any more.
+
+Wed Oct 6 04:12:08 1999 Brendan Kehoe <brendan@cygnus.com>
+
+ * configure.in (EXP_LD_SEARCH_FLAGS): If $GCC is "yes", don't do
+ the substitution translating -Wl,-rpath,foo into just -rpath,
+ since we're not using just the linker.
+ * configure: Regenerated.
+
+1999-09-17 DJ Delorie <dj@cygnus.com>
+
+ * expect.c: define SIMPLE_EVENT so that timeouts work
+
+Wed Sep 15 19:29:13 1999 Jeffrey A Law (law@cygnus.com)
+
+ * exp_command.c (Exp_SpawnCmd): Make wfd and rfd wide enough and
+ aligned enough so that they can hold pointer values.
+
+1999-09-14 Felix Lee <flee@cygnus.com>
+
+ * exp_main_exp.c (main): call Tcl_FindExecutable.
+
+1999-06-01 Angela Marie Thomas <angela@cygnus.com>
+
+ * Makefile.in: Add install-minimal target.
+
+1999-05-18 Fred Fish <fnf@cygnus.com>
+
+ * exp_strf.c (strchr): Do not try to declare if defined
+ already with a #define.
+
+1999-05-03 Tom Tromey <tromey@cygnus.com>
+
+ * configure, Dbgconfigure: Rebuilt with newer autoconf.
+
+Mon Nov 2 15:05:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: detect cygwin* instead of cygwin32*
+ * configure: regenerate
+
+Fri Oct 16 22:26:59 1998 <dj@cygnus.com>
+
+ * exp_event.c (pipe_thread): don't select or WFSO forever,
+ else you hang when pipe_close is called.
+
+Thu Oct 08 16:08:57 1998 <dj@cygnus.com>
+
+ * exp_command.c (cygwin_pipe_dup): use this instead of dup()
+ because sometimes we try to dup() a handle instead of a fd
+ * exp_event.c (pipe_thread): check for "forgotten" threads
+ and clean them up properly (else leaks).
+
+Thu Oct 1 13:22:28 1998 DJ Delorie <dj@indy.delorie.com>
+
+ * exp_event.c (pipe_watch): close a thread handle leak.
+
+1998-09-28 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure.in: Comment out not using -g on Linux.
+ * configure: Regenerated.
+
+Thu Sep 24 12:04:39 1998 DJ Delorie <dj@indy.delorie.com>
+
+ * exp_command.c (fd_new): move cygwin init outside of tcl version
+ check.
+
+Thu Sep 17 18:08:42 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * exp_event.c (pipe_info): Reorganize for better cygwin
+ functionality.
+ (pipe_thread): Use cygwin select() to detect pipe activity
+ since it now correctly handles EOF conditions.
+ (pipe_close): Reorganize for better operation with pipe_thread
+ change.
+ (pipe_get_handle): Return cygwin fd since Windows handle is
+ no longer required.
+ (make_pipe_channel): Remove initialization of obsolete fields.
+
+1998-08-28 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * aclocal.m4(CY_AC_LOAD_TCLCONFIG): Don't look for
+ Tcl_CreateCommand(), cause libtcl hasn't been built yet. All this
+ did was try to make sure you haven't removed your Tcl build
+ directory.
+ * configure: Regenerated.
+
+1998-08-21 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * Most files: Merge in expect 5.26 to get better tcl8.x
+ support. See HISTORY for more details.
+
+ * aclocal.m4 (CY_AC_INTTYPES_H): Find inttypes.h, but if it's
+ definitions conflict with sys/types.h, then don't include
+ it.
+
+Wed Jul 15 11:06:50 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * configure.in: Fix typo.
+ * configure: Regenerated.
+
+Tue Jul 14 13:27:30 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * configure.in (EXP_BUILD_LIB_SPEC): Always link expect against
+ the static library.
+ (EXP_LIB_FILE): Always set to EXP_NONSHARED_LIB_FILE.
+
+ * configure: Regenerated.
+
+Tue Apr 28 18:54:13 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * aclocal.m4: add autoconf macros AM_EXEEXT and AM_CYGWIN32
+ * configure.in: call AM_EXEEXT
+ * Makefile.in: add EXEEXT variables
+ * configure: regenerate
+
+Thu Mar 19 09:12:04 1998 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in: Handle hpux11 just like hpux10 for now.
+
+Sat Feb 28 17:24:38 1998 Richard Henderson <rth@cygnus.com>
+
+ * exp_command.c: Use _NSIG if NSIG not present.
+ * exp_trap.c: Likewise.
+
+Sun Feb 22 17:39:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * exp_event.c: Extensive additions to support
+ Tcl_CreateFileHandler and Tcl_DeleteFileHandler on cygwin32.
+ Define a new pipe channel type, based on code in tclWinPipe.c.
+ * exp_command.h (struct exp_f): If __CYGWIN32__, add channel,
+ fileproc, and procdata fields.
+ * exp_command.c (fd_new): If __CYGWIN32__, initialize channel and
+ fileproc fields.
+ (Exp_SpawnCmd): If __CYGWIN32__, don't accept -open or -leaveopen
+ argumnents.
+ (Exp_LogFileCmd): Likewise.
+ (Tcl_CloseCmd): Use Tcl_Alloc instead of ckalloc. Use
+ Tcl_NewStringObj instead of TclNewObj and TclInitStringRep. Use
+ Tcl_Free instead of ckfree.
+ * expect.c (exp_i_read): If __CYGWIN32__, call
+ exp_reading_from_descriptor.
+ * pty_termios.c: If __CYGWIN32__, don't include <sys/stropts.h>.
+ (pty_stty): If __CYGWIN32__, just exec stty, not /bin/stty.
+ (getptyslave): If __CYGWIN32__, don't I_PUSH anything.
+ * configure.in: Add many checks for cross_compiling to avoid doing
+ the wrong thing when building with a cross compiler. Add several
+ cases to specifically handle a cygwin32 host when building with a
+ cross compiler. On cygwin32, link against -luser32.
+ * configure: Rebuild.
+
+Fri Jan 30 16:48:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't check for openpty on Linux. It exists on
+ Alpha Linux Red Hat 4.2, but it doesn't work correctly.
+
+Thu Jan 22 17:29:27 1998 Fred Fish <fnf@cygnus.com>
+
+ * exp_clib.c (exp_spawnv): Provide reason for error message if we
+ fail to get the controlling terminal using TIOCSCTTY.
+ * exp_command.c (Exp_SpawnCmd): Ditto.
+
+Sun Dec 7 20:39:33 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * exp_command.c(Exp_SpawnCmd): Use ClientData instead of
+ int for file descriptors.
+
+Wed Oct 15 12:14:26 1997 Jeffrey A Law (law@cygnus.com)
+
+ * testsuite/config/default.exp (eprompt): Tweak again for new
+ prompt variant.
+
+Fri Sep 12 12:57:10 1997 Jeffrey A Law (law@cygnus.com)
+
+ * testsuite/config/default.exp (eprompt): Accept new prompt
+ variant.
+
+Fri Sep 12 10:40:56 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * exp_main_sub.c: Instead of using -1 for an invalid value, use 1
+ instead--this will allow the "testsuite" to pass.
+
+Thu Sep 4 11:49:44 1997 Jeffrey A Law (law@cygnus.com)
+
+ * exp_command.c (NUM_ARGS): Move start of cpp #define to
+ column zero.
+
+Thu Aug 28 16:42:58 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * exp_command.c (Tcl_CloseCmd): Function to call Tcl_CloseObjCmd
+ with appropriate arguments, mostly stolen from tclBasic.c.
+
+ * Dbg.c (simple_interactor): There doesn't appear to be any
+ equivalent for curEventNum, so replace with -1 for now. (It only
+ appears in the prompt anyway).
+ * exp_main_sub.c (Exp_Prompt1Cmd): Ditto.
+ * exp_main_sub.c (exp_interpreter): Ditto.
+
+Wed Aug 13 12:57:20 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * Makefile.in (X11_PROGS): Commented out until expectk is working
+ with tcl8.
+ (X11_PROGS_INSTALLED): Ditto.
+
+Mon Aug 11 20:56:56 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * Changes to get expect working under tcl8.
+
+ * expect.c: Include tclInt.h to get a definition of TclWordEnd.
+ (exp_eval_with_one_arg): Under Tcl8 TclWordEnd takes an additional
+ parameter. Don't go past the end of the string.
+
+ * exp_main_exp.c: If USE_ITCL is defined, include a call to
+ Itcl_Init.
+
+ * exp_command.c: Tcl8 uses an OS-specific type for "file handles".
+ This code will NOT work under anything that doesn't use an int;
+ it requires cleanup to make it reasonably portable.
+ * exp_command.h: Ditto.
+
+ * aclocal.m4: Check for itcl headers.
+ * configure.in: Ditto.
+
+ * Makefile.in: Add expecti target.
+
+ * Dbg.c (print_argv): Tcl8 has a new argument to TclFindElement
+ specifying the length of the string.
+ (PrintStackBelow): Tcl8 uses objc/objv in the stack frame
+ instead of argc/argv; this change is woefully incomplete.
+
+Tue Apr 1 13:55:15 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * exp_event.c(exp_get_next_event): Don't delete the
+ timeout timer until we actually return.
+
+Thu Mar 20 14:27:45 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: don't check if stty reads stdout for
+ i[[3456]]86-*-sysv4.2MP during config; hard code instead
+ * configure: regenerated
+
+Thu Mar 13 10:43:06 1997 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (FLAGS_TO_PASS): Removed RUNTEST, RUNTESTFLAGS.
+ (RUNTESTFLAGS): Removed.
+ (RUNTEST): Removed.
+
+ * configure: Regenerated.
+ * configure.in: Always set EXP_CFLAGS to "".
+
+ * configure.in (AC_CONFIG_AUX_DIR): Look in srcdir.
+
+Wed Nov 20 10:42:03 1996 Tom Tromey <tromey@cygnus.com>
+
+ * configure.in: Always respect CFLAGS as passed in environment.
+ If not set, let AC_PROG_CC set it.
+
+Tue Nov 19 09:22:08 1996 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (install_shared_lib): Put else clause onto each if.
+
+Fri Nov 15 11:23:43 1996 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (XCFLAGS): Use EXP_SHLIB_CFLAGS, not
+ TCL_SHLIB_CFLAGS.
+ (TCL_SHLIB_CFLAGS): Define.
+
+ * configure.in: Allow arguments to --enable-blah to work.
+ Compute and AC_SUBST EXP_SHLIB_CFLAGS.
+ Added missing AC_MSG_CHECKING.
+
+Thu Nov 7 13:30:39 1996 Tom Tromey <tromey@cygnus.com>
+
+ * Dbg.c, exp_clib.c, exp_command.c, exp_command.h, exp_glob.c,
+ exp_int.h, exp_inter.c, exp_main_sub.c, exp_printify.c,
+ exp_printify.h, exp_pty.h, exp_trap.c, exp_tty.c, exp_tty.h,
+ exp_win.c, exp_win.h, expect.c, expect_comm.h, pty_termios.c:
+ Changes to make gcc -Wall complain less.
+
+Mon Nov 4 14:01:03 1996 Tom Tromey <tromey@cygnus.com>
+
+ * exp_clib.c (exp_disconnect): #if condition fix.
+ (exp_spawnv): Ditto.
+
+ * exp_command.c (Exp_SpawnCmd): #if condition fix.
+ (Exp_DisconnectCmd): Ditto.
+
+Tue Oct 15 12:38:50 1996 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Regenerated.
+ * configure.in: Make sure to pass --cache-file argument to
+ sub-configure.
+
+Wed Oct 9 11:24:17 1996 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Regenerated.
+ * configure.in (stty_reads_stdout): /bin/stty on OSF 4.0 fails.
+
+Wed Oct 2 10:13:37 1996 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Regenerated.
+ * configure.in (stty_reads_stdout): /bin/stty on DG/UX fails.
+
+Tue Oct 1 10:40:11 1996 Tom Tromey <tromey@cygnus.com>
+
+ * Dbg.c, exp_clib.c, exp_closetcl.c, exp_command.c, exp_console.c,
+ exp_event.c, exp_inter.c, exp_main_tk.c, exp_pty.c, exp_strf.c,
+ exp_trap.c, exp_win.c, exp_win.h, expect.c, pty_termios.c: Patches
+ to make "gcc -Wall" be more quiet. From Fred Fish.
+
+Fri Sep 27 10:15:48 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * expect.c (exp_i_read): Pass interp as first arg to exp_error.
+ * configure.in (stty_reads_stdout): /bin/stty on OSF2.0, OSF3.2,
+ HPUX 9.X, HPUX 10.X guesses wrong, so set value explicitly.
+
+Mon Sep 9 10:29:32 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure: Regenerated.
+ * configure.in: Added code to actually handle --with-x.
+
+ * configure: Regenerated.
+ * configure.in: Don't bother looking for Tk if --with-x=no
+ specified.
+
+Thu Sep 5 11:01:09 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure: Regenerated.
+ * configure.in (stty_reads_stdout): AIX fails "stty" test in
+ background, so set explicitly. Ditto HPUX 9 and 10.
+
+Thu Aug 29 17:04:55 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (i[345]86-*-*): Recognize i686 for pentium pro.
+ * configure: Regenerate.
+
+Mon Aug 26 12:33:58 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (install): Depend on install_shared_lib.
+
+Fri Aug 23 10:17:45 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure: Regenerated.
+ * configure.in: Look in `..' for aux files. Re-enable caching.
+
+Fri Aug 16 12:54:39 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * exp_main_tk.c (print_version): New variable.
+ (argTable): Added -version.
+ (Tk_Init2): Print version if required.
+
+ * exp_main_sub.c (exp_parse_argv): Added `-v' support again.
+
+Wed Aug 14 12:02:26 1996 Tom Tromey <tromey@rtl.cygnus.com>
+
+ * Makefile.in (X11_PROGS_INSTALLED): Now the same as X11_PROGS.
+ (install): Don't depend on expect_installed.
+ (clean): Don't remove expect_installed or expectk_installed.
+ (mostlyclean): Ditto.
+
+Mon Aug 5 12:55:06 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (XCFLAGS): New macro.
+ (CFLAGS): Define to just @CFLAGS@.
+ (CFLAGS_INT): Use $(XCFLAGS).
+ (expect, expect_installed, expect.tc, expectk, expectk_installed,
+ expectk.tc): Use $(XCFLAGS).
+
+Tue Jul 23 14:00:56 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * expect_comm.h: Don't include expect_cf.h.
+
+ * Makefile.in (install): Don't install expect_cf.h.
+
+Thu Jul 18 17:27:12 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (install-scripts): Install cat-buffers here.
+
+Mon Jul 15 13:50:52 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (configure): Don't automatically rebuild.
+ (Dbgconfigure): Don't automatically rebuild.
+
+Mon Jun 24 17:47:52 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir,
+ execdatadir): Uset autoconf set values.
+ (docdir, oldincludedir): Removed.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * configure: Rebuilt.
+
+Wed Jun 12 14:18:09 1996 Tom Tromey <tromey@thepub.cygnus.com>
+
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TCLH, CY_AC_PATH_TKH): Use odd names to
+ avoid name clashes with SunOS headers.
+
+Tue Jun 4 17:54:06 1996 Gordon Irlam <gordoni@snuffle.cygnus.com>
+
+ * install-sh: Add MIT copyright. Fix typo.
+
+Tue May 28 13:09:26 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (Dbgconfigure): Removed broken srcdir test.
+
+ * Dbgconfigure: Regenerated.
+ * Dbgconfig.in: Use CY_AC_C_WORKS.
+
+ * configure: Regenerated.
+ * aclocal.m4 (CY_AC_PATH_TCLH): Don't use AC_TRY_RUN.
+ (CY_AC_PATH_TKH): Don't use AC_TRY_RUN.
+
+Tue May 21 10:14:24 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure: Regenerated.
+ * aclocal.m4: Typo fix.
+
+Thu May 16 09:54:18 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure: Regenerated.
+ * configure.in: Use CY_AC_C_WORKS instead of CY_AC_C_CROSS.
+ * aclocal.m4: Replaced CY_AC_C_CROSS with CY_AC_C_WORKS.
+
+Fri May 10 16:59:46 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * exp_pty.c (errno): Delete. Include errno.h instead.
+
+Tue Apr 30 10:17:41 1996 Tom Tromey <tromey@snuffle.cygnus.com>
+
+ * exp_main_tk.c (main): Removed "-inet-1.0".
+
+ * exp_main_sub.c (exp_parse_argv): Removed "-inet-1.0".
+
+ * configure: Regenerated.
+ * configure.in: Append $XLIBS to X_LIBS.
+ (have_nsl): Only check for -lnsl once.
+ Run AC_CANONICAL_SYSTEM.
+
+ * Makefile.in (install): Don't install scripts.
+ (install-scripts): New target.
+
+ * exp_main_tk.c (print_version): New global.
+ (argTable): Added -version.
+ (main): Handle -version option.
+
+ * exp_main_exp.c (argv): Run Tcl_FindExecutable.
+
+ * exp_main_tk.c (main): Run Tcl_FindExecutable.
+
+ * exp_main_sub.c (exp_parse_argv): Added -v argument.
+ (exp_version): No longer static.
+
+Thu Apr 25 12:31:21 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in: Removed "$(srcdir)/" from all dependencies, to work
+ around problem with Sun make's VPATH.
+
+Mon Feb 12 23:11:38 1996 Rob Savoye <rob@chinadoll>
+
+ * aclocal.m4: Fix typo of ac_cv_tkh to be ac_cv_tclh so it works
+ on all systems.
+ * configure, DBGconfigure, testsuite/configure: Regenerated with
+ autoconf 2.7.
+
+Tue Feb 6 11:48:05 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * exp_clib.c, exp_printify.c, expect_comm.h: For Tcl 7.5 and
+ greater, use ../compat/stdlib.h, not compat/stdlib.h.
+
+Tue Jan 30 12:21:37 1996 Fred Fish <fnf@kalessin.cygnus.com>
+
+ * exp_regexp.c (regmatch, regrepeat): Only declare strchr if it is not
+ a macro.
+
+Mon Jan 22 11:17:06 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure.in: Check for -lieee, -ldl, and -ldld.
+
+ * Makefile.in (OFILES): Include @LIBOBJS@.
+ (strerror.o): New target.
+
+ * strerror.c: New file.
+
+ * configure.in: Test for strerror.
+
+Fri Jan 19 11:08:11 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (install, ${SCRIPT_LIST}, test): Find new Tcl libraries.
+
+Thu Jan 18 13:43:13 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Most files: Update to expect 5.19.
+
+Fri Jan 12 16:22:12 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * exp_closetcl.c (exp_close_tcl_files): Skip stdin, stdout,
+ stderr.
+ * expect_comm.h: Declare exp_close_files_interp.
+ * exp_command.c (exp_init_most_cmds): Set exp_close_files_interp.
+
+Thu Jan 11 09:43:14 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * exp_closetcl.c (exp_close_files_interp): New variable for Tcl
+ 7.5.
+ (exp_close_tcl_files): Updated for Tcl 7.5.
+
+ Prototype and varargs changes:
+ * expect.c: Don't include <varargs.h>.
+ * Dbg.c: Copied in many defines from expect_comm.h.
+ (print): Use new varargs defines.
+ * exp_clib.c (exp_fexpectl): Use EXP_VARARGS_START.
+ * expect_comm.h: Include "tclInt.h".
+ * exp_console.c (exp_console_manipulation_failed): First arg to
+ errorlog is char*, not FILE*.
+ * exp_log.c (debuglog): Pass name of last argument to
+ EXP_VARARGS_START.
+ * expect_cf.h.in (tcl_AsyncReady): Removed define.
+ * expect.c (Exp_ExpectGlobalCmd): Added cast.
+ * exp_command.c (exp_i_update): First arg to exp_debuglog is
+ * exp_poll.c (exp_get_next_event): Likewise.
+ char*, not Tcl_Interp*.
+ * exp_log.h: Use prototypes everywhere. Include "expect_comm.h".
+ * expect_tcl.h: Use EXP_VARARGS, not VARARGS.
+ (tcl_AsyncReady): New define for Tcl 7.5.
+
+ * aclocal.m4 (CY_AC_PATH_TCLH): Handle Tcl 7.5 and greater.
+ (CY_AC_PATH_TCLLIB): Handle Tcl 7.5 and greater.
+ (CY_AC_PATH_TKH): Handle Tk 4.1 and greater.
+ (CY_AC_PATH_TKLIB): Handle Tk 4.1 and greater. Properly quote
+ argument to AC_REQUIRE.
+ * configure: Regenerated.
+
+Tue Jan 9 16:26:47 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * Makefile.in: Change SHORT_BINDIR to $prefix, rather than
+ exec_prefix. This is only used to store the platform independant
+ expect scripts.
+
+Dec 18 17:22:05 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in, configure: For a solaris2 machine doing a static
+ build, add `-ldl -lw' to avoid unresolved refs using the
+ OpenWindows libraries.
+
+Wed Nov 22 08:49:01 1995 Rob Savoye <rob@chinadollchinadoll.cygnus.com>
+
+ * Most files: Update to expect 5.18.1.
+
+Fri Nov 17 17:31:55 1995 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure.in: Add support for SCO OpenServer. It doesn't like
+ the trap either.
+
+Thu Nov 16 09:28:53 1995 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure.in: Use $host to get the OS type rather than trying to
+ get the host name ourselves. Use the $host to set the
+ STTY_READS_STDOUT for hosts were the test is known to fail. It
+ also now configures in the background.
+ * configure.in, Dbgconfig.in, testsuite/configure.in: Use
+ AC_PROG_CC again since Cygnus configure now does the sames thing.
+
+Mon Oct 30 18:16:48 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (no_tk): zero out X_PROGS if we can't find tk
+ libraries.
+
+Tue Oct 24 18:25:09 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Makefile.in (X11HDIR): Changed to X11_CFLAGS.
+ (X11_LIB_FLAGS): Changed to X11_LDFLAGS.
+ (X11_LIB): Changed to X11_LIBS.
+ (CPPFLAGS_SIMPLE): Use X11_CFLAGS.
+ (expectk, expectk.tc, tk): use X11_LDFLAGS & X11_LIBS.
+
+ * configure.in (X11HDIR, X11_LIB_FLAGS, X11_LIB): Use X11_CFLAGS,
+ X11_LDFLAGS, X11_LIBS. Link X11 statically on Solaris, SunOS and
+ HPUX.
+
+Thu Oct 19 20:55:54 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in: Remove extraneous tabs and blanks in otherwise
+ empty lines. That confuses older non-GNU versions of "make".
+
+Mon Oct 9 20:58:50 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * testsuite/aclocal.m4: New file. Include ../aclocal.m4.
+
+Thu Aug 31 00:16:26 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * HISTORY, Makefile.in, aclocal.m4, exp_command.h, exp_inter.c,
+ exp_main_tk.c, exp_pty.c, expect.c, tests/all,
+ testsuite/Makefile.in. Update to the 5.18.0 release. Minor
+ changes.
+
+Thu Aug 17 18:47:21 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * Most files: Update to the 5.17.7 release.
+
+Thu Aug 3 22:47:36 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * pty_termios.c (HAVE_PTMX): Undefine if both HAVE_PTYM and
+ HAVE_PTMX are defined (as happens for hpux10).
+
+Thu Jul 27 16:31:23 1995 J.T. Conklin <jtc@cygnus.com>
+
+ * Makefile.in (configure): Removed rule that automatically
+ rebuilds configure script. Users might not have autoconf.
+
+Tue Jul 18 23:15:03 1995 Fred Fish <fnf@fishbowl>
+
+ * expect.c (Exp_ExpectGlobalCmd): Cast ckrealloc first arg to char*.
+
+Sun Jun 18 13:02:41 1995 Fred Fish <fnf@amigalib.com>
+
+ * configure, configure.in (XLIBS): When adding -lX11, also preserve
+ the previous libraries that we went to the trouble of finding.
+
+Sun Jun 18 12:15:44 1995 Fred Fish <fnf@amigalib.com>
+
+ * Makefile.in (exp_clib.o): Add dependencies.
+
+Mon May 1 16:50:22 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * configure.in: Also set XINCLUDES in the Makefile.
+
+Fri Apr 28 18:56:02 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * aclocal.m4: Create a clone of AC_C_CROSS called CY_C_CROSS that
+ has better error handling in case the native compiler is hosed.
+ * aclocal.m4: Look for tcl and tk directories as just tcl (and tk)
+ or tcl[0-9] (and tk[0-9)] so it doesn't match the tclX
+ release. Print an error and exit if any of the --with-{tcl,tk}*
+ options are used and point to bogus paths. Based Tcl header search
+ on tclInt./h rather than tcl.h.
+ * Makefile.in: Add dependancies for back in for configure and
+ Dbgconfigure targets.
+
+Mon Apr 24 16:46:01 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * exp_command.c, exp_event.h, exp_inter.c, exp_main_tk.c,
+ exp_poll.c, exp_select.c, exp_simple.c, exp_tk.c, exp_trap.c,
+ exp_tty.c, FAQ, README, HISTORY: Update to expect 5.16.3.
+
+Fri Apr 14 12:00:39 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * configure.in: Copy Dbg_cf.h to objdir, not srcdir.
+
+Tue Apr 11 18:52:24 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * aclocal.m4: Split the macros so header and library searches are
+ seperate macros. AC_PATH_{TCL,TK} nows only calls the macros. Lots
+ of optimization to the AC_PATH_T* macros. Supports the use of
+ --with-tclinclude, --with-tcllib, --with-tkinclude, --with-tklib
+ to specify alternative search dirs for tcl and tk stuff.
+ * Makefile.in, testsuite/Makefile.in: Re-write targets for
+ configure, Dbgconfigure so they work in an unconfigured srcdir.
+ * configure.in: Put AC_PATH_X before AC_PATH_TK and make the TK
+ test conditional. Fix how Dbgconfigure gets passed the Tcl header
+ dir to use --with-PACKAGE which is much simpler. Removed the test
+ for user override of X search paths since AC_PATH_X uses.
+ --x-includes and --x-libraries instead.
+ * Dbgconfig.in: Use AC_PATH_TCLH to find just the headers, and
+ test for LynxOS.
+ * debugger/: Remove directory. Recursive configuring is so much
+ easier...
+ * DbgMkfl.in, Dbg_cf.h.in, Dbg.c, Dbg.h, Dbgconfigure,
+ Dbgconfig.in: Sigh, moved back to the top-level expect directory.
+
+Wed Apr 5 17:25:45 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * configure.in: Add a trap so the configure runs in the
+ background.
+
+Thu Mar 16 16:56:08 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * debugger: New directory for the Tcl debugger.
+ * debugger/Dbg.c, debugger/Dbg.h, debugger/Dbg_cf.h.in: Moved from
+ the top level expect directory so it builds standalone.
+ * DbgMkfl.in, debugger/Makefile.in: Moved to debugger dir and
+ renamed.
+ * install-sh, mkinstalldirs: New files borrowed from the autoconf
+ distribution.
+ * aclocal.m4: New autoconf macros.
+ * Makefile.in: Tweaked so it's recursive.
+ * configure.in: Use new macros in aclocal.m4 rather than hunting
+ for the Tcl and Tk stuff ourseleves.
+ * debugger/Makefile.in: Build debugger standalone.
+ * testsuite/Makefile.in, testsuite/configure.in: New files for
+ autoconf support.
+ * exp_test.c, testsuite/exp_test.c: Move test file.
+
+Fri Jan 13 15:30:30 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * Makefile.in (check): Pass EXPECT correctly to runtest.
+
+Thu Oct 20 18:04:06 1994 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * Makefile.in: Add X11_INCLUDE_FLAGS so top level flags get used
+ too.
+
+Tue Jun 14 12:32:07 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * aclocal.m4: Copy from TCL directory.
+ * configure.in: Improve checks for installed Tcl and Tk.
+ * configure: Rebuilt.
+
+Tue Jun 7 13:52:34 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (mostlyclean, realclean): New targets.
+
+Wed May 18 12:21:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (install): Add another ``else true''.
+
+Fri Apr 29 16:49:36 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (install): Always use else in if conditional to
+ avoid Ultrix sh bug.
+
+Mon Apr 11 15:22:12 1994 Rob Savoye (rob@cirdan.cygnus.com)
+
+ * Upgrade to the new "official" beta release of expect 5.7.
+
+Wed Mar 30 17:15:28 1994 Rob Savoye (rob@cirdan.cygnus.com)
+
+ * testsuite/expect.tests/expect-test.exp: Just run the new expect
+ tests and format the outout under DejaGnu.
+
+Mon Mar 28 14:33:55 1994 Rob Savoye (rob@cirdan.cygnus.com)
+
+ * Upgrade to expect 5.6.3.
+
+Thu Dec 2 16:26:54 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * configure.in: Add tests to find Tcl and Tk headers and
+ libraries.
+
+Thu Aug 19 18:26:49 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * upgraded to version 4.7.6, add OSF/1 patches in again.
+
+Wed Aug 18 20:10:16 1993 Rob Savoye (rob@rtl.cygnus.com)
+
+ * upgraded to version 4.7.4, add OSF/1 patches in again.
+
+Tue Aug 17 20:17:40 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * pty_termios.c, exp_command.c, configure.in: Add support for
+ using ptmx_bsd's if they exist. Only found on OSF/1. (patch
+ applied from Gregory Depp <depp@osf.org>
+
+Thu Jun 10 11:36:09 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * exp_main.h: fix prototype for exp_cook
+
+Fri Jun 4 08:55:22 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (TCLLIB): If ../tcl/libtcl.a does not exist, use
+ -ltcl.
+
+Tue May 25 14:45:12 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * Makefile.in, configure.in: Add some support for autoconfiguring
+ for X.
+
+Sun May 23 22:32:09 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * exp_command.c: Fix so send_log still works when master is out of
+ bounds. (ok since it doesn't get used).
+
+Mon May 17 19:51:52 1993 Rob Savoye (rob@cygnus.com)
+
+ * configure.in: Change test for ranlib so it kicks out "true"
+ rather than "@:" if it can't be found.
+
+Thu Apr 15 14:11:50 1993 Rob Savoye (rob@cygnus.com)
+
+ * configure.in, Makefile.in: If using ptmx's (SVR4 style pty's)
+ then check for libpt.a too.
+
+Thu Apr 8 17:13:39 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: all doesn't depend on $(SCRIPTS). When building
+ $(SCRIPTS) using fixline & sources in $(srcdir), not the current
+ directory. When installing manpages, install from $(srcdir).
+ Don't install like "install foo $(bindir)" but rather "install foo
+ $(bindir)/foo".
+
+Mon Mar 22 23:56:29 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add check & installcheck targets
+
+Tue Mar 2 20:28:30 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in, configure: declare SETUID to be @: instead of echo
+
+ * pty_termios.c: declare ptynum
+
+ * Makefile.in: a number of changes, including use of the AR and
+ ARFLAGS variables, the appropriate variables for X11 (as passed
+ down from the top level Makefile), clean up some doc lines
+
+Mon Mar 1 15:05:40 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * configure.in, defs.h.in: Fixed problem for systems that think
+ getpty() should be _getpty().
+
+Thu Feb 25 15:34:34 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * exp_tty.h: Defines portable tty macros.
+ * pty_termios.c: New file, slightly based on pty_usg.c. Uses
+ portable macros and also supports termio.
+ * pty_sgttyb.c: Was pty_bsd.c.
+ * configure.in, Makefile.in, configure: autoconf support for
+ expect.
+
+Sun Feb 21 17:42:28 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * exp_tty.h: Removed and renamed the macros to use configure's.
+
+Wed Feb 17 18:56:36 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * expect.c, Makefile.in: Changed SIG_FN_RETURN to RETSIGTYPE
+ since that's what autoconf kicks out.
+
+Thu Dec 24 15:07:32 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: added dummy dvi target
+
+Wed Dec 16 11:26:16 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * inter_select.c (init_interact): if SCO is defined, use sysconf
+ to get maxfds, rather than getdtablesize.
+ * configure.in (*-*-sco*): Use mh-sco.
+ * mh-sco: New file; like mh-sysv, but pass -DSCO in HDEFS.
+
+Tue Nov 17 14:28:20 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/mh-{hpux,aix,irix4,sysv*}: updated with appropriate
+ values for the host machine (HDEFS, RANLIB, etc)
+
+ * configure.in: use that
+
+ * Makefile.in: use $(HDEFS) in compiling C files
+
+Sun Nov 15 21:46:16 1992 Fred Fish (fnf@cygnus.com)
+
+ * Update to base 3.24.0 release, merging back in changes made
+ by cygnus to 3.22.12 release.
+
+Sat Nov 14 20:16:26 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (CFLAGS): Rework use of CFLAGS to fit in better with
+ cygnus configuration standard.
+ * config/mh-svr4: Removed.
+ * config/mh-sysv4: New file, renamed from mh-svr4.
+ * configure.in (*-sysv4): New configuration.
+ * configure.in (*-sun-solaris2, *-sysv4): Use mh-sysv4.
+ * expect.c (sigwinch_handler): Fix #if without any condition.
+ * command.c, expect.c, global.h, lib_exp.c, main.c, term.h:
+ Test for SYSV4 as well as SYSV3.
+ * inter_select.c (sys/sysconfig.h): Include when SYSV4 defined.
+ * inter_select.c (init_interact): Add sysconf call for SYSV4.
+ * pty_svr4.c (ptsname): Declare for SYSV4.
+
+Thu Oct 22 17:35:07 1992 Rob Savoye (rob@cygnus.com)
+
+ * command.c: Added a "send_log" command. It only writes to a log
+ file if one was opened by the "log_file" command.
+
+ * main.c: Added setbuf commands for stdin, stdout, stderr to turn
+ off buffering.
+
diff --git a/expect/Dbg.c b/expect/Dbg.c
new file mode 100644
index 00000000000..bbc0995f49c
--- /dev/null
+++ b/expect/Dbg.c
@@ -0,0 +1,1291 @@
+/* Dbg.c - Tcl Debugger - See cmdHelp() for commands
+
+Written by: Don Libes, NIST, 3/23/93
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include <stdio.h>
+
+#include "Dbg_cf.h"
+#if 0
+/* tclInt.h drags in stdlib. By claiming no-stdlib, force it to drag in */
+/* Tcl's compat version. This avoids having to test for its presence */
+/* which is too tricky - configure can't generate two cf files, so when */
+/* Expect (or any app) uses the debugger, there's no way to get the info */
+/* about whether stdlib exists or not, except pointing the debugger at */
+/* an app-dependent .h file and I don't want to do that. */
+#define NO_STDLIB_H
+#endif
+
+
+#include "tclInt.h"
+/*#include <varargs.h> tclInt.h drags in varargs.h. Since Pyramid */
+/* objects to including varargs.h twice, just */
+/* omit this one. */
+/*#include "string.h" tclInt.h drags this in, too! */
+#include "Dbg.h"
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+static int simple_interactor();
+static int zero();
+
+/* most of the static variables in this file may be */
+/* moved into Tcl_Interp */
+
+static Dbg_InterProc *interactor = simple_interactor;
+static ClientData interdata = 0;
+static Dbg_IgnoreFuncsProc *ignoreproc = zero;
+static Dbg_OutputProc *printproc = 0;
+static ClientData printdata = 0;
+
+static void print _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp));
+
+static int debugger_active = FALSE;
+
+/* this is not externally documented anywhere as of yet */
+char *Dbg_VarName = "dbg";
+
+#define DEFAULT_COMPRESS 0
+static int compress = DEFAULT_COMPRESS;
+#define DEFAULT_WIDTH 75 /* leave a little space for printing */
+ /* stack level */
+static int buf_width = DEFAULT_WIDTH;
+
+static int main_argc = 1;
+static char *default_argv = "application";
+static char **main_argv = &default_argv;
+
+static Tcl_Trace debug_handle;
+static int step_count = 1; /* count next/step */
+
+#define FRAMENAMELEN 10 /* enough to hold strings like "#4" */
+static char viewFrameName[FRAMENAMELEN];/* destination frame name for up/down */
+
+static CallFrame *goalFramePtr; /* destination for next/return */
+static int goalNumLevel; /* destination for Next */
+
+static enum debug_cmd {
+ none, step, next, ret, cont, up, down, where, Next
+} debug_cmd;
+
+/* info about last action to use as a default */
+static enum debug_cmd last_action_cmd = next;
+static int last_step_count = 1;
+
+/* this acts as a strobe (while testing breakpoints). It is set to true */
+/* every time a new debugger command is issued that is an action */
+static debug_new_action;
+
+#define NO_LINE -1 /* if break point is not set by line number */
+
+struct breakpoint {
+ int id;
+ char *file; /* file where breakpoint is */
+ int line; /* line where breakpoint is */
+ char *pat; /* pattern defining where breakpoint can be */
+ regexp *re; /* regular expression to trigger breakpoint */
+ char *expr; /* expr to trigger breakpoint */
+ char *cmd; /* cmd to eval at breakpoint */
+ struct breakpoint *next, *previous;
+};
+
+static struct breakpoint *break_base = 0;
+static int breakpoint_max_id = 0;
+
+static struct breakpoint *
+breakpoint_new()
+{
+ struct breakpoint *b = (struct breakpoint *)ckalloc(sizeof(struct breakpoint));
+ if (break_base) break_base->previous = b;
+ b->next = break_base;
+ b->previous = 0;
+ b->id = breakpoint_max_id++;
+ b->file = 0;
+ b->line = NO_LINE;
+ b->pat = 0;
+ b->re = 0;
+ b->expr = 0;
+ b->cmd = 0;
+ break_base = b;
+ return(b);
+}
+
+static
+void
+breakpoint_print(interp,b)
+Tcl_Interp *interp;
+struct breakpoint *b;
+{
+ print(interp,"breakpoint %d: ",b->id);
+
+ if (b->re) {
+ print(interp,"-re \"%s\" ",b->pat);
+ } else if (b->pat) {
+ print(interp,"-glob \"%s\" ",b->pat);
+ } else if (b->line != NO_LINE) {
+ if (b->file) {
+ print(interp,"%s:",b->file);
+ }
+ print(interp,"%d ",b->line);
+ }
+
+ if (b->expr)
+ print(interp,"if {%s} ",b->expr);
+
+ if (b->cmd)
+ print(interp,"then {%s}",b->cmd);
+
+ print(interp,"\n");
+}
+
+static void
+save_re_matches(interp,re)
+Tcl_Interp *interp;
+regexp *re;
+{
+ int i;
+ char name[20];
+ char match_char;/* place to hold char temporarily */
+ /* uprooted by a NULL */
+
+ for (i=0;i<NSUBEXP;i++) {
+ if (re->startp[i] == 0) break;
+
+ sprintf(name,"%d",i);
+ /* temporarily null-terminate in middle */
+ match_char = *re->endp[i];
+ *re->endp[i] = 0;
+ Tcl_SetVar2(interp,Dbg_VarName,name,re->startp[i],0);
+
+ /* undo temporary null-terminator */
+ *re->endp[i] = match_char;
+ }
+}
+
+/* return 1 to break, 0 to continue */
+static int
+breakpoint_test(interp,cmd,bp)
+Tcl_Interp *interp;
+char *cmd; /* command about to be executed */
+struct breakpoint *bp; /* breakpoint to test */
+{
+ if (bp->re) {
+ if (0 == TclRegExec(bp->re,cmd,cmd)) return 0;
+ save_re_matches(interp,bp->re);
+ } else if (bp->pat) {
+ if (0 == Tcl_StringMatch(cmd,bp->pat)) return 0;
+ } else if (bp->line != NO_LINE) {
+ /* not yet implemented - awaiting support from Tcl */
+ return 0;
+ }
+
+ if (bp->expr) {
+ int value;
+
+ /* ignore errors, since they are likely due to */
+ /* simply being out of scope a lot */
+ if (TCL_OK != Tcl_ExprBoolean(interp,bp->expr,&value)
+ || (value == 0)) return 0;
+ }
+
+ if (bp->cmd) {
+ Tcl_Eval(interp,bp->cmd);
+ } else {
+ breakpoint_print(interp,bp);
+ }
+
+ return 1;
+}
+
+static char *already_at_top_level = "already at top level";
+
+/* similar to TclGetFrame but takes two frame ptrs and a direction.
+If direction is up, search up stack from curFrame
+If direction is down, simulate searching down stack by
+ seaching up stack from origFrame
+*/
+static
+int
+TclGetFrame2(interp, origFramePtr, string, framePtrPtr, dir)
+ Tcl_Interp *interp;
+ CallFrame *origFramePtr; /* frame that is true top-of-stack */
+ char *string; /* String describing frame. */
+ CallFrame **framePtrPtr; /* Store pointer to frame here (or NULL
+ * if global frame indicated). */
+ enum debug_cmd dir; /* look up or down the stack */
+{
+ Interp *iPtr = (Interp *) interp;
+ int level, result;
+ CallFrame *framePtr; /* frame currently being searched */
+
+ CallFrame *curFramePtr = iPtr->varFramePtr;
+
+ /*
+ * Parse string to figure out which level number to go to.
+ */
+
+ result = 1;
+ if (*string == '#') {
+ if (Tcl_GetInt(interp, string+1, &level) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (level < 0) {
+ levelError:
+ Tcl_AppendResult(interp, "bad level \"", string, "\"",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ framePtr = origFramePtr; /* start search here */
+
+ } else if (isdigit(*string)) {
+ if (Tcl_GetInt(interp, string, &level) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (dir == up) {
+ if (curFramePtr == 0) {
+ Tcl_SetResult(interp,already_at_top_level,TCL_STATIC);
+ return TCL_ERROR;
+ }
+ level = curFramePtr->level - level;
+ framePtr = curFramePtr; /* start search here */
+ } else {
+ if (curFramePtr != 0) {
+ level = curFramePtr->level + level;
+ }
+ framePtr = origFramePtr; /* start search here */
+ }
+ } else {
+ level = curFramePtr->level - 1;
+ result = 0;
+ }
+
+ /*
+ * Figure out which frame to use.
+ */
+
+ if (level == 0) {
+ framePtr = NULL;
+ } else {
+ for (;framePtr != NULL; framePtr = framePtr->callerVarPtr) {
+ if (framePtr->level == level) {
+ break;
+ }
+ }
+ if (framePtr == NULL) {
+ goto levelError;
+ }
+ }
+ *framePtrPtr = framePtr;
+ return result;
+}
+
+
+static char *printify(s)
+char *s;
+{
+ static int destlen = 0;
+ char *d; /* ptr into dest */
+ unsigned int need;
+ static char buf_basic[DEFAULT_WIDTH+1];
+ static char *dest = buf_basic;
+
+ if (s == 0) return("<null>");
+
+ /* worst case is every character takes 4 to printify */
+ need = strlen(s)*4;
+ if (need > destlen) {
+ if (dest && (dest != buf_basic)) ckfree(dest);
+ dest = (char *)ckalloc(need+1);
+ destlen = need;
+ }
+
+ for (d = dest;*s;s++) {
+ /* since we check at worst by every 4 bytes, play */
+ /* conservative and subtract 4 from the limit */
+ if (d-dest > destlen-4) break;
+
+ if (*s == '\b') {
+ strcpy(d,"\\b"); d += 2;
+ } else if (*s == '\f') {
+ strcpy(d,"\\f"); d += 2;
+ } else if (*s == '\v') {
+ strcpy(d,"\\v"); d += 2;
+ } else if (*s == '\r') {
+ strcpy(d,"\\r"); d += 2;
+ } else if (*s == '\n') {
+ strcpy(d,"\\n"); d += 2;
+ } else if (*s == '\t') {
+ strcpy(d,"\\t"); d += 2;
+ } else if ((unsigned)*s < 0x20) { /* unsigned strips parity */
+ sprintf(d,"\\%03o",*s); d += 4;
+ } else if (*s == 0177) {
+ strcpy(d,"\\177"); d += 4;
+ } else {
+ *d = *s; d += 1;
+ }
+ }
+ *d = '\0';
+ return(dest);
+}
+
+static
+char *
+print_argv(interp,argc,argv)
+Tcl_Interp *interp;
+int argc;
+char *argv[];
+{
+ static int buf_width_max = DEFAULT_WIDTH;
+ static char buf_basic[DEFAULT_WIDTH+1]; /* basic buffer */
+ static char *buf = buf_basic;
+ int space; /* space remaining in buf */
+ int len;
+ char *bufp;
+ int proc; /* if current command is "proc" */
+ int arg_index;
+
+ if (buf_width > buf_width_max) {
+ if (buf && (buf != buf_basic)) ckfree(buf);
+ buf = (char *)ckalloc(buf_width + 1);
+ buf_width_max = buf_width;
+ }
+
+ proc = (0 == strcmp("proc",argv[0]));
+ sprintf(buf,"%.*s",buf_width,argv[0]);
+ len = strlen(buf);
+ space = buf_width - len;
+ bufp = buf + len;
+ argc--; argv++;
+ arg_index = 1;
+
+ while (argc && (space > 0)) {
+ char *elementPtr;
+ char *nextPtr;
+ int wrap;
+
+ /* braces/quotes have been stripped off arguments */
+ /* so put them back. We wrap everything except lists */
+ /* with one argument. One exception is to always wrap */
+ /* proc's 2nd arg (the arg list), since people are */
+ /* used to always seeing it this way. */
+
+ if (proc && (arg_index > 1)) wrap = TRUE;
+ else {
+ (void) TclFindElement(interp,*argv,
+#if TCL_MAJOR_VERSION >= 8
+ -1,
+#endif
+ &elementPtr,&nextPtr,(int *)0,(int *)0);
+ if (*elementPtr == '\0') wrap = TRUE;
+ else if (*nextPtr == '\0') wrap = FALSE;
+ else wrap = TRUE;
+ }
+
+ /* wrap lists (or null) in braces */
+ if (wrap) {
+ sprintf(bufp," {%.*s}",space-3,*argv);
+ } else {
+ sprintf(bufp," %.*s",space-1,*argv);
+ }
+ len = strlen(buf);
+ space = buf_width - len;
+ bufp = buf + len;
+ argc--; argv++;
+ arg_index++;
+ }
+
+ if (compress) {
+ /* this copies from our static buf to printify's static buf */
+ /* and back to our static buf */
+ strncpy(buf,printify(buf),buf_width);
+ }
+
+ /* usually but not always right, but assume truncation if buffer is */
+ /* full. this avoids tiny but odd-looking problem of appending "}" */
+ /* to truncated lists during {}-wrapping earlier */
+ if (strlen(buf) == buf_width) {
+ buf[buf_width-1] = buf[buf_width-2] = buf[buf_width-3] = '.';
+ }
+
+ return(buf);
+}
+
+#if TCL_MAJOR_VERSION >= 8
+static
+char *
+print_objv(interp,objc,objv)
+Tcl_Interp *interp;
+int objc;
+Tcl_Obj *objv[];
+{
+ char **argv;
+ int argc;
+ int len;
+ argv = (char **)ckalloc(objc+1 * sizeof(char *));
+ for (argc=0 ; argc<objc ; argc++) {
+ argv[argc] = Tcl_GetStringFromObj(objv[argc],&len);
+ }
+ argv[argc] = NULL;
+ print_argv(interp,argc,argv);
+}
+#endif
+
+static
+void
+PrintStackBelow(interp,curf,viewf)
+Tcl_Interp *interp;
+CallFrame *curf; /* current FramePtr */
+CallFrame *viewf; /* view FramePtr */
+{
+ char ptr; /* graphically indicate where we are in the stack */
+
+ /* indicate where we are in the stack */
+ ptr = ((curf == viewf)?'*':' ');
+
+ if (curf == 0) {
+ print(interp,"%c0: %s\n",
+ ptr,print_argv(interp,main_argc,main_argv));
+ } else {
+ PrintStackBelow(interp,curf->callerVarPtr,viewf);
+ print(interp,"%c%d: %s\n",ptr,curf->level,
+#if TCL_MAJOR_VERSION >= 8
+ print_objv(interp,curf->objc,curf->objv));
+#else
+ print_argv(interp,curf->argc,curf->argv));
+#endif
+ }
+}
+
+static
+void
+PrintStack(interp,curf,viewf,argc,argv,level)
+Tcl_Interp *interp;
+CallFrame *curf; /* current FramePtr */
+CallFrame *viewf; /* view FramePtr */
+int argc;
+char *argv[];
+char *level;
+{
+ PrintStackBelow(interp,curf,viewf);
+
+ print(interp," %s: %s\n",level,print_argv(interp,argc,argv));
+}
+
+/* return 0 if goal matches current frame or goal can't be found */
+/* anywere in frame stack */
+/* else return 1 */
+/* This catches things like a proc called from a Tcl_Eval which in */
+/* turn was not called from a proc but some builtin such as source */
+/* or Tcl_Eval. These builtin calls to Tcl_Eval lose any knowledge */
+/* the FramePtr from the proc, so we have to search the entire */
+/* stack frame to see if it's still there. */
+static int
+GoalFrame(goal,iptr)
+CallFrame *goal;
+Interp *iptr;
+{
+ CallFrame *cf = iptr->varFramePtr;
+
+ /* if at current level, return success immediately */
+ if (goal == cf) return 0;
+
+ while (cf) {
+ cf = cf->callerVarPtr;
+ if (goal == cf) {
+ /* found, but since it's above us, fail */
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* debugger's trace handler */
+/*ARGSUSED*/
+static void
+debugger_trap(clientData,interp,level,command,cmdProc,cmdClientData,argc,argv)
+ClientData clientData; /* not used */
+Tcl_Interp *interp;
+int level; /* positive number if called by Tcl, -1 if */
+ /* called by Dbg_On in which case we don't */
+ /* know the level */
+char *command;
+int (*cmdProc)(); /* not used */
+ClientData cmdClientData;
+int argc;
+char *argv[];
+{
+ char level_text[6]; /* textual representation of level */
+
+ int break_status;
+ Interp *iPtr = (Interp *)interp;
+
+ CallFrame *trueFramePtr; /* where the pc is */
+ CallFrame *viewFramePtr; /* where up/down are */
+
+ int print_command_first_time = TRUE;
+ static int debug_suspended = FALSE;
+
+ struct breakpoint *b;
+
+ /* skip commands that are invoked interactively */
+ if (debug_suspended) return;
+
+ /* skip debugger commands */
+ if (argv[0][1] == '\0') {
+ switch (argv[0][0]) {
+ case 'n':
+ case 's':
+ case 'c':
+ case 'r':
+ case 'w':
+ case 'b':
+ case 'u':
+ case 'd': return;
+ }
+ }
+
+ if ((*ignoreproc)(interp,argv[0])) return;
+
+ /* if level is unknown, use "?" */
+ sprintf(level_text,(level == -1)?"?":"%d",level);
+
+ /* save so we can restore later */
+ trueFramePtr = iPtr->varFramePtr;
+
+ /* do not allow breaking while testing breakpoints */
+ debug_suspended = TRUE;
+
+ /* test all breakpoints to see if we should break */
+ /* if any successful breakpoints, start interactor */
+ debug_new_action = FALSE; /* reset strobe */
+ break_status = FALSE; /* no successful breakpoints yet */
+ for (b = break_base;b;b=b->next) {
+ break_status |= breakpoint_test(interp,command,b);
+ }
+ if (break_status) {
+ if (!debug_new_action) goto start_interact;
+
+ /* if s or n triggered by breakpoint, make "s 1" */
+ /* (and so on) refer to next command, not this one */
+/* step_count++;*/
+ goto end_interact;
+ }
+
+ switch (debug_cmd) {
+ case cont:
+ goto finish;
+ case step:
+ step_count--;
+ if (step_count > 0) goto finish;
+ goto start_interact;
+ case next:
+ /* check if we are back at the same level where the next */
+ /* command was issued. Also test */
+ /* against all FramePtrs and if no match, assume that */
+ /* we've missed a return, and so we should break */
+/* if (goalFramePtr != iPtr->varFramePtr) goto finish;*/
+ if (GoalFrame(goalFramePtr,iPtr)) goto finish;
+ step_count--;
+ if (step_count > 0) goto finish;
+ goto start_interact;
+ case Next:
+ /* check if we are back at the same level where the next */
+ /* command was issued. */
+ if (goalNumLevel < iPtr->numLevels) goto finish;
+ step_count--;
+ if (step_count > 0) goto finish;
+ goto start_interact;
+ case ret:
+ /* same comment as in "case next" */
+ if (goalFramePtr != iPtr->varFramePtr) goto finish;
+ goto start_interact;
+ }
+
+start_interact:
+ if (print_command_first_time) {
+ print(interp,"%s: %s\n",
+ level_text,print_argv(interp,1,&command));
+ print_command_first_time = FALSE;
+ }
+ /* since user is typing a command, don't interrupt it immediately */
+ debug_cmd = cont;
+ debug_suspended = TRUE;
+
+ /* interactor won't return until user gives a debugger cmd */
+ (*interactor)(interp,interdata);
+end_interact:
+
+ /* save this so it can be restored after "w" command */
+ viewFramePtr = iPtr->varFramePtr;
+
+ if (debug_cmd == up || debug_cmd == down) {
+ /* calculate new frame */
+ if (-1 == TclGetFrame2(interp,trueFramePtr,viewFrameName,
+ &iPtr->varFramePtr,debug_cmd)) {
+ print(interp,"%s\n",interp->result);
+ Tcl_ResetResult(interp);
+ }
+ goto start_interact;
+ }
+
+ /* reset view back to normal */
+ iPtr->varFramePtr = trueFramePtr;
+
+#if 0
+ /* allow trapping */
+ debug_suspended = FALSE;
+#endif
+
+ switch (debug_cmd) {
+ case cont:
+ case step:
+ goto finish;
+ case next:
+ goalFramePtr = iPtr->varFramePtr;
+ goto finish;
+ case Next:
+ goalNumLevel = iPtr->numLevels;
+ goto finish;
+ case ret:
+ goalFramePtr = iPtr->varFramePtr;
+ if (goalFramePtr == 0) {
+ print(interp,"nowhere to return to\n");
+ break;
+ }
+ goalFramePtr = goalFramePtr->callerVarPtr;
+ goto finish;
+ case where:
+ PrintStack(interp,iPtr->varFramePtr,viewFramePtr,argc,argv,level_text);
+ break;
+ }
+
+ /* restore view and restart interactor */
+ iPtr->varFramePtr = viewFramePtr;
+ goto start_interact;
+
+ finish:
+ debug_suspended = FALSE;
+}
+
+/*ARGSUSED*/
+static
+int
+cmdNext(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ debug_new_action = TRUE;
+ debug_cmd = *(enum debug_cmd *)clientData;
+ last_action_cmd = debug_cmd;
+
+ step_count = (argc == 1)?1:atoi(argv[1]);
+ last_step_count = step_count;
+ return(TCL_RETURN);
+}
+
+/*ARGSUSED*/
+static
+int
+cmdDir(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ debug_cmd = *(enum debug_cmd *)clientData;
+
+ if (argc == 1) argv[1] = "1";
+ strncpy(viewFrameName,argv[1],FRAMENAMELEN);
+
+ return TCL_RETURN;
+}
+
+/*ARGSUSED*/
+static
+int
+cmdSimple(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ debug_new_action = TRUE;
+ debug_cmd = *(enum debug_cmd *)clientData;
+ last_action_cmd = debug_cmd;
+
+ return TCL_RETURN;
+}
+
+static
+void
+breakpoint_destroy(b)
+struct breakpoint *b;
+{
+ if (b->file) ckfree(b->file);
+ if (b->pat) ckfree(b->pat);
+ if (b->re) ckfree((char *)b->re);
+ if (b->cmd) ckfree(b->cmd);
+
+ /* unlink from chain */
+ if ((b->previous == 0) && (b->next == 0)) {
+ break_base = 0;
+ } else if (b->previous == 0) {
+ break_base = b->next;
+ b->next->previous = 0;
+ } else if (b->next == 0) {
+ b->previous->next = 0;
+ } else {
+ b->previous->next = b->next;
+ b->next->previous = b->previous;
+ }
+
+ ckfree((char *)b);
+}
+
+static void
+savestr(straddr,str)
+char **straddr;
+char *str;
+{
+ *straddr = ckalloc(strlen(str)+1);
+ strcpy(*straddr,str);
+}
+
+/* return 1 if a string is substring of a flag */
+static int
+flageq(flag,string,minlen)
+char *flag;
+char *string;
+int minlen; /* at least this many chars must match */
+{
+ for (;*flag;flag++,string++,minlen--) {
+ if (*string == '\0') break;
+ if (*string != *flag) return 0;
+ }
+ if (*string == '\0' && minlen <= 0) return 1;
+ return 0;
+}
+
+/*ARGSUSED*/
+static
+int
+cmdWhere(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ if (argc == 1) {
+ debug_cmd = where;
+ return TCL_RETURN;
+ }
+
+ argc--; argv++;
+
+ while (argc) {
+ if (flageq("-width",*argv,2)) {
+ argc--; argv++;
+ if (*argv) {
+ buf_width = atoi(*argv);
+ argc--; argv++;
+ } else print(interp,"%d\n",buf_width);
+ } else if (flageq("-compress",*argv,2)) {
+ argc--; argv++;
+ if (*argv) {
+ compress = atoi(*argv);
+ argc--; argv++;
+ } else print(interp,"%d\n",compress);
+ } else {
+ print(interp,"usage: w [-width #] [-compress 0|1]\n");
+ return TCL_ERROR;
+ }
+ }
+ return TCL_OK;
+}
+
+#define breakpoint_fail(msg) {error_msg = msg; goto break_fail;}
+
+/*ARGSUSED*/
+static
+int
+cmdBreak(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ struct breakpoint *b;
+ char *error_msg;
+
+ argc--; argv++;
+
+ if (argc < 1) {
+ for (b = break_base;b;b=b->next) breakpoint_print(interp,b);
+ return(TCL_OK);
+ }
+
+ if (argv[0][0] == '-') {
+ if (argv[0][1] == '\0') {
+ while (break_base) {
+ breakpoint_destroy(break_base);
+ }
+ breakpoint_max_id = 0;
+ return(TCL_OK);
+ } else if (isdigit(argv[0][1])) {
+ int id = atoi(argv[0]+1);
+
+ for (b = break_base;b;b=b->next) {
+ if (b->id == id) {
+ breakpoint_destroy(b);
+ if (!break_base) breakpoint_max_id = 0;
+ return(TCL_OK);
+ }
+ }
+ Tcl_SetResult(interp,"no such breakpoint",TCL_STATIC);
+ return(TCL_ERROR);
+ }
+ }
+
+ b = breakpoint_new();
+
+ if (flageq("-regexp",argv[0],2)) {
+ argc--; argv++;
+ if ((argc > 0) && (b->re = TclRegComp(argv[0]))) {
+ savestr(&b->pat,argv[0]);
+ argc--; argv++;
+ } else {
+ breakpoint_fail("bad regular expression")
+ }
+ } else if (flageq("-glob",argv[0],2)) {
+ argc--; argv++;
+ if (argc > 0) {
+ savestr(&b->pat,argv[0]);
+ argc--; argv++;
+ } else {
+ breakpoint_fail("no pattern?");
+ }
+ } else if ((!(flageq("if",*argv,1)) && (!(flageq("then",*argv,1))))) {
+ /* look for [file:]line */
+ char *colon;
+ char *linep; /* pointer to beginning of line number */
+
+ colon = strchr(argv[0],':');
+ if (colon) {
+ *colon = '\0';
+ savestr(&b->file,argv[0]);
+ *colon = ':';
+ linep = colon + 1;
+ } else {
+ linep = argv[0];
+ /* get file from current scope */
+ /* savestr(&b->file, ?); */
+ }
+
+ if (TCL_OK == Tcl_GetInt(interp,linep,&b->line)) {
+ argc--; argv++;
+ print(interp,"setting breakpoints by line number is currently unimplemented - use patterns or expressions\n");
+ } else {
+ /* not an int? - unwind & assume it is an expression */
+
+ if (b->file) ckfree(b->file);
+ }
+ }
+
+ if (argc > 0) {
+ int do_if = FALSE;
+
+ if (flageq("if",argv[0],1)) {
+ argc--; argv++;
+ do_if = TRUE;
+ } else if (!flageq("then",argv[0],1)) {
+ do_if = TRUE;
+ }
+
+ if (do_if) {
+ if (argc < 1) {
+ breakpoint_fail("if what");
+ }
+
+ savestr(&b->expr,argv[0]);
+ argc--; argv++;
+ }
+ }
+
+ if (argc > 0) {
+ if (flageq("then",argv[0],1)) {
+ argc--; argv++;
+ }
+
+ if (argc < 1) {
+ breakpoint_fail("then what?");
+ }
+
+ savestr(&b->cmd,argv[0]);
+ }
+
+ sprintf(interp->result,"%d",b->id);
+ return(TCL_OK);
+
+ break_fail:
+ breakpoint_destroy(b);
+ Tcl_SetResult(interp,error_msg,TCL_STATIC);
+ return(TCL_ERROR);
+}
+
+static char *help[] = {
+"s [#] step into procedure",
+"n [#] step over procedure",
+"N [#] step over procedures, commands, and arguments",
+"c continue",
+"r continue until return to caller",
+"u [#] move scope up level",
+"d [#] move scope down level",
+" go to absolute frame if # is prefaced by \"#\"",
+"w show stack (\"where\")",
+"w -w [#] show/set width",
+"w -c [0|1] show/set compress",
+"b show breakpoints",
+"b [-r regexp-pattern] [if expr] [then command]",
+"b [-g glob-pattern] [if expr] [then command]",
+"b [[file:]#] [if expr] [then command]",
+" if pattern given, break if command resembles pattern",
+" if # given, break on line #",
+" if expr given, break if expr true",
+" if command given, execute command at breakpoint",
+"b -# delete breakpoint",
+"b - delete all breakpoints",
+0};
+
+/*ARGSUSED*/
+static
+int
+cmdHelp(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ char **hp;
+
+ for (hp=help;*hp;hp++) {
+ print(interp,"%s\n",*hp);
+ }
+
+ return(TCL_OK);
+}
+
+/* occasionally, we print things larger buf_max but not by much */
+/* see print statements in PrintStack routines for examples */
+#define PAD 80
+
+/*VARARGS*/
+static void
+print TCL_VARARGS_DEF(Tcl_Interp *,arg1)
+{
+ Tcl_Interp *interp;
+ char *fmt;
+ va_list args;
+
+ interp = TCL_VARARGS_START(Tcl_Interp *,arg1,args);
+ fmt = va_arg(args,char *);
+ if (!printproc) vprintf(fmt,args);
+ else {
+ static int buf_width_max = DEFAULT_WIDTH+PAD;
+ static char buf_basic[DEFAULT_WIDTH+PAD+1];
+ static char *buf = buf_basic;
+
+ if (buf_width+PAD > buf_width_max) {
+ if (buf && (buf != buf_basic)) ckfree(buf);
+ buf = (char *)ckalloc(buf_width+PAD+1);
+ buf_width_max = buf_width+PAD;
+ }
+
+ vsprintf(buf,fmt,args);
+ (*printproc)(interp,buf,printdata);
+ }
+ va_end(args);
+}
+
+/*ARGSUSED*/
+Dbg_InterStruct
+Dbg_Interactor(interp,inter_proc,data)
+Tcl_Interp *interp;
+Dbg_InterProc *inter_proc;
+ClientData data;
+{
+ Dbg_InterStruct tmp;
+
+ tmp.func = interactor;
+ tmp.data = interdata;
+ interactor = (inter_proc?inter_proc:simple_interactor);
+ interdata = data;
+ return tmp;
+}
+
+/*ARGSUSED*/
+Dbg_IgnoreFuncsProc *
+Dbg_IgnoreFuncs(interp,proc)
+Tcl_Interp *interp;
+Dbg_IgnoreFuncsProc *proc;
+{
+ Dbg_IgnoreFuncsProc *tmp = ignoreproc;
+ ignoreproc = (proc?proc:zero);
+ return tmp;
+}
+
+/*ARGSUSED*/
+Dbg_OutputStruct
+Dbg_Output(interp,proc,data)
+Tcl_Interp *interp;
+Dbg_OutputProc *proc;
+ClientData data;
+{
+ Dbg_OutputStruct tmp;
+
+ tmp.func = printproc;
+ tmp.data = printdata;
+ printproc = proc;
+ printdata = data;
+ return tmp;
+}
+
+/*ARGSUSED*/
+int
+Dbg_Active(interp)
+Tcl_Interp *interp;
+{
+ return debugger_active;
+}
+
+char **
+Dbg_ArgcArgv(argc,argv,copy)
+int argc;
+char *argv[];
+int copy;
+{
+ char **alloc;
+
+ main_argc = argc;
+
+ if (!copy) {
+ main_argv = argv;
+ alloc = 0;
+ } else {
+ main_argv = alloc = (char **)ckalloc((argc+1)*sizeof(char *));
+ while (argc-- >= 0) {
+ *main_argv++ = *argv++;
+ }
+ main_argv = alloc;
+ }
+ return alloc;
+}
+
+static struct cmd_list {
+ char *cmdname;
+ Tcl_CmdProc *cmdproc;
+ enum debug_cmd cmdtype;
+} cmd_list[] = {
+ {"n", cmdNext, next},
+ {"s", cmdNext, step},
+ {"N", cmdNext, Next},
+ {"c", cmdSimple, cont},
+ {"r", cmdSimple, ret},
+ {"w", cmdWhere, none},
+ {"b", cmdBreak, none},
+ {"u", cmdDir, up},
+ {"d", cmdDir, down},
+ {"h", cmdHelp, none},
+ {0}
+};
+
+/* this may seem excessive, but this avoids the explicit test for non-zero */
+/* in the caller, and chances are that that test will always be pointless */
+/*ARGSUSED*/
+static int zero(interp,string)
+Tcl_Interp *interp;
+char *string;
+{
+ return 0;
+}
+
+static int
+simple_interactor(interp)
+Tcl_Interp *interp;
+{
+ int rc;
+ char *ccmd; /* pointer to complete command */
+ char line[BUFSIZ+1]; /* space for partial command */
+ int newcmd = TRUE;
+ Interp *iPtr = (Interp *)interp;
+
+ Tcl_DString dstring;
+ Tcl_DStringInit(&dstring);
+
+ newcmd = TRUE;
+ while (TRUE) {
+ struct cmd_list *c;
+
+ if (newcmd) {
+#if TCL_MAJOR_VERSION < 8
+ print(interp,"dbg%d.%d> ",iPtr->numLevels,iPtr->curEventNum+1);
+#else
+ /* unncessarily tricky coding - if nextid
+ isn't defined, maintain our own static
+ version */
+
+ static int nextid = 0;
+ char *nextidstr = Tcl_GetVar2(interp,"tcl::history","nextid",0);
+ if (nextidstr) {
+ sscanf(nextidstr,"%d",&nextid);
+ }
+ print(interp,"dbg%d.%d> ",iPtr->numLevels,nextid++);
+#endif
+ } else {
+ print(interp,"dbg+> ");
+ }
+ fflush(stdout);
+
+ if (0 >= (rc = read(0,line,BUFSIZ))) {
+ if (!newcmd) line[0] = 0;
+ else exit(0);
+ } else line[rc] = '\0';
+
+ ccmd = Tcl_DStringAppend(&dstring,line,rc);
+ if (!Tcl_CommandComplete(ccmd)) {
+ newcmd = FALSE;
+ continue; /* continue collecting command */
+ }
+ newcmd = TRUE;
+
+ /* if user pressed return with no cmd, use previous one */
+ if ((ccmd[0] == '\n' || ccmd[0] == '\r') && ccmd[1] == '\0') {
+
+ /* this loop is guaranteed to exit through break */
+ for (c = cmd_list;c->cmdname;c++) {
+ if (c->cmdtype == last_action_cmd) break;
+ }
+
+ /* recreate textual version of command */
+ Tcl_DStringAppend(&dstring,c->cmdname,-1);
+
+ if (c->cmdtype == step ||
+ c->cmdtype == next ||
+ c->cmdtype == Next) {
+ char num[10];
+
+ sprintf(num," %d",last_step_count);
+ Tcl_DStringAppend(&dstring,num,-1);
+ }
+ }
+
+#if TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION < 4
+ rc = Tcl_RecordAndEval(interp,ccmd,0);
+#else
+ rc = Tcl_RecordAndEval(interp,ccmd,TCL_NO_EVAL);
+ rc = Tcl_Eval(interp,ccmd);
+#endif
+ Tcl_DStringFree(&dstring);
+
+ switch (rc) {
+ case TCL_OK:
+ if (*interp->result != 0)
+ print(interp,"%s\n",interp->result);
+ continue;
+ case TCL_ERROR:
+ print(interp,"%s\n",Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY));
+ /* since user is typing by hand, we expect lots
+ of errors, and want to give another chance */
+ continue;
+ case TCL_BREAK:
+ case TCL_CONTINUE:
+#define finish(x) {rc = x; goto done;}
+ finish(rc);
+ case TCL_RETURN:
+ finish(TCL_OK);
+ default:
+ /* note that ccmd has trailing newline */
+ print(interp,"error %d: %s\n",rc,ccmd);
+ continue;
+ }
+ }
+ /* cannot fall thru here, must jump to label */
+ done:
+ Tcl_DStringFree(&dstring);
+
+ return(rc);
+}
+
+static char init_auto_path[] = "lappend auto_path $dbg_library";
+
+static void
+init_debugger(interp)
+Tcl_Interp *interp;
+{
+ struct cmd_list *c;
+
+ for (c = cmd_list;c->cmdname;c++) {
+ Tcl_CreateCommand(interp,c->cmdname,c->cmdproc,
+ (ClientData)&c->cmdtype,(Tcl_CmdDeleteProc *)0);
+ }
+
+ debug_handle = Tcl_CreateTrace(interp,
+ 10000,debugger_trap,(ClientData)0);
+
+ debugger_active = TRUE;
+ Tcl_SetVar2(interp,Dbg_VarName,"active","1",0);
+#ifdef DBG_SCRIPTDIR
+ Tcl_SetVar(interp,"dbg_library",DBG_SCRIPTDIR,0);
+#endif
+ Tcl_Eval(interp,init_auto_path);
+
+}
+
+/* allows any other part of the application to jump to the debugger */
+/*ARGSUSED*/
+void
+Dbg_On(interp,immediate)
+Tcl_Interp *interp;
+int immediate; /* if true, stop immediately */
+ /* should only be used in safe places */
+ /* i.e., when Tcl_Eval can be called */
+{
+ if (!debugger_active) init_debugger(interp);
+
+ debug_cmd = step;
+ step_count = 1;
+
+ if (immediate) {
+ static char *fake_cmd = "--interrupted-- (command_unknown)";
+
+ debugger_trap((ClientData)0,interp,-1,fake_cmd,(int (*)())0,
+ (ClientData)0,1,&fake_cmd);
+/* (*interactor)(interp);*/
+ }
+}
+
+void
+Dbg_Off(interp)
+Tcl_Interp *interp;
+{
+ struct cmd_list *c;
+
+ if (!debugger_active) return;
+
+ for (c = cmd_list;c->cmdname;c++) {
+ Tcl_DeleteCommand(interp,c->cmdname);
+ }
+
+ Tcl_DeleteTrace(interp,debug_handle);
+ debugger_active = FALSE;
+ Tcl_UnsetVar(interp,Dbg_VarName,TCL_GLOBAL_ONLY);
+}
diff --git a/expect/Dbg.h b/expect/Dbg.h
new file mode 100644
index 00000000000..48bb69adf9f
--- /dev/null
+++ b/expect/Dbg.h
@@ -0,0 +1,60 @@
+/* Dbg.h - Tcl Debugger include file
+
+Written by: Don Libes, NIST, 3/23/93
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+/* _DEBUG or _DBG is just too likely, use something more unique */
+#ifndef _NIST_DBG
+#define _NIST_DBG
+
+#include "tcl.h"
+
+typedef int (Dbg_InterProc) _ANSI_ARGS_((Tcl_Interp *interp, ClientData data));
+typedef int (Dbg_IgnoreFuncsProc) _ANSI_ARGS_((
+ Tcl_Interp *interp,
+ char *funcname));
+typedef void (Dbg_OutputProc) _ANSI_ARGS_((
+ Tcl_Interp *interp,
+ char *output,
+ ClientData data));
+
+typedef struct {
+ Dbg_InterProc *func;
+ ClientData data;
+} Dbg_InterStruct;
+
+typedef struct {
+ Dbg_OutputProc *func;
+ ClientData data;
+} Dbg_OutputStruct;
+
+EXTERN char *Dbg_VarName;
+EXTERN char *Dbg_DefaultCmdName;
+
+/* trivial interface, creates a "debug" command in your interp */
+EXTERN int Dbg_Init _ANSI_ARGS_((Tcl_Interp *));
+
+EXTERN void Dbg_On _ANSI_ARGS_((Tcl_Interp *interp,
+ int immediate));
+EXTERN void Dbg_Off _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN char **Dbg_ArgcArgv _ANSI_ARGS_((int argc,char *argv[],
+ int copy));
+EXTERN int Dbg_Active _ANSI_ARGS_((Tcl_Interp *interp));
+EXTERN Dbg_InterStruct Dbg_Interactor _ANSI_ARGS_((
+ Tcl_Interp *interp,
+ Dbg_InterProc *interactor,
+ ClientData data));
+EXTERN Dbg_IgnoreFuncsProc *Dbg_IgnoreFuncs _ANSI_ARGS_((
+ Tcl_Interp *interp,
+ Dbg_IgnoreFuncsProc *));
+EXTERN Dbg_OutputStruct Dbg_Output _ANSI_ARGS_((
+ Tcl_Interp *interp,
+ Dbg_OutputProc *,
+ ClientData data));
+
+#endif /* _NIST_DBG */
diff --git a/expect/DbgMkfl.in b/expect/DbgMkfl.in
new file mode 100644
index 00000000000..6bd6212e949
--- /dev/null
+++ b/expect/DbgMkfl.in
@@ -0,0 +1,232 @@
+#
+# Makefile for tcl debugger
+#
+
+VERSION = \"@DBG_VERSION_FULL@\"
+SHORT_VERSION = @DBG_VERSION@
+
+# Compatible with Tcl version 7.5
+# Compatible with Tk version 4.1
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+######################################################################
+# The following lines are things you are likely to want to change
+######################################################################
+
+# Tcl include files. (If you haven't installed Tcl yet, read the README file).
+# This must point to the directory that contains ALL of Tcl's include
+# files, not just the public ones.
+TCLHDIR = @TCLHDIRDASHI@
+
+# flags to pass to cc
+# You should be able to leave this just the way it is. However, here are some
+# note if you run into problems:
+#
+# Avoid -O (optimize) unless you are convinced your optimizer is flawless
+# (hint: not a chance). I have heard many reports of -O causing Expect to
+# misbehave.
+# I encourage you to use -g (debugging). While it is unlikely you will
+# encounter an internal error in Expect, should this happen, I may just need
+# the -g information and then you will need to recompile Expect. As an aside,
+# Expect is not a space or time pig, so this won't affect the performance of
+# your Expect scripts.
+# Note: On Linux systems which only have dynamic X libraries, the -g prevents
+# the linker from using them. So do not use -g on such systems.
+CFLAGS = @DBG_CFLAGS@ @DBG_SHLIB_CFLAGS@
+
+# which C compiler to use
+CC = @CC@
+
+# By default, `make install' will install the appropriate files in
+# /usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify
+# an installation prefix other than /usr/local here:
+prefix = @prefix@
+
+# You can specify a separate installation prefix for architecture-specific
+# files such as binaries and libraries.
+exec_prefix = @exec_prefix@
+
+# If you have ranlib but it should be avoided, change this from "ranlib" #
+# to something innocuous like "echo". Known systems with this problem:
+# older SCO boxes.
+UNSHARED_RANLIB = @UNSHARED_RANLIB@
+
+######################################################################
+# End of things you are likely to want to change
+######################################################################
+
+libdir = $(exec_prefix)/lib
+datadir = $(prefix)/lib
+
+mandir = @mandir@
+man1dir = $(mandir)/man1
+includedir = $(prefix)/include
+
+# Where to store utility scripts. This corresponds to the variable
+# "dbg_library".
+DBG_SCRIPTDIR = $(datadir)/dbg
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+AR = ar
+ARFLAGS = cr
+
+# TCLHDIR includes "-I"
+CPPFLAGS = -I. -I$(srcdir) $(TCLHDIR) \
+ -DDBG_VERSION=$(VERSION) \
+ -DDBG_SCRIPTDIR=\"$(DBG_SCRIPTDIR)\"
+
+CFLAGS_INT = $(MH_CFLAGS) $(CPPFLAGS) $(CFLAGS)
+
+.c.o:
+ $(CC) -c $(CFLAGS_INT) $(HDEFS) $<
+
+CFILES = Dbg.c Dbg_cmd.c
+OFILES = Dbg.o Dbg_cmd.o
+
+# libraries (both .a and shared)
+DBG_LIB_FILES = @DBG_LIB_FILES@
+# default Dbg library (shared if possible, otherwise static)
+DBG_LIB_FILE = @DBG_LIB_FILE@
+# Dbg object library (.a)
+DBG_UNSHARED_LIB_FILE = @DBG_UNSHARED_LIB_FILE@
+# Dbg object library (shared, if possible)
+DBG_SHARED_LIB_FILE = @DBG_SHARED_LIB_FILE@
+
+all: $(DBG_LIB_FILES)
+
+$(DBG_UNSHARED_LIB_FILE): $(OFILES)
+ -rm -f $(DBG_UNSHARED_LIB_FILE)
+ $(AR) $(ARFLAGS) $(DBG_UNSHARED_LIB_FILE) $(OFILES)
+ -$(UNSHARED_RANLIB) $(DBG_UNSHARED_LIB_FILE)
+
+$(DBG_SHARED_LIB_FILE): $(OFILES)
+ -rm -f $(DBG_SHARED_LIB_FILE)
+ @TCL_SHLIB_LD@ -o $(DBG_SHARED_LIB_FILE) $(OFILES)
+
+# Delete all the installed files that the `install' target creates
+# (but not the noninstalled files such as `make all' creates)
+uninstall:
+ -rm -f $(man1dir)/tcldbg.1 \
+ $(libdir)/$(DBG_SHARED_LIB_FILE) \
+ $(libdir)/$(DBG_UNSHARED_LIB_FILE) \
+ $(includedir)/Dbg.h \
+ $(DBG_SCRIPTDIR)/pkgIndex.tcl
+
+install: $(DBG_LIB_FILES)
+ ${srcdir}/mkinstalldirs $(man1dir) $(libdir) $(includedir) $(DBG_SCRIPTDIR)
+ $(INSTALL_DATA) $(srcdir)/tcldbg.man $(man1dir)/tcldbg.1
+ if [ -s $(DBG_UNSHARED_LIB_FILE) ] ; then \
+ $(INSTALL_DATA) $(DBG_UNSHARED_LIB_FILE) $(libdir)/$(DBG_UNSHARED_LIB_FILE) ; \
+ $(UNSHARED_RANLIB) $(libdir)/$(DBG_UNSHARED_LIB_FILE) ; \
+ fi
+ if [ -s $(DBG_SHARED_LIB_FILE) ] ; then \
+ $(INSTALL_DATA) $(DBG_SHARED_LIB_FILE) $(libdir)/$(DBG_SHARED_LIB_FILE) ; \
+ fi
+ $(INSTALL_DATA) $(srcdir)/Dbg.h $(includedir)
+# create utility-script directory
+ $(INSTALL_DATA) $(srcdir)/Dbg_lib.tcl $(DBG_SCRIPTDIR)
+ $(INSTALL_DATA) $(srcdir)/tclIndex $(DBG_SCRIPTDIR)
+
+
+###################################
+# Targets for Makefile and configure
+###################################
+
+Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) config.status
+ @echo "Rebuilding the Makefile..."
+ $(SHELL) config.status
+
+configure: $(srcdir)/configure.in $(srcdir)/Makefile.in $(srcdir)/aclocal.m4
+ autoconf configure.in > configure
+ -@chmod a+x configure
+ -rm -f config.cache
+
+config.status: $(srcdir)/configure
+ @echo "Rebuilding config.status..."
+ $(SHELL) ./config.status --recheck
+
+################################################
+# Various "clean" targets follow GNU conventions
+################################################
+
+clean:
+ -rm -f *~ *.o core \
+ $(DBG_UNSHARED_LIB_FILE) $(DBG_SHARED_LIB_FILE)
+
+# like "clean", but also delete files created by "configure"
+distclean: clean
+ -rm -f Makefile config.status config.cache config.log Dbg_cf.h
+
+# like "clean", but doesn't delete test utilities or massaged scripts
+# because most people don't have to worry about them
+mostlyclean:
+ -rm -f *~ *.o core \
+ $(DBG_UNSHARED_LIB_FILE) $(DBG_SHARED_LIB_FILE)
+
+# delete everything from current directory that can be reconstructed
+# except for configure
+realclean: distclean
+
+tclIndex: Dbg_lib.tcl
+ expect -c "auto_mkindex . *.tcl;exit"
+
+LINTFLAGS = -h -q -x
+
+lint:
+ lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) $(TCLLINTLIB) | tee debug.lint
+
+##################################
+# Targets for development at NIST
+##################################
+
+nist:
+ configure --verbose --prefix=/depot/tcl --exec-prefix=/depot/tcl/arch
+
+# report globals that shouldn't be public but are
+bad_globals:
+ nm $(DBG_UNSHARED_LIB_FILE) | egrep -v " [a-zU] | _Dbg"
+
+# after copying source directory, restablish all links
+symlink:
+ rm -f aclocal.m4
+ ln -s ../expect/aclocal.m4
+
+######################################
+# Targets for pushing out releases
+######################################
+
+FTPDIR = /proj/itl/www/div826/subject/expect/tcl-debug
+
+ftp: tcl-debug-$(SHORT_VERSION).tar.Z tcl-debug-$(SHORT_VERSION).tar.gz
+ cp tcl-debug-$(SHORT_VERSION).tar.Z $(FTPDIR)/tcl-debug.tar.Z
+ cp tcl-debug-$(SHORT_VERSION).tar.gz $(FTPDIR)/tcl-debug.tar.gz
+ cp HISTORY $(FTPDIR)
+ cp README $(FTPDIR)/README.distribution
+ rm tcl-debug-$(SHORT_VERSION).tar*
+ ls -l $(FTPDIR)/tcl-debug.tar*
+
+# make an alpha relase and install it on ftp server
+alpha: tcl-debug-$(SHORT_VERSION).tar.Z tcl-debug-$(SHORT_VERSION).tar.gz
+ cp tcl-debug-$(SHORT_VERSION).tar.Z $(FTPDIR)/tcl-debug-alpha.tar.Z
+ cp tcl-debug-$(SHORT_VERSION).tar.gz $(FTPDIR)/tcl-debug-alpha.tar.gz
+ rm tcl-debug-$(SHORT_VERSION).tar*
+ ls -l $(FTPDIR)/tcl-debug-alpha.tar*
+
+tcl-debug-$(SHORT_VERSION).tar:
+ rm -f ../tcl-debug-$(SHORT_VERSION)
+ ln -s `pwd` ../tcl-debug-$(SHORT_VERSION)
+ cd ..;tar cvfh $@ `pubfile tcl-debug-$(SHORT_VERSION)`
+ mv ../$@ .
+
+tcl-debug-$(SHORT_VERSION).tar.Z: tcl-debug-$(SHORT_VERSION).tar
+ compress -fc tcl-debug-$(SHORT_VERSION).tar > $@
+
+tcl-debug-$(SHORT_VERSION).tar.gz: tcl-debug-$(SHORT_VERSION).tar
+ gzip -fc tcl-debug-$(SHORT_VERSION).tar > $@
+
+Dbg.o: $(srcdir)/Dbg.c $(srcdir)/Dbg.h
diff --git a/expect/Dbg_cf.h.in b/expect/Dbg_cf.h.in
new file mode 100644
index 00000000000..84395a644e8
--- /dev/null
+++ b/expect/Dbg_cf.h.in
@@ -0,0 +1,21 @@
+/* This file is only to be included by the Debugger itself. */
+/* Applications should only include Dbg.h. */
+
+/*
+ * Check for headers
+ */
+#ifndef __NIST_DBG_CF_H__
+#define __NIST_DBG_CF_H__
+
+#undef NO_STDLIB_H /* Tcl requires this name */
+
+/*
+ * Check for functions
+ */
+#undef HAVE_STRCHR
+
+#ifndef HAVE_STRCHR
+#define strchr(s,c) index(s,c)
+#endif /* HAVE_STRCHR */
+
+#endif /* __NIST_DBG_CF_H__ */
diff --git a/expect/Dbgconfig.in b/expect/Dbgconfig.in
new file mode 100644
index 00000000000..f63812c6001
--- /dev/null
+++ b/expect/Dbgconfig.in
@@ -0,0 +1,117 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(Dbg.h)
+
+DBG_MAJOR_VERSION=1
+DBG_MINOR_VERSION=7
+DBG_MICRO_VERSION=0
+DBG_VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION
+DBG_VERSION_FULL=$DBG_VERSION.$DBG_MICRO_VERSION
+# Tcl's handling of shared_lib_suffix requires this symbol exist
+VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION
+
+AC_CONFIG_HEADER(Dbg_cf.h)
+
+CY_AC_PATH_TCLCONFIG
+CY_AC_LOAD_TCLCONFIG
+CC=$TCL_CC
+AC_PROG_CC
+CY_AC_C_WORKS
+
+# this'll use a BSD compatible install or our included install-sh
+AC_PROG_INSTALL
+
+# Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared
+AC_PROG_RANLIB
+UNSHARED_RANLIB=$RANLIB
+
+# This is for LynxOS, which needs a flag to force true POSIX when
+# building. It's weirder than that, cause the flag varies depending
+# how old the compiler is. So...
+# -X is for the old "cc" and "gcc" (based on 1.42)
+# -mposix is for the new gcc (at least 2.5.8)
+# This modifies the value of $CC to have the POSIX flag added
+# so it'll configure correctly
+CY_AC_TCL_LYNX_POSIX
+
+# we really only need the header files
+CY_AC_PATH_TCLH
+if test x"$no_tcl" = x"true" ; then
+ echo " ERROR: Can't find Tcl directory"
+ echo " See README for information on how to obtain Tcl."
+ echo " If Tcl is installed, see INSTALL on how to tell"
+ echo " configure where Tcl is installed."
+ exit 1
+fi
+
+# Use -g on all systems but Linux where it upsets the dynamic X libraries.
+AC_MSG_CHECKING([if we are running Linux])
+if test "x`(uname) 2>/dev/null`" = xLinux; then
+ AC_MSG_RESULT(yes)
+ linux=1
+ DBG_CFLAGS=
+else
+ AC_MSG_RESULT(no)
+ linux=0
+ DBG_CFLAGS=-g
+fi
+
+#
+# Look for functions that may be missing
+#
+AC_FUNC_CHECK(strchr, AC_DEFINE(HAVE_STRCHR))
+
+#
+# Look for various header files
+#
+AC_HEADER_CHECK(stdlib.h, ,AC_DEFINE(NO_STDLIB_H))
+
+# consume these flags so that user can invoke tcl-debug's configure with
+# the same command as Tcl's configure
+AC_ARG_ENABLE(load,
+ [ --disable-load disallow dynamic loading],
+ [disable_dl=yes], [disable_dl=no])
+
+AC_ARG_ENABLE(gcc,
+ [ --enable-gcc allow use of gcc if available],
+ [enable_gcc=yes], [enable_gcc=no])
+
+DBG_UNSHARED_LIB_FILE=libtcldbg.a
+
+AC_MSG_CHECKING([type of library to build])
+AC_ARG_ENABLE(shared,
+ [ --enable-shared build libtcldbg as a shared library],
+ [enable_shared=yes], [enable_shared=no])
+if test "$enable_shared" = "yes" -a "x${TCL_SHLIB_SUFFIX}" != "x" ; then
+ DBG_SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS
+# DBG_SHARED_LIB_FILE=libtcldbg$DBG_VERSION$TCL_SHLIB_SUFFIX
+ eval "DBG_SHARED_LIB_FILE=libdbg${TCL_SHARED_LIB_SUFFIX}"
+ DBG_LIB_FILE=$DBG_SHARED_LIB_FILE
+ DBG_LIB_FILES="$DBG_SHARED_LIB_FILE $DBG_UNSHARED_LIB_FILE"
+ AC_MSG_RESULT(both shared and unshared)
+else
+ DBG_SHLIB_CFLAGS=
+ DBG_SHARED_LIB_FILE="reconfigure_Tcl_for_shared_library"
+ DBG_LIB_FILE=$DBG_UNSHARED_LIB_FILE
+ DBG_LIB_FILES="$DBG_UNSHARED_LIB_FILE"
+ AC_MSG_RESULT(unshared)
+fi
+
+#
+# Set up makefile substitutions
+#
+AC_SUBST(DBG_MAJOR_VERSION)
+AC_SUBST(DBG_MINOR_VERSION)
+AC_SUBST(DBG_MICRO_VERSION)
+AC_SUBST(DBG_VERSION_FULL)
+AC_SUBST(DBG_VERSION)
+AC_SUBST(CC)
+AC_SUBST(DBG_SHARED_LIB_FILE)
+AC_SUBST(DBG_UNSHARED_LIB_FILE)
+AC_SUBST(DBG_SHLIB_CFLAGS)
+AC_SUBST(DBG_LIB_FILE)
+AC_SUBST(DBG_LIB_FILES)
+AC_SUBST(DBG_CFLAGS)
+AC_SUBST(UNSHARED_RANLIB)
+AC_OUTPUT(Makefile)
+
diff --git a/expect/Dbgconfigure b/expect/Dbgconfigure
new file mode 100755
index 00000000000..3b11615b9e2
--- /dev/null
+++ b/expect/Dbgconfigure
@@ -0,0 +1,1913 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-tclconfig directory containing tcl configuration (tclConfig.sh)"
+ac_help="$ac_help
+ --with-tclinclude directory where tcl private headers are"
+ac_help="$ac_help
+ --disable-load disallow dynamic loading"
+ac_help="$ac_help
+ --enable-gcc allow use of gcc if available"
+ac_help="$ac_help
+ --enable-shared build libtcldbg as a shared library"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=Dbg.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+DBG_MAJOR_VERSION=1
+DBG_MINOR_VERSION=7
+DBG_MICRO_VERSION=0
+DBG_VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION
+DBG_VERSION_FULL=$DBG_VERSION.$DBG_MICRO_VERSION
+# Tcl's handling of shared_lib_suffix requires this symbol exist
+VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION
+
+
+
+
+#
+# Ok, lets find the tcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tclconfig
+#
+
+if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ # Check whether --with-tclconfig or --without-tclconfig was given.
+if test "${with_tclconfig+set}" = set; then
+ withval="$with_tclconfig"
+ with_tclconfig=${withval}
+fi
+
+ echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6
+echo "configure:563: checking for Tcl configuration" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+
+ # First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ { echo "configure: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" 1>&2; exit 1; }
+ fi
+ fi
+
+ # then check for a private Tcl installation
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[7-9].[0-9] 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[7-9].[0-9] 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[7-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+
+fi
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG="# no Tcl configs found"
+ echo "configure: warning: Can't find Tcl configuration definitions" 1>&2
+ else
+ no_tcl=
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ echo "$ac_t""found $TCLCONFIG" 1>&6
+ fi
+fi
+
+
+ . $TCLCONFIG
+
+
+
+
+
+
+
+
+# Tcl defines TCL_SHLIB_SUFFIX but TCL_SHARED_LIB_SUFFIX then looks for it
+# as just SHLIB_SUFFIX. How bizarre.
+ SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX
+
+
+
+
+
+
+
+
+
+
+
+
+CC=$TCL_CC
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:659: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:689: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:740: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:772: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 783 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:788: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:814: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:819: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:828: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:847: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# If we cannot compile and link a trivial program, we can't expect anything to work
+echo $ac_n "checking whether the compiler ($CC) actually works""... $ac_c" 1>&6
+echo "configure:880: checking whether the compiler ($CC) actually works" >&5
+cat > conftest.$ac_ext <<EOF
+#line 882 "configure"
+#include "confdefs.h"
+
+int main() {
+/* don't need anything here */
+; return 0; }
+EOF
+if { (eval echo configure:889: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ c_compiles=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ c_compiles=no
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 901 "configure"
+#include "confdefs.h"
+
+int main() {
+/* don't need anything here */
+; return 0; }
+EOF
+if { (eval echo configure:908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ c_links=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ c_links=no
+fi
+rm -f conftest*
+
+if test x"${c_compiles}" = x"no" ; then
+ { echo "configure: error: the native compiler is broken and won't compile." 1>&2; exit 1; }
+fi
+
+if test x"${c_links}" = x"no" ; then
+ { echo "configure: error: the native compiler is broken and won't link." 1>&2; exit 1; }
+fi
+echo "$ac_t""yes" 1>&6
+
+
+# this'll use a BSD compatible install or our included install-sh
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# 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"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:961: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1018: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+UNSHARED_RANLIB=$RANLIB
+
+# This is for LynxOS, which needs a flag to force true POSIX when
+# building. It's weirder than that, cause the flag varies depending
+# how old the compiler is. So...
+# -X is for the old "cc" and "gcc" (based on 1.42)
+# -mposix is for the new gcc (at least 2.5.8)
+# This modifies the value of $CC to have the POSIX flag added
+# so it'll configure correctly
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1055: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1070 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1076: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1087 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1093: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1104 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1110: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+
+echo $ac_n "checking if running LynxOS""... $ac_c" 1>&6
+echo "configure:1136: checking if running LynxOS" >&5
+if eval "test \"`echo '$''{'ac_cv_os_lynx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1141 "configure"
+#include "confdefs.h"
+/*
+ * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__"
+ */
+#if defined(__Lynx__) || defined(Lynx)
+yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_lynx=yes
+else
+ rm -rf conftest*
+ ac_cv_os_lynx=no
+fi
+rm -f conftest*
+
+fi
+
+#
+if test "$ac_cv_os_lynx" = "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define LYNX 1
+EOF
+
+ echo $ac_n "checking whether -mposix or -X is available""... $ac_c" 1>&6
+echo "configure:1171: checking whether -mposix or -X is available" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_posix_flag'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1176 "configure"
+#include "confdefs.h"
+
+int main() {
+
+ /*
+ * This flag varies depending on how old the compiler is.
+ * -X is for the old "cc" and "gcc" (based on 1.42).
+ * -mposix is for the new gcc (at least 2.5.8).
+ */
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ choke me
+ #endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1192: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_posix_flag=" -mposix"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_posix_flag=" -X"
+fi
+rm -f conftest*
+fi
+
+ CC="$CC $ac_cv_c_posix_flag"
+ echo "$ac_t""$ac_cv_c_posix_flag" 1>&6
+ else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+# we really only need the header files
+
+#
+# Ok, lets find the tcl source trees so we can use the headers
+# Warning: transition of version 9 to 10 will break this algorithm
+# because 10 sorts before 9. We also look for just tcl. We have to
+# be careful that we don't match stuff like tclX by accident.
+# the alternative search directory is involked by --with-tclinclude
+#
+no_tcl=true
+echo $ac_n "checking for Tcl private headers""... $ac_c" 1>&6
+echo "configure:1222: checking for Tcl private headers" >&5
+# Check whether --with-tclinclude or --without-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then
+ withval="$with_tclinclude"
+ with_tclinclude=${withval}
+fi
+
+if eval "test \"`echo '$''{'ac_cv_c_tclh'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+# first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
+ else
+ { echo "configure: error: ${with_tclinclude} directory doesn't contain private headers" 1>&2; exit 1; }
+ fi
+fi
+
+# next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" != x ; then
+ if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/../generic; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../tcl \
+ `ls -dr ${srcdir}/../../tcl[7-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../../tcl \
+ `ls -dr ${srcdir}/../../../tcl[7-9].[0-9] 2>/dev/null ` ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tcl[7-9].[0-9] 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[7-9].[0-9] 2>/dev/null` \
+ /usr/local/src/tcl \
+ /usr/local/lib/tcl \
+ ${prefix}/include ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+# see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ ac_safe=`echo "tclInt.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for tclInt.h""... $ac_c" 1>&6
+echo "configure:1292: checking for tclInt.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1297 "configure"
+#include "confdefs.h"
+#include <tclInt.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1302: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_cv_c_tclh=installed
+else
+ echo "$ac_t""no" 1>&6
+ac_cv_c_tclh=""
+fi
+
+fi
+
+fi
+
+if test x"${ac_cv_c_tclh}" = x ; then
+ TCLHDIR="# no Tcl private headers found"
+ TCLHDIRDASHI="# no Tcl private headers found"
+ { echo "configure: error: Can't find Tcl private headers" 1>&2; exit 1; }
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
+ echo "$ac_t""is installed" 1>&6
+ TCLHDIR=""
+ TCLHDIRDASHI=""
+ TCL_LIBRARY=""
+ else
+ echo "$ac_t""found in ${ac_cv_c_tclh}" 1>&6
+ # this hack is cause the TCLHDIR won't print if there is a "-I" in it.
+ TCLHDIR="${ac_cv_c_tclh}"
+ TCLHDIRDASHI="-I${ac_cv_c_tclh}"
+ TCL_LIBRARY=`echo $TCLHDIR | sed -e 's/generic//'`library
+ fi
+fi
+
+
+
+
+
+if test x"$no_tcl" = x"true" ; then
+ echo " ERROR: Can't find Tcl directory"
+ echo " See README for information on how to obtain Tcl."
+ echo " If Tcl is installed, see INSTALL on how to tell"
+ echo " configure where Tcl is installed."
+ exit 1
+fi
+
+# Use -g on all systems but Linux where it upsets the dynamic X libraries.
+echo $ac_n "checking if we are running Linux""... $ac_c" 1>&6
+echo "configure:1363: checking if we are running Linux" >&5
+if test "x`(uname) 2>/dev/null`" = xLinux; then
+ echo "$ac_t""yes" 1>&6
+ linux=1
+ DBG_CFLAGS=
+else
+ echo "$ac_t""no" 1>&6
+ linux=0
+ DBG_CFLAGS=-g
+fi
+
+#
+# Look for functions that may be missing
+#
+echo $ac_n "checking for strchr""... $ac_c" 1>&6
+echo "configure:1378: checking for strchr" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strchr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1383 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strchr(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strchr();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strchr) || defined (__stub___strchr)
+choke me
+#else
+strchr();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1406: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strchr=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strchr=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strchr`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRCHR 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+#
+# Look for various header files
+#
+ac_safe=`echo "stdlib.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6
+echo "configure:1434: checking for stdlib.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1439 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1444: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_STDLIB_H 1
+EOF
+
+fi
+
+
+# consume these flags so that user can invoke tcl-debug's configure with
+# the same command as Tcl's configure
+# Check whether --enable-load or --disable-load was given.
+if test "${enable_load+set}" = set; then
+ enableval="$enable_load"
+ disable_dl=yes
+else
+ disable_dl=no
+fi
+
+
+# Check whether --enable-gcc or --disable-gcc was given.
+if test "${enable_gcc+set}" = set; then
+ enableval="$enable_gcc"
+ enable_gcc=yes
+else
+ enable_gcc=no
+fi
+
+
+DBG_UNSHARED_LIB_FILE=libtcldbg.a
+
+echo $ac_n "checking type of library to build""... $ac_c" 1>&6
+echo "configure:1493: checking type of library to build" >&5
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ enable_shared=yes
+else
+ enable_shared=no
+fi
+
+if test "$enable_shared" = "yes" -a "x${TCL_SHLIB_SUFFIX}" != "x" ; then
+ DBG_SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS
+# DBG_SHARED_LIB_FILE=libtcldbg$DBG_VERSION$TCL_SHLIB_SUFFIX
+ eval "DBG_SHARED_LIB_FILE=libdbg${TCL_SHARED_LIB_SUFFIX}"
+ DBG_LIB_FILE=$DBG_SHARED_LIB_FILE
+ DBG_LIB_FILES="$DBG_SHARED_LIB_FILE $DBG_UNSHARED_LIB_FILE"
+ echo "$ac_t""both shared and unshared" 1>&6
+else
+ DBG_SHLIB_CFLAGS=
+ DBG_SHARED_LIB_FILE="reconfigure_Tcl_for_shared_library"
+ DBG_LIB_FILE=$DBG_UNSHARED_LIB_FILE
+ DBG_LIB_FILES="$DBG_UNSHARED_LIB_FILE"
+ echo "$ac_t""unshared" 1>&6
+fi
+
+#
+# Set up makefile substitutions
+#
+
+
+
+
+
+
+
+
+
+
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile Dbg_cf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@TCL_DEFS@%$TCL_DEFS%g
+s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g
+s%@SHLIB_SUFFIX@%$SHLIB_SUFFIX%g
+s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g
+s%@TCL_RANLIB@%$TCL_RANLIB%g
+s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g
+s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g
+s%@TCL_SHARED_LIB_SUFFIX@%$TCL_SHARED_LIB_SUFFIX%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@RANLIB@%$RANLIB%g
+s%@CPP@%$CPP%g
+s%@TCLHDIR@%$TCLHDIR%g
+s%@TCLHDIRDASHI@%$TCLHDIRDASHI%g
+s%@TCL_LIBRARY@%$TCL_LIBRARY%g
+s%@DBG_MAJOR_VERSION@%$DBG_MAJOR_VERSION%g
+s%@DBG_MINOR_VERSION@%$DBG_MINOR_VERSION%g
+s%@DBG_MICRO_VERSION@%$DBG_MICRO_VERSION%g
+s%@DBG_VERSION_FULL@%$DBG_VERSION_FULL%g
+s%@DBG_VERSION@%$DBG_VERSION%g
+s%@DBG_SHARED_LIB_FILE@%$DBG_SHARED_LIB_FILE%g
+s%@DBG_UNSHARED_LIB_FILE@%$DBG_UNSHARED_LIB_FILE%g
+s%@DBG_SHLIB_CFLAGS@%$DBG_SHLIB_CFLAGS%g
+s%@DBG_LIB_FILE@%$DBG_LIB_FILE%g
+s%@DBG_LIB_FILES@%$DBG_LIB_FILES%g
+s%@DBG_CFLAGS@%$DBG_CFLAGS%g
+s%@UNSHARED_RANLIB@%$UNSHARED_RANLIB%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="Dbg_cf.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
diff --git a/expect/FAQ b/expect/FAQ
new file mode 100644
index 00000000000..c88f75e1cc0
--- /dev/null
+++ b/expect/FAQ
@@ -0,0 +1,1547 @@
+Expect FAQ (Frequently Asked Questions)
+
+An HTML version of this FAQ can be found in http://elib.cme.nist.gov/pub/expect/FAQ.html
+
+This FAQ lists common questions, usually about subjects that didn't
+fit well in the book for one reason or another (or weren't
+indexed sufficiently well so that people can't find the answers easily
+enough). In some cases, I've left the original questions. I suppose
+I could've stripped off the headers, but it seems more realistic to
+see actual people who've asked the questions. Thanks to everyone who
+asked.
+
+The man page and the papers listed in the README file should
+also be consulted for highly technical or philosophical discussion of
+the implementation, design, and practical application of Expect.
+
+Don
+
+======================================================================
+
+ Here is the list of questions. You can search for the corresponding
+ answer by searching for the question number. For example searching
+ for "#3." will get you that answer.
+
+
+**** General ****
+
+#1. I keep hearing about Expect. So what is it?
+#2. How do you pronounce "Ousterhout" anyway? (Or "Libes" for that matter?)
+
+#3. Why should I learn yet another language (Tcl) instead of
+writing my interaction in <a language I already know>.
+#4. What about Perl?
+#5. Do we need to pay or ask for permission to distribute Expect?
+#6. Since Expect is free, can we give you a gift?
+#7. Are there any hidden dangers in using Expect?
+
+**** Book, newsgroup, FAQ, README, ... ****
+
+#8. Why is this FAQ so short?
+#9. The FAQ background makes the FAQ hard to read.
+#10. Why isn't there an Expect mailing list?
+#11. Why isn't overlay covered in Exploring Expect?
+#12. Is the front cover of your book a self portrait (ha ha)?
+#13. How are your daughter's kidneys?
+#14. Are you going to have a book signing?
+#15. How many books have you sold?
+#16. I just want to tell you how much I like your book!
+#17. Why don't the examples in your USENIX papers work?
+#18. Can you put the examples in your book into an anonymous ftp site?
+#19. Do you have ideas for more articles on Expect?
+
+**** Can Expect do this? ****
+
+#20. Can Expect automatically generate a script from watching a session?
+#21. Can Expect understand screen-oriented (Curses) programs?
+#22. Can Expect be run as a CGI script?
+#23. Can Expect be run from cron?
+
+**** Compilation or porting questions ****
+
+#24. Why can't I compile Expect with Tcl 7.5?
+#25. Why does Expect need to be setuid root on Cray?
+#26. Does Expect run on VMS?
+#27. Is it possible to use Expect and TclX together?
+#28. Is it possible to use Expect and <lots of random extensions> together?
+#29. Why does configure complain about "cross-compiling"?
+#30. make/configure seems to be looping endlessly
+#31. Compile fails with: Don't know how to make pty_.c
+#32. Does Expect run on MSDOS, Win95, WinNT, MacOS, etc...
+
+**** Other... ****
+
+#33. Is it possible to prevent Expect from printing out its interactions?
+#34. Why does it send back the same string twice?
+#35. Why can't I send the line "user@hostname\r"?
+#36. How do I hide the output of the send command?
+#37. Why does "talk" fail with "Who are you? You have no entry utmp" or
+ "You don't exist. Go away".
+#38. Why does . match a newline?
+#39. Why doesn't Expect kill telnet (or other programs) sometimes?
+#40. How come I get "ioctl(set): Inappropriate ..., bye recursed" ...
+#41. How come there's no interact function in the Expect library?
+
+
+*
+* Questions and Answers
+*
+
+
+
+**** General ****
+
+
+#1. I keep hearing about Expect. So what is it?
+
+From: libes (Don Libes)
+To: Charles Hymes <chymes@crew.umich.edu>
+Subject: I keep hearing about Expect. So what is it?
+
+Charles Hymes writes:
+>
+>So, what is Expect?
+
+Expect is a tool primarily for automating interactive applications
+such as telnet, ftp, passwd, fsck, rlogin, tip, etc. Expect really
+makes this stuff trivial. Expect is also useful for testing these
+same applications. Expect is described in many books, articles,
+papers, and FAQs. There is an entire book on it available from
+O'Reilly.
+
+You can ftp Expect from ftp.cme.nist.gov as pub/expect/expect.tar.Z or ...gz
+
+Expect requires Tcl. If you don't already have Tcl, you can get it
+in the same directory (above) as pub/expect/tcl.tar.Z or ...gz.
+
+Expect is free and in the public domain.
+
+Don
+
+======================================================================
+
+#2. How do you pronounce "Ousterhout" anyway? (Or "Libes" for that matter?)
+
+
+From: ouster@sprite.Berkeley.EDU (John Ousterhout)
+To: libes@cme.nist.gov
+Subject: Re: pronunciation?
+Date: Tue, 29 May 90 21:26:10 PDT
+
+Those of us in the family pronounce it "OH-stir-howt", where the
+first syllable rhymes with "low", the second with "purr", and the
+third with "doubt". Unfortunately this isn't the correct Dutch
+pronounciation for a name spelled this way (someplace along
+the line it got misspelled: it was originally "Oosterhout"), nor
+is it what you'd guess if you use common sense. So, we've gotten
+used to responding to almost anything.
+
+ -John-
+
+I suppose I should say something in kind. "Libes" is pronounced
+"Lee-bis" with stress on the first syllable. Like John though, I've
+gotten used to responding to anything close.
+
+By the way, notice the date on this message. I had only written
+the first cut of Expect four months earlier. I asked John how to
+pronounce his name because I had already got a paper accepted into
+USENIX and needed to be able to say his name correctly while giving
+the talk!
+
+Don
+
+======================================================================
+
+#3. Why should I learn yet another language (Tcl) instead of
+writing my interaction in <a language I already know>.
+
+From: libes (Don Libes)
+To: Aamod Sane <sane@cs.uiuc.edu>
+Subject: Re: Expect, Tcl, programmed dialogue etc.
+Date: Mon, 2 Sep 91 15:47:14 EDT
+
+> >>A friend told me about "Expect". But then, I have to know the
+> >>idiocies of "tcl". I would like to know if there is an alternative
+> >>to Expect that is also useful in other places, so that I do not
+> >>have to spend time getting used to tcl for just this one tool.
+>
+> Your reasoning is shortsighted. Tcl is a language that can be used in
+> other applications. It won't be a waste of your time to learn it.
+>
+>I have nothing against tcl as such.
+>The reluctance to learn it comes mainly from the feeling that half my
+>life seems to be spent learning new languages that differ very little
+>from existing ones, and differ in annoying little details at that.
+>To add to the misery, every implementation has its own
+>idiosyncracies...:-(
+
+Ironically, Tcl was written specifically to halt this very problem.
+
+The author recognized that every utility seems to have its own
+idiosyncratic .rc file or programming language. Tcl was designed as a
+general-purpose language that could be included with any utility, to
+avoid having everyone hack up their own new language.
+
+ In this context, your statements do Tcl a great disservice.
+
+Don
+
+======================================================================
+
+#4. What about Perl?
+
+From: libes (Don Libes)
+To: Joe McGuckin <joe@ns.via.net>
+Subject: Re: Need Perl examples
+Date: Sun, 22 Jan 95 20:17:39 EST
+
+Joe McGuckin writes:
+>
+>Yeah, I've scanned through your book a couple of times in the last
+>week, trying to make up my mind if I should buy it.
+
+I spent three years writing it - so I'm glad to hear you're spending a
+little time considering its merit!
+
+>Pro:
+> Looks like implementing some sort of telnet daemon would be trivial.
+
+Once you see it as an Expect script, you'll realize how trivial
+these things can really be.
+
+>Con:
+> Yet another language to learn. I know perl reasonably well & would
+> like to stick with it.
+
+Good point. While I'm not a Perl guru, I've used it quite a bit
+and it's nice for many things. But I wouldn't have bothered writing
+Expect in the first place if I thought Perl was ideal. And many Perl
+experts agree - I know a lot of them who call out to Expect scripts
+rather than do this stuff in Perl - it's that much easier with Expect.
+Expect is also much more mature. It's portable, stable, robust, and
+it's fully documented - with lots of examples and a complete tutorial,
+too.
+
+In response to someone complaining about how difficult it was to do
+something in Perl, Larry Wall once remarked: "The key to using
+Perl is to focus on its strengths and avoid its weaknesses." That
+definitely applies here.
+
+Even if you do proceed with Perl, you will find the book
+helpful. Automating interactive applications has unique pitfalls to
+it and many of the descriptions and solutions in the book transcend
+the choice of language that you use to implement them.
+
+Don
+
+======================================================================
+
+#5. Do we need to pay or ask for permission to distribute Expect?
+
+From: libes (Don Libes)
+To: Mohammad Reza Jahanbin <mrj@CIS.Prime.COM>
+Subject: Copyright Question.
+Date: Tue, 26 Jan 93 23:46:24 EST
+
+Mohammad Reza Jahanbin writes:
+>Before anything let me thank you on behalf of ComputeVision R&D for
+>putting so much effort into Expect. Part of CV has been using Expect
+>for the past two years or so to build variety of tools including an
+>automated testbed for a product.
+>
+>CV is currently considering shipping the automated testbed to some of its
+>retailers, to enable them to perform their own tests before distributing
+>the product.
+>
+>The Question is, are we allowed to ship Expect? Do we need to ask
+>anyone for permission? Do we need to say or write anything in the
+>documentation? Do we need to pay for it?
+>
+>I have not been able to find any copyright (or indeed copyleft) notices
+>in the usual Expect distribution. Would you be able to clarify our position.
+
+Sorry to delay in responding. I sent your request to my management
+and they had to discuss it (if they didn't, there would be no reason
+to pay them). While they continue to discuss it, I can tell you
+informally the gist of what they will eventually say:
+
+You are allowed to do just about anything with Expect. You can even
+sell it. You need not ask our permission. You need not pay for it.
+(It is my understanding that your tax dollars, in effect, already have
+paid for it.)
+
+You should not claim that you wrote it (since this would be a lie), nor
+should you attempt to copyright it (this would be fruitless as it is a
+work of the US government and therefore not subject to copyright).
+
+NIST would appreciate any credit you can give for this work. One line
+may suffice (as far as I'm concerned) although there should be
+something to the effect that this software was produced for research
+purposes. No warantee, guarantee, or liability is implied.
+
+My management is always interested in feedback on our work. If you
+would like to send letters of praise describing how Expect has helped
+your business, we would be delighted. Letters (on letterhead please)
+are strong evidence used by policy makers when deciding where every
+dollar goes. If you want to send these letters to NIST directly, you
+may send them to the following individuals:
+
+Arati Prabahkar, Director
+NIST
+Admin Bldg, Rm A-1134
+Gaithersburg, MD 20899
+
+Ric Jackson, Manufacturing Engineering Laboratory
+NIST
+Bldg 220, Rm B-322
+Gaithersburg, MD 20899
+
+Howard Bloom, Manufacturing Systems Integration Division
+NIST
+Bldg 220, Rm A-127
+Gaithersburg, MD 20899
+
+Steve Ray, Manufacturing Collaboration Technologies Group
+NIST
+Bldg 220, Rm A-127
+Gaithersburg, MD 20899
+
+In case you're wondering about the uninformative titles, Arati Prabahkar is the
+director of all of NIST (about 3000 people) and Steve Ray (way down there
+at the bottom) is my immediate supervisor (and of 10 other very lucky people).
+
+I hope this has answered your questions. Let me know if you have
+further questions.
+
+Don
+
+======================================================================
+
+#6. Since Expect is free, can we give you a gift?
+
+This is not an actual letter but represents the gist of several
+that I've received.
+
+>>>Expect has saved us many thousands of dollars. We'd like to send
+>>>you a free copy of our product.
+>>
+>>Thanks, but please don't. As a federal employee, I'm not
+>>allowed to accept gifts of any significant value.
+>
+>But, what if it is for personal use (like at home)? I assume
+>that would be okay.
+
+It doesn't matter (much). What the rules address is whether a gift
+might cause me to make an official decision differently. This is
+especially a concern because I may very well have to decide whether or
+not to buy products from your company in the future.
+
+There is a clause that says "you may accept gifts from friends,
+regardless of value ... but you should be careful to avoid accepting
+gifts which may create an appearance of impropriety, even if permitted
+as an exception to the gift rules."
+
+I'm still permitted to accept small token gifts, such as a t-shirt
+or reasonably-priced dinner (under $20 per gift to a maximum of $50
+per year from any person or company) - so things are not totally
+ridiculous. Although the precise values in the gift rules seem rather
+arbitrary, I actually like the gift rules. They stop a lot of the
+nonsense that used to go on involving gifts.
+
+Don
+
+======================================================================
+
+#7. Are there any hidden dangers in using Expect?
+
+From: Charlton Henry Harrison <charlton@cs.utexas.edu>
+To: libes@NIST.GOV
+Date: Fri, 27 Jan 1995 23:30:56 -0600
+
+>>>Dear Don:
+>>>
+>>> I've been a fan of Expect ever since I first learned of UNIX back
+>>>in late '93. I'm young and don't have my CS degree just yet, but I worked
+>>>a while back at Texas Instruments in their Telecom Customer Support dept.
+>>>I started in late '93 (and hence, that's where I first started exploring
+>>>the UNIX environment) and immediately forsaw the need of automating a lot
+>>>of my redundant and mindless duties, but I didn't know how since we were
+>>>working over a heterogeneous LAN with multiple OSs.
+>>> Then I found out about Expect. I automated everything! My boss didn't
+>>>like hearing that I was working on something else in order to get out of
+>>>work, and I got tired of explaining it to him.
+>>> Although I accomplished all the aspects of my duties, I was infamous
+>>>for being the laziest person at work, and it showed (I made my job SO easy).
+>>>I got a new boss after a while, and he hated me from the start and fired
+>>>me soon after. Oh well, I guess my mentality didn't click with theirs.
+>>> There are a lot of people like that: they believe life is putting
+>>>in a hard day's work to get by. I hate that.
+>>> So the point is, thank you for the wonderful 'Expect'. I bought
+>>>your book and now I have the most recent version of it on my Linux system
+>>>at home. Needless to say I'm looking for another job, though.
+>>>
+>>> Charlton
+>>>
+>> Thanks very much for your nice letter. Sorry to hear about your
+>> automating yourself out of a job. Actually, I think most computer
+>> scientists have to face this dilemma. In some ways, it's a
+>> self-defeating occupation.
+>>
+>> Don
+>
+>Yeah, I'd be interested in hearing if you have a personal philosophy on
+>how to handle this kind of thing. I plan on pursuing a career in Artificial
+>Intelligence for similar reason of making life easier for everyone (me
+>in particular!) What the future holds in this category is a great
+>mystery.
+
+I'm glad you asked. My personal philosophy on this kind of thing is:
+Find someone really rich and marry them.
+
+Don
+
+======================================================================
+
+**** Book, newsgroup, FAQ, README, ... ****
+
+
+#8. Why is this FAQ so short?
+
+From: libes (Don Libes)
+To: Wade Holst <wade@cs.ualberta.ca>
+Subject: Expect question
+
+Wade Holst writes:
+>
+> 1) Is there a more up-to-date version of the FAQ than what
+> comes with expect-5.5? (For such a useful application, I
+> would expect more than 12 questions).
+
+I know that a lot of other packages have *huge* FAQs but I
+have always believed that this is an indication that their regular
+documentation sucks. As questions arise that are not addressed well
+by the original docs, the docs themselves should be fixed rather than
+new ones created.
+
+In contrast, I believe that an FAQ should literally be a list of
+frequently asked questions and little else. An FAQ should not be a
+replacement for good documentation.
+
+In that sense, I have tried to use this FAQ as a second place to
+look rather than a first place. The place you should always look
+first is Exploring Expect. At over 600 pages, the book is very
+comprehensive, well-organized, and includes three indices and two
+tables-of-contents to make it very easy to find what you want to know.
+
+The book was not a rush job. During the three years I spent
+writing it, virtually every question I was asked became incorporated
+as subject material for the book. I wanted to make sure that the book
+wouldn't need much of an FAQ!
+
+It would not make sense to try and distill the entire book into an
+FAQ (that is actually comprehensive rather that truly frequently asked
+questions). There's simply too much material there.
+
+So this FAQ is short. It really tries to stick just to *truly*
+frequently asked questions.
+
+Don
+
+======================================================================
+
+#9. The FAQ background makes the FAQ hard to read.
+
+To: bonneau@mudd.csap.af.mil (Allen Bonneau)
+Subject: FAQ background colors
+Date: Wed, 10 Apr 96 10:24:52 EDT
+
+Allen Bonneau writes:
+>... the white and gray background makes the FAQ difficult to read.
+
+It's not white and gray. It's several very close shades of gray.
+It's supposed to be very subtle. Sounds like you have your browser in
+a mode where it is mishandling colors. Try turning on dithering.
+
+Don
+
+======================================================================
+
+#10. Why isn't there an Expect mailing list?
+
+From: libes (Don Libes)
+To: dclark@nas.nasa.gov (David R. Clark)
+Subject: Mailing list for Expect
+Date: Mon, 23 Sep 91 18:21:28 EDT
+
+>Would be nice if their were an Expect mailing list. I would use it more
+>often, and be made aware of other users.
+
+Perhaps I'm too myopic, but I don't see the need for it. Most of
+the questions about Expect posted to Usenet every day can be found in
+the various FAQs or in the book, so it's pretty easy getting
+answers to them.
+
+For one reason or another (occasionally a bug fix, but often, just
+adding a neat example), I update Expect every couple of weeks.
+Personally, I'd hate being on the other end of something like this.
+Who needs patches every two weeks for problems that are likely not
+even relevant to you? (Most patches these days are either extremely
+esoteric or are related to porting Expect to some unusual machine.)
+
+>It would be helpful, too, if this served as an area for swapping programs.
+>Many of the things that I want to do are done by others already.
+
+Send me things that you'd like to distribute. I can include it
+with Expect or put it in a publicly accessible directory so other
+people can get it. I'm also willing to list links in Expect's home
+page to other web pages about projects that use Expect.
+
+There is a Tcl newsgroup, comp.lang.tcl, which many Expect users
+read. It's pretty good for asking questions about Tcl, and many of
+the readers use Expect so Expect questions are encouraged. The
+newsgroup is gatewayed to a mailing list (tcl@sprite.berkeley.edu)
+which is further described in the Tcl documentation.
+
+Don
+
+======================================================================
+
+#11. Why isn't overlay covered in Exploring Expect?
+
+From: libes (Don Libes)
+To: spaf@cs.purdue.edu
+Subject: Your book
+
+Gene Spafford writes:
+>I'm curious as to why the "overlay" command is not mentioned anywhere
+>in the book. Is that a recent addition? A deprecated feature? I
+>ended up using it in one of my scripts....
+
+The overlay command has been in Expect for a long time. In all that
+time no one has ever asked me about it and I have never used it.
+Well, I used it once but I really didn't like the result, and so I
+rewrote the script to not use it. I left the overlay command in
+Expect because it seemed like an interesting idea, but I never really
+finished it - in the sense that I believe it needs some more options
+and controls. In comparison, the interact command is very flexible
+and makes the need for overlay pretty moot.
+
+Don
+
+======================================================================
+
+#12. Is the front cover of your book a self portrait (ha ha)?
+
+From: libes (Don Libes)
+To: pkinz@cougar.tandem.com (kinzelman_paul)
+Subject: the cover?
+
+kinzelman paul writes:
+>The book finally came in. I tried to buy 4 copies but they had only 2
+>left and they came in last Saturday. Move over Stephen King! :-)
+
+4 copies!? Wow. That's more than my mother bought!
+
+>I was discussing your book with somebody who stopped in and we began
+>to speculate about the monkey on the cover. I don't suppose it's a
+>self portrait? :-)
+
+There is some real humor here. There seems to be considerable
+debate over what the creature is! The colophon at the end of
+the book says that it is a chimpanzee. I like that idea much more
+than a monkey which is what it looks like to me. My wife, who has a
+degree in zoology, explained to me that chimps are actually the second
+smartest of primates (humans are the smartest). Chimps are very
+intelligent and can do many things (but not everything) that humans
+do. Perfect for describing Expect. Anyway, she says I should be
+honored to have it grace the book cover - even in theory.
+
+I remarked to Edie (the cover designer at O'Reilly) that even though
+the cover was nice looking, everyone was going to stare at it and say,
+"Gee, but it looks like a monkey." She replied "The purpose of the
+cover is just to get people to pick the book up. This cover will do
+that. Don't worry. If you get any rude comments from anyone, at least
+you know they are paying attention."
+
+[After being inundated by people pointing out that the animal
+really is a monkey, O'Reilly subsequently decided to acquiesce and has
+changed the colophon to admit that yes it is a rhesus monkey.
+Evidentally, the book from which O'Reilly has been taking those
+pictures from was wrong on this one.]
+
+Don
+
+======================================================================
+
+#13. How are your daughter's kidneys?
+
+From: libes
+To: olav@emerson.physics.ubc.ca
+Subject: How are your daughter's kidneys?
+B. Olav Anderson writes:
+>Don,
+>
+>I bought your book regarding expect and it's great and so is Expect.
+>
+>P.S. How's your daughters kidneys? I hope the're well hydrated :-)
+
+In retrospect, I probably should have said that her "diapers" were
+what was well-hydrated. Glad to see that you found something in the
+book worth reading!
+
+Don
+
+======================================================================
+
+#14. Are you going to have a book signing?
+
+From: libes (Don Libes)
+To: Josef Sachs <sachs@panix.com>
+Subject: Expect
+
+Josef Sachs writes:
+>Do you have any book-signing sessions planned?
+
+That's very ego-boosting to contemplate but I doubt that my name
+is enough to draw the kind of crowd that would make it worthwhile.
+I'll leave that kind of thing to Howard Stern. Anyway, I have a
+full-time job working for the government. I doubt they would take too
+kindly to me taking time off for self-aggrandizing. (They weren't
+particularly encouraging to have me write a book in the first place -
+as you'll read in the Preface.)
+
+I've written a couple of other books and people have mailed me those
+for signatures. (One guy sent me an entire box of books for
+signatures - he was giving them to friends as Christmas gifts.) If
+you're similarly inclined, my address is in Expect's README file. Or
+if you're ever in my neck of the woods, feel free to stop by for a
+chat (and bring your copy).
+
+Don
+
+======================================================================
+
+#15. How many books have you sold?
+
+From: Don Libes
+To: Thomas Ragland <rags@noc.ans.net>
+Subject: Re: AIX smit automation
+In-Reply-To: <199601092106.VAA19276@bugsy.aa.ans.net>
+References: <199601092106.VAA19276@bugsy.aa.ans.net>
+--text follows this line--
+Thomas Ragland writes:
+> btw approximately how many books were sold? I just bought
+> it and it is quite helpful. Once again, thanks.
+>
+>Thomas
+
+Glad you liked the book. Sorry to disappoint you but I have no
+idea about how many have been sold. (I made my mother buy a couple,
+so I know it's a positive number.) Believe it or not, I try *not*
+to pay attention to that type of thing. I did with my first book
+and was very disappointed. (It sold well but it didn't earn that
+first million that I was dreaming about...) I've learned that I don't
+write to sell books or make money. If I did, I'd be better off
+writing "Yet Another Book on HTML" or a romance novel. No, the
+real reason that I write is - I enjoy it.
+
+Don
+
+======================================================================
+
+#16. I just want to tell you how much I like your book!
+
+To: Joe Pasko <pasko@hp7.scri.fsu.edu>
+Subject: Re: ***Expect spawn questions*****
+Date: Thu, 15 Feb 96 14:52:23 EST
+Joe Pasko writes:
+>
+>Thanks Don,
+>
+>I just took your advice and it was the tty settings. Thanks a bunch !
+>
+>As a side note: Great book !! It's the best howto for tcl-type stuff
+>that I've seen around.
+
+Thanks for the kind words. But don't tell me (gee, I already like my
+book!) - post your opinion to a newsgroup and send a review to a
+magazine. I regret that many Tcl users don't pick up the book simply
+because they think it isn't of any use to the general Tcl user - which
+of course isn't true.
+
+Don
+
+======================================================================
+
+#17. Why don't the examples in your USENIX papers work?
+
+From: libes (Don Libes)
+To: Will Smith (AC) <william@ritchie.acomp.usf.edu>
+Subject: Expect
+
+Will Smith (AC) writes:
+>I just entered some scripts from a USENIX paper that my boss had. I get
+>errors about my quotes in the script. Also, it doesn't seem to know
+>about expect_match. Thanks in advance for any insight you could offer.
+
+The USENIX papers are old and out-of-date as far as quoting goes. A
+couple years ago, I cleaned up and simplified this aspect of Expect.
+Similarly, expect_out is now where the results of expect's pattern
+matching are saved.
+
+The man page is always the best reference on what Expect currently
+supports. Alternatively, you can read the CHANGES files. These files
+document the changes from one major version to another.
+
+Don
+
+======================================================================
+
+#18. Can you put the examples in your book into an anonymous ftp site?
+
+From: libes (Don Libes)
+To: pren@cs.umass.edu
+Subject: Examples in your book "Exploring Expect"
+
+Peifong Ren writes:
+>
+>Hi,
+>
+>I bought your book "Exploring Expect" from O'Reilly.
+>I wonder can you put the eamples in your book into an anonymous ftp
+>site?
+
+All of the substantive examples come with recent versions of Expect.
+Just look in the example directory.
+
+The remaining 50 or so examples are short enough that typing them
+in only takes a minute or two. If I put them online, you'd spend more
+time looking for them (reading my online catalog, figuring out what
+the online descriptions meant, mapping them back to the file, etc.)
+then it would take to type them in. And since you're likely to want
+to change the examples anyway, there's nothing to be gained for short
+ones.
+
+Don
+
+======================================================================
+
+#19. Do you have ideas for more articles on Expect?
+
+From: libes (Don Libes)
+To: faught@zeppelin.convex.com (Danny R. Faught)
+Cc: libes
+Subject: Re: SQA Quarterly articles
+Date: Thu, 21 Dec 95 13:31:01 EST
+
+Danny R. Faught writes:
+>I just arranged to write an article on automating interactive
+>processes for an issue early next year. You have so many good pieces
+>on expect out there, it's going to be hard to add anything original.
+
+One thing I've never written is a good mini-tutorial. Magazine
+editors love these types of pieces and there's certainly a need for
+it. So I'd encourage that type of article.
+
+Another possibility is an article on how you or your colleagues
+personally applied Expect to solve your particular problem. Application-
+oriented papers are the kind that necessarily have to be written by
+people in the field who are applying the technology. People love this
+kind of practical paper. For example, a good paper might be "Writing
+a pager". This is a nice topic because you can start with a simple
+5-line script that solves the problem and then show progressive
+refinements that handle different twists on the same problem. (And
+"how to write a pager" is a very frequently asked question on Usenet.)
+
+Don
+
+======================================================================
+
+**** Can Expect do this? ****
+
+
+#20. Can Expect automatically generate a script from watching a session?
+
+From: libes (Don Libes)
+To: pete@willow24.cray.com
+Subject: Expect
+Date: Fri, 12 Oct 90 17:16:47 EDT
+
+>I like "Expect" and am thinking of using it to help automate the
+>testing of interactive programs. It would be useful if Expect had a
+>"watch me" mode, where it "looks over the shoulder" of the user and
+>records his keystrokes for later use in an Expect script.
+>
+>(Red Ryder and other Macintosh telecommunications packages offer this
+>sort of thing. You log onto Compuserve once in "watch me" mode, and
+>RR keeps track of the keystrokes/prompts. When you're done you have a
+>script that can be used to log onto Compuserve automatically.)
+>
+>Before I look into adding a "watch me" feature, I thought I should
+>ask: has this been done already?
+>
+>I'll say again that I like the tool a lot--nice work! There are other
+>people here using it for things like the testing of ksh, which
+>responds differently to signals when not used interactively.
+>
+>-- Pete
+
+The autoexpect script in Expect's example directory does what you
+want.
+
+Don
+
+======================================================================
+
+#21. Can Expect understand screen-oriented (Curses) programs?
+
+Yes, it can - with a little clever scripting. Look at the
+term_expect script for an example. It uses a Tk text widget to
+support screen-oriented Expect commands. This technique is described
+very thoroughly in Chapter 19 of Exploring Expect.
+
+Adrian Mariano (adrian@cam.cornell.edu) converted the term_expect
+code (see above) so that it runs without Tk (exercise 4 in Chapter
+19!) Both term_expect and virterm can be found in the example
+directory that comes with Expect.
+
+An alternative approach to screen-handling was demonstrated by Mark
+Weissman (weissman@gte.com) and Christopher Matheus who modified a
+version of Expect to include a built-in Curses emulator. It can be
+ftp'd from the Tcl archive as expecTerm1.0beta.tar.Z. (Note that
+Expecterm does not run with the current version of Expect.)
+
+I like the idea of keeping the curses emulator outside of Expect
+itself. It leaves the interface entirely defineable by the user. And
+you can do things such as define your own terminal types if you want.
+For these reasons and several others, I'm not likely to return to
+Expecterm.
+
+Don
+
+======================================================================
+
+#22. Can Expect be run as a CGI script?
+
+Expect scripts work fine as CGI scripts. A couple pointers might
+help to get you going:
+
+Many Expect scripts can be run directly with one change - the
+following line should be inserted before any other output:
+
+puts "Content-type: text/html\n"
+
+Be sure not to forget that extra newline at the end of the puts.
+
+Next, make sure you invoke external programs using full paths. For
+example, instead of "spawn telnet", use "spawn /usr/ucb/telnet" (or
+whatever). Remember that the PATH and other environment variables are
+going to be different than what you are used to. This is very similar
+to dealing with cron and you can get other good tips and advice from
+reading the Background chapter in the book.
+
+ One last tip: If a script runs fine by hand but not from CGI, just
+log in as "nobody" to the host on which your CGI script runs. Then
+try running it by hand. This generally makes it very obvious what's
+going on. (If you can't log in to the server or can't log in as
+"nobody", use the kibitz trick described in the Background chapter.)
+
+Don
+
+======================================================================
+
+#23. Can Expect be run from cron?
+
+Expect itself works fine from cron - however, you can cause
+problems if you do things that don't make sense in cron - such as
+assume that there is a terminal type predefined. There are a number
+of other pitfalls to watch out for. The list and explanations aren't
+short - which is why there's a whole chapter ("Background") on the
+subject in the book.
+
+Here's one that someone tried to stump me with recently: They told
+me that their program started up and then Expect immediately exited.
+We spent a lot of time tracking this down (Was the spawned program
+really starting up but then hanging - which would indicate a bug in
+the program; or was the program NOT starting up - which would indicate
+a bug in the environment; etc.) Turned out that Expect wasn't even
+running their program. They had assumed cron honored the #! line
+(which it doesn't) and so the first line in their script (exec date)
+was being interpreted by the shell and of course, the script did
+nothing after that - because that's what the shell's exec is supposed
+to do!)
+
+Don
+
+======================================================================
+
+**** Compilation or porting questions ****
+
+
+#24. Why can't I compile Expect with Tcl 7.5?
+
+You can - you just need a newer version of Expect. Note that the
+production release of Tcl 7.5 was just released and a compatible
+Expect is still in beta. So you shouldn't do this without
+caution.
+
+Expect 5.19 works fine with Tcl 7.4. If you stay with Tcl 7.4, I
+encourage you to upgrade to Expect 5.19 if you haven't already.
+
+Don
+
+======================================================================
+
+#25. Why does Expect need to be setuid root on Cray?
+
+From: libes (Don Libes)
+To: u70217@f.nersc.gov (Lori Wong)
+Subject: setuid in Expect
+Date: Thu, 24 Oct 91 16:15:20 EDT
+
+> I have been running Expect now under UNICOS 6.1 and CSOS 1.0 (Cray
+>Computer Corporation's OS). The two machines that I am running Expect
+>on have stringent security features, one of which is to limit setuid
+>privileges to specific individuals. I was wondering if you would be
+>kind enough to explain the purpose of the setuid that is needed by Expect
+>and whether it could be compiled to run without having to have setuid
+>privilege? I know it has to do with spawning and communicating with
+>the various spawned tasks, but don't know enough of the details to be
+>able to explain why Expect specifically needs setuid and whether or not
+>it could cause a security problem (could someone use it to enter into
+>the system and wreak havoc, for example?). Right now, I've limited
+>the access of Expect to my group, but need to know what the security
+>implications are if I open it to all users. I'd appreciate any light
+>you can shed on this subject...
+
+Root-access is needed to open a pty under Unicos. Thus, all programs
+accessing ptys must be setuid root. If you do an "ls -l" of programs
+like "script", "xterm", etc, you'll see this.
+
+I have no idea why this is. The requirement was probably for security
+reasons to begin with, but it has the ironic effect of making more
+programs require setuid and therefore greater possibility of errant
+setuid programs.
+
+In fact, there is one known Unicos bug relating to the way uids are
+switched at exec time which requires further special coding. If you
+search for "Cray" in the Expect source you will see significant chunks
+of code to get around the problem.
+
+I don't know if this reassures you any. All I can tell you is that a
+number of Cray experts have looked into the situation and are happy
+with the current implementation of Expect.
+
+Don
+
+======================================================================
+
+#26. Does Expect run on VMS?
+
+From: libes (Don Libes)
+To: Cameron Laird <claird@Starbase.NeoSoft.COM>
+Subject: VMS question.
+
+Cameron Laird writes:
+>Do you know of anyone working with Expect and VMS?
+>I'd like not to re-invent wheels, but, if I'm to be
+>the first one, I want others to benefit.
+
+No, I'm not aware of anyone doing it. Since VMS claims POSIX
+conformance, it shouldn't be that hard - Expect uses the POSIX calls
+if it can. Probably the hardest part will just be modifying the Makefile
+and the configure script!
+
+However, that there might be a simpler solution. The neat thing
+about Expect is that you can control other computers easily. Run
+Expect on your UNIX box and have it log in to the VMS box and do its
+thing. (You can bypass the login garbage by using an inet daemon.)
+We've done exactly this to a number of weird pieces of hardware we
+have around the lab (robots, Lisp machines, embedded controllers, and,
+of course, a VAX running VMS). It saves time porting!
+
+Don
+
+======================================================================
+
+#27. Is it possible to use Expect and TclX together?
+
+Is it possible to use Expect and TclX together?
+From: bfriesen@iphase.com (Bob Friesenhahn)
+Date: 20 Jul 1994 04:09:43 GMT
+Organization: Interphase Corporation, Dallas TX - USA
+
+Jeffery A. Echtenkamp (echtenka@michigan.nb.rockwell.com) wrote:
+: Do Expect and tclX work together? If so, must anything special be done to
+: get them to work together?
+
+This answer courtesy of Bob Friesenhahn, Interphase (bfriesen@iphase.com):
+
+They work fine together. However, you should prepend "exp_" to your Expect
+command names. This will ensure that there are no conflicts between Expect
+commands and tclX commands of the same name (like wait).
+
+Just pick up the "make-a-wish" package, follow the instructions, and you will
+be all set. I have built a wish based on tcl, tk, Expect, tclX, and dp using
+this technique with no observed problems.
+
+Bob
+
+[If you need additional information, please read Chapter 22
+("Expect as Just Another Tcl Extension") of Exploring Expect. Its
+sole focus is how to make Expect work with other extensions. - Don]
+======================================================================
+
+#28. Is it possible to use Expect and <lots of random extensions> together?
+
+From: libes (Don Libes)
+To: Frank Winkler <winkler@eas.iis.fhg.de>
+Subject: Q Expect + TkSteal
+
+Frank Winkler writes:
+>Hi don,
+>
+>a short question considering installation of Expectk.
+>
+>Is it possible to build an Expectk-binary, which uses
+>the features of BLT, TkSteal and Expect ?
+
+I've never done it, but I know it must be possible because the tgdb
+package in the Tcl archive uses all of those extensions with Expect.
+
+Expect is a "well-behaved extension" in the sense that it requires no
+changes to the Tcl core. So Expect should work with any other Tcl
+extensions. You just need to add the usual Exp_Init call to main() or
+the other _Init calls to Expect's main.
+
+>If yes, which of them should be build first, second ... ?
+
+Order doesn't matter.
+
+I've done this kind of thing by hand. It's pretty simple. But people
+tell me the make-a-wish package in the Tcl archive automates the
+creation of multi-extension Tcl applications.
+
+[Also see the answer to the previous FAQ answer.]
+
+Don
+
+======================================================================
+
+#29. Why does configure complain about "cross-compiling"?
+
+From: libes (Don Libes)
+To: morton@hendrix.jci.tju.edu (Dan Morton)
+Subject: Re: Sorry to bother you, but...
+
+Dan Morton writes:
+>Don,
+>
+>I've posted an inquiry to comp.lang.tcl about my configure problems with
+>expect, but I've not yet gotten a reply. Perhaps you can nudge me in the
+>right direction?
+>
+>I'm running HP-UX 9.0 on a 735, and I've snagged the latest versions of Tcl
+>and expect from NIST (7.4 and 5.18 respectively). My gcc is v2.6. Tcl
+>configured and built out of the box, but I can't get expect to configure
+>properly. No matter what I do, it thinks it wants to cross-compile. I
+>think it's failing that little snippet of eval code. It gets further if I
+>specify --host=HP, but still complains about cross compiling. Here's the
+>result without options:
+>
+>{hendrix:~/expect-5.18:8} ./configure
+>checking for gcc... gcc
+>checking whether we are using GNU C... yes
+>checking whether gcc accepts -g... no
+>checking how to run the C preprocessor... gcc -E
+>checking whether cross-compiling... yes
+>checking whether cross-compiling... (cached) configure: error: You need to
+>specify --target to cross compile,
+> or the native compiler is broken
+
+I guess the error message has to be clearer. The message:
+
+ "or the native compiler is broken"
+
+means that configure tried to compile a simple program and it failed.
+Here's the program it tries to compile:
+
+ main() {
+ return(0);
+ }
+
+The configure output that you showed me says that it found gcc.
+Perhaps it was misinstalled or is just a placeholder and doesn't
+actually do anything? Try compiling a tiny C program yourself from
+the command line.
+
+Don
+
+======================================================================
+
+#30. make/configure seems to be looping endlessly
+
+To: Xiaorong Qu <aqu@cisco.com>
+Subject: Make message for Expect
+--text follows this line--
+Xiaorong Qu writes:
+>Don,
+>
+>The following is the output of make, you can find
+>that the process repeated three times.
+
+I bet what's going on is that your system clock is set to some
+ridiculous time such as last year. "Make" is sensitive to your clock.
+Please fix your clock. Then check that all the files are "older"
+than the current time. (If not, "touch" them all.)
+
+Don
+
+======================================================================
+
+#31. Compile fails with: Don't know how to make pty_.c
+
+From: libes (Don Libes)
+To: wren@io.nosc.mil
+Subject: Compile fails with: Don't know how to make pty_.c
+
+> I'm trying to compile Expect on hpux 9.01,
+> downloaded from ftp.cme.nist.gov expect.tar
+
+> after running config
+> the make fails with "Don't know how to make pty_.c. (compile fails)
+> I see three versions pty_sgttyb.c, pty_termios.c and pty_unicos.c in
+> the load, but the configure picked none of them.
+> I tried forcing to pty_termios.c but that failed with other compile errors.
+
+I've seen this happen because gcc was partially installed. configure
+finds the gcc stub and uses gcc for all the tests. But because the
+compiler doesn't work, every test fails so configure doesn't select
+any of the choices.
+
+So either finish installing gcc or delete the stub.
+
+(And if it's not that, then something similar is wrong with whatever
+compiler you've got. Look closely at the output from configure, it
+will tell you what compiler it is trying to use.)
+
+By the way, Expect compiles fine on my HP (A.09.05 E 9000/735).
+
+Don
+
+======================================================================
+
+#32. Does Expect run on MSDOS, Win95, WinNT, MacOS, etc...
+
+From: libes (Don Libes)
+To: Gerry_Jones@qmgateib.mitre.org
+Subject: Does Expect run on ...
+Date: Wed, 11 Oct 95 19:57:42 EDT
+
+>I am in a group looking into developing script language-based applications for
+>Mac and PC-Windows environments. Our intent is to write scripts to work with
+>interactive applications (e.g. telnet). After asking around, I started
+>looking into Tcl/Tk, which now have 'official' (?) (alpha) Mac and PC-Windows
+>ports. One of the people in our group has been working (in UNIX) with Tcl and
+>Tk for quite some time, and said if there isn't an Expect port or similar tool
+>for Mac and PC-Windows, then we shouldn't use Tcl/Tk; i.e. they would be too
+>limited and/or require too much work to do what we need. I've been cruising
+>the Web for information, reading the Newsgroups, read the FAQs, etc., and have
+>the following questions:
+>
+>1) Is there a current or planned port of Expect to Mac or PC-Windows
+>environments?
+
+No, Expect isn't currently portable to Windows or Mac. Let me know
+if you're seriously interested in a lot of work. I'm not saying it's
+not possible. It's definitely possible and the porting work at Sun
+has made it easier than before. But it's still not a weekend hack.
+Far from it.
+
+I actually requested some time to work on it this year and
+management said ("sure Don, go ahead") but I see now that they
+approved approximately 65 weeks worth of projects for me for the
+second half of the fiscal year. (Yes, I'm serious, they really did.)
+So I wouldn't hold my breath on this. I'm really hoping someone
+skilled with UNIX and NT volunteers some time. Funding contributions
+would also help.
+
+If you are a student and would like a fun but demanding job for the
+summer, let me know. I'd be willing to let someone come up to speed
+even if you don't already have all the skills. And we offer
+continuing internships if you'd like to come back for a semester or
+two. Pay is competitive. Note: you must be a US citizen and you must
+have good grades just to get through our personnel department.
+
+Don
+
+======================================================================
+
+**** Other... ****
+
+
+#33. Is it possible to prevent Expect from printing out its interactions?
+
+From: libes (Don Libes)
+To: Sunanda Iyengar <sunanda@simvax.labmed.umn.edu>
+Subject: Disabling display from Expect
+
+Sunanda Iyengar writes:
+>Is it possible to have Expect interact with a process and not print-out
+>the results of interaction? In my application, I need it to go into a
+>silent mode, communicate with a process without reporting to the user, and
+>then come back to normal mode and put the process into interactive mode.
+
+Use the following command:
+
+ log_user 0
+
+To restore output:
+
+ log_user 1
+
+See the Expect man page for more details or page 175 of Exploring
+Expect for details and examples.
+
+Don
+
+======================================================================
+
+#34. Why does it send back the same string twice?
+
+From: Don Libes
+To: yusufg@himalaya.cc.gatech.edu (Yusuf Goolamabbas)
+Subject: Duplicate pattern matches in Expectk
+--text follows this line--
+ Hi, I am trying to do a very simple thing in expectk
+
+ spawn cat
+ expect_background -re ".+" {
+ send $expect_out(0,string)
+ }
+ exp_send "Hello World\n"
+
+ Now the display in the text widget looks like this
+ Hello World\r
+ Hello World\r
+
+ whereas I was expecting only one line
+ Hello World\r
+
+ Thanks in advance, Yusuf
+ --
+ Yusuf Goolamabbas yusufg@cc.gatech.edu
+ Graphics, Visualization, & Usability Center (O) 404.894.8791
+ College of Computing Georgia Tech
+ http://www.cc.gatech.edu/grads/g/Yusuf.Goolamabbas/home.html
+
+This is correct behavior. The first "Hello World" is echoed by the
+terminal driver. The second is echoed by cat. This behavior has
+nothing to do with Expectk (or Expect for that matter). You can see
+this same thing if you type to cat interactively.
+
+% cat
+Hello World
+Hello World
+
+In the example above, I typed "cat" at the shell prompt and pressed
+return. Then I entered "Hello World" and pressed return. Looking at
+the output I *see* "Hello World" twice even though I only entered it
+once.
+
+You can account for this behavior in your patterns. Alternatively,
+just turn off the echo. In your particular case though, it's doing
+the right thing, showing you the result of an interactive cat just as
+if you had typed it yourself.
+
+In practice, this kind of problem doesn't arise - because programs
+like cat aren't spawned (except in very special situations). I assume
+that cat was just something you chose to experiment with.
+
+Don
+
+======================================================================
+
+#35. Why can't I send the line "user@hostname\r"?
+
+From: libes (Don Libes)
+To: bt@nadine.hpl.hp.com
+Subject: Re: [Q] Expect, ftp and '@'
+
+> I am attempting to use Expect to perform anonymous ftp gets without
+>my having to type all the stuff --- I mean, waaaiiiting for the
+>prompt, entering a-n-o-n-y-m-o-u-s with my fat fingers, and the rest.
+>
+> But I have a probleme: as I set the password to be my e-mail address:
+> set password "bt@hplb.hpl.hp.com"
+
+> the ftp servers seem not to receive neither my login name nor the
+>at-sign. Some of them do not care, some others say "ok, but don't do
+>that again", and the last ones throw me off.
+
+The short answer is to upgrade to Expect 5.20 or later. (Warning:
+5.20 is still in beta.) If you don't feel like doing this,
+here's the explanation for older versions of Expect:
+
+spawn initializes the terminal by using your current parameters and
+then forces them to be "sane". Unfortunately, on your system, "sane"
+says to interpret the "@" as the line-kill character.
+
+The most sensible thing to do is change "sane" in your Makefile to
+something that makes sense. (Since you work at HP, you might also
+suggest that they modernize stty!)
+
+Here's an example of a replacement line for the Makefile:
+
+ STTY = -DDFLT_STTY=\""sane kill ^U"\"
+
+Other alternatives are: quote the @, or use the -nottyinit flag, or
+set the stty_init variable.
+
+Don
+
+======================================================================
+
+#36. How do I hide the output of the send command?
+
+From: tim@mks.com (Timothy D. Prime)
+Subject: Re: hide the text of expect's send command?
+Date: 29 Mar 1996 15:41:02 GMT
+
+In article <khughesDoy1yH.5zo@netcom.com>, Kirby Hughes <khughes@netcom.com> wrote:
+> I don't want to see (on the screen) the text sent by a "send" command. Is
+> there a way to hide it? "log_user 0" works for text coming back to me, but
+> doesn't (seem to) work for sending...
+>
+> #!/usr/local/bin/expect --
+> log_user 0
+> spawn telnet proxy
+> expect Command
+> send "c [lrange $argv 0 1]\n"
+> log_user 1
+> interact
+
+This answer courtesy of Timothy Prime, Mortice Kern Systems (tim@mks.com):
+
+The output you are seeing wasn't printed by the send command.
+(I.e., the log_user command is working just fine.) The output you see
+is from the interact command. The interact command found program
+output and thus wrote it to the terminal so that you could see it.
+That's what the interact command is supposed to do!
+
+Although the expanation might take a little thought, the solution is
+easy. Simply put an expect command in before the command "log_user 1".
+Match against the last characters that you wish to suppress.
+======================================================================
+
+#37. Why does "talk" fail with "Who are you? You have no entry utmp" or
+ "You don't exist. Go away".
+
+From: libes (Don Libes)
+To: Will Smith (AC) <william@ritchie.acomp.usf.edu>
+Subject: Expect
+
+Will Smith (AC) writes:
+>Hi there. I was wondering if you had any ideas to why i am getting
+>this problem running an Expect script which tries to spawn a talk
+>process to myself on another machine. Would it have anything to do
+>with the fact that the executables are NOT installed in /usr/local/bin
+>or because it wasnt installed by ROOT or what. This is what my Expect
+>script looks like.
+>
+>#! /home/ritchie/ops/william/test/expect -f
+>
+>spawn talk william@curiac.acomp
+>set timeout 200
+>expect {*established*}
+>set send_human {.1 .3 1 .05 2}
+>send -h "This is only a test.. I swear \ Please don't bust me with expect \n >expect "{*\r*}"
+>expect "{*\r*}"
+>exec sleep 5
+>send -h "Ok, well see ya tomorrow you idiot \n"
+>exec sleep 3
+>
+>The error i get is that it returns this when i run the script.
+>
+> Who are you? You have no entry in /etc/utmp! Aborting...
+
+On most systems, Expect does not automatically make a utmp entry. (A
+utmp entry normally indicates login information which seems kind of
+pointless for Expect scripts.) This allows Expect to run non-setuid.
+
+Normally, this lack of utmp entries doesn't mean much. However, a few
+programs actually refuse to run without a utmp entry. Fortunately,
+there are workarounds:
+
+Program-dependent solutions:
+
+"talk" is the only program I'm aware of that falls into this category.
+One solution is to get ytalk. ytalk doesn't have this problem plus it
+fixes many other bugs in talk, such as being able to communicate with
+both old and new talk.
+
+Program-independent solutions:
+
+Use a program specifically intended to create utmp entries. Such
+programs are easy to write or get if you don't have them already. For
+instance, sessreg is one which comes with the xdm distribution. And
+Solaris uses utmp_update. I like this approach because it isolates
+the setuid code in a small single system utility rather than in every
+program on the system that needs this ability.
+
+Don
+
+======================================================================
+
+#38. Why does . match a newline?
+
+From: libes (Don Libes)
+To: xipr@alv.teli.se (Ivan Prochazka)
+Subject: Why does . match a newline?
+Ivan Prochazka writes:
+>
+>Hello Don.
+>
+>In my opinion(and emacs) the regexp-symbol "." stands for all
+>characters except newline(\n).
+>This is not the case in Expect 5.2.
+
+Yes, there are some packages that follow this convention, but I don't
+think it is appropriate for Expect. Unlike emacs, most Expect
+patterns don't look for full lines - more often they look for prompts
+which *don't* end with newlines.
+
+I find that I actually write the [^\n] pattern very rarely. And
+if I write it frequently in a script, then the expect itself probably
+ought to be in a subroutine.
+
+In fact, the more common line-terminating sequence in Expect is \r\n,
+so that might make a more likely argument. In any case, Expect
+defines . the way POSIX does. So I feel pretty good about the
+definition of . being what it is.
+
+Don
+
+======================================================================
+
+#39. Why doesn't Expect kill telnet (or other programs) sometimes?
+
+From: libes (Don Libes)
+To: Karl.Sierka@Labyrinth.COM
+Subject: Re: need help running telnet Expect script from cron on sunos 4.1.3
+
+karl.sierka@labyrinth.com writes:
+> The only problem I am still having with the script I wrote is that
+> the telnet does not seem to die on it's own, unless I turn on debugging.
+
+Actually, Expect doesn't explicitly kill processes at all. Generally,
+processes kill themselves after reading EOF on input. So it just seems
+like Expect kills all of its children.
+
+> I was forced to save the pid of the spawned telnet, and kill it with an
+> 'exec kill $pid' in a proc that is hopefully called before the script
+> exits. This seems to work fine, but it makes me nervous since omnet
+> charges for connect time, and leaving a hung telnet lying around could
+> get expensive. I warned the rest of the staff so that they will also be
+> on the lookout for any possible hung telnets to omnet.
+
+The problem is that telnet is not recognizing EOF. (This is quite
+understandable since real users can't actually generate one from the
+telnet user interface.) The solution is to either 1) explicitly drive
+telnet to kill itself (i.e., a graceful logout) followed by "expect
+eof" or 2) "exec kill" as you are doing.
+
+This is described further in Exploring Expect beginning on page 103.
+
+Don
+
+======================================================================
+
+#40. How come I get "ioctl(set): Inappropriate ..., bye recursed" ...
+
+From: libes (Don Libes)
+To: james@Solbourne.COM (James B. Davis)
+Subject: How come I get "ioctl(set): Inappropriate ..., bye recursed" ...
+Date: Tue, 10 Dec 91 10:47:21 MST
+
+>Every time I ^C out of a Expect script run I get:
+>
+>ioctl(set): Inappropriate ioctl for device
+>bye recursed
+>
+>james@solbourne.com
+
+This answer courtesy of Michael Grant (mgrant@xdr.ncsl.nist.gov):
+
+You (or whoever installed gcc) forgot to run the fixincludes shell
+script while installing gcc. Recompiled gcc with itself, then run the
+fixincludes script - and the messages will go away.
+
+Michael Grant
+======================================================================
+
+#41. How come there's no interact function in the Expect library?
+
+From: libes (Don Libes)
+To: Djamal SIMOHAND <djamal@lyohp5.in2p3.fr>
+Subject: Re: exp_expectl
+Date: Wed, 3 Jan 96 12:17:01 EST
+
+Djamal SIMOHAND writes:
+>I have already used the Expect program to write a script to connect by
+>telnet on my machine. Now I made a graphic interface in C and I need
+>the expect in C in order to have a coherent executable.
+>
+>I've already written most of the C already, but the connection is
+>closed just after my program is finished. Then I have no opportunity
+>to work on my machine. It seems I need of the equivalent of
+>"interact" in C. Is there such a function in the C library?
+>
+>Thanks for your help,
+> Djamal
+
+No, there is no interact-like function in the C library. The reason
+is three-fold:
+
+1) It is simple enough to write your own. It's just a loop after
+all:
+
+ while 1 {
+ select/poll()
+ read()
+ write()
+ }
+
+2) There's no way I could possibly provide all the options you might
+need. In Expect, it's not a problem because the environment is very
+controlled, but in C, it's impossible to control what you might want
+to do. For example, you mention that you're embedding your code in a
+graphics application. Graphics packages typically have their own
+event manager, so you wouldn't want a monolithic interact function.
+
+3) The library is intended for embedding in other applications, where
+it rarely makes sense to give the user direct control of a spawned
+process. That kind of thing makes so much more sense to handle with
+an Expect script than a C program. The C library was not intended as
+a replacement for Expect. Expect is really the tool of choice for
+interaction problems, not C.
+
+In summary, there's very little payoff for the library to supply an
+interact function. A simple one would only satisfy people who should
+be using Expect anyway - and it's impossible to create one that would
+do everything that everyone wants. It's easier just to let people
+roll their own.
+
+Don
+
+======================================================================
+
+
+Names of companies and products, and links to commercial pages are
+provided in order to adequately specify procedures and equipment used.
+In no case does such identification imply recommendation or
+endorsement by the National Institute of Standards and Technology, nor
+does it imply that the products are necessarily the best available for
+the purpose.
+
+Last edited: Thu Jun 6 07:35:19 EDT 1996 by Don Libes
diff --git a/expect/HISTORY b/expect/HISTORY
new file mode 100644
index 00000000000..df0ea58c1e9
--- /dev/null
+++ b/expect/HISTORY
@@ -0,0 +1,3042 @@
+This is the HISTORY file for Expect. Modifications made by Cygnus
+support are in ChangeLog. - Don
+
+Date Version Description
+------- ------- ------------------------------------------------------
+6/15/98 5.26.1 Dean Sauder <dsauder@dcn.att.com> noted C-preprocessor lines in
+ configure must start in column 0.
+
+5/18/98 5.26.0 Kevin Schleicher <kms@lucent.com> noted xkibitz leaves xterms
+ if first xterm is HUP'd. Kevin also noticed a resource leak
+ in dislocate. Both problems fixed.
+
+ Robbie Gilbert <rwg@fns.com> noted expect_devtty was logging
+ devtty (twice) to stdout. Fixed.
+
+ Added support inttypes.h, required on Solaris 5.6 for termios.h
+
+ Kristina <kristina@greatbasin.net> noted that tip failed when
+ spawned from a cgi script (BSDI BSD/OS 3.1 i386) because tip
+ didn't see a definition for SHELL and HOME. They need to be
+ set. (Doesn't have to be anything useful; the empty string is
+ fine!) Solution: documented this in Expect man page.
+
+ Zachariah Baum <zack@studioarchetype.com> noted that config.sub
+ didn't grok Intel 686. Found a newer version that did in
+ autoconf-2.11.
+
+ POTENTIAL INCOMPATIBILITY: Changed interact so that it observes
+ parity while matching. It used to ignore parity. This impacts
+ people who use interact to connect through to a real serial
+ device that generates parity. If matches don't work, use the
+ exp_parity command. (This fix should have been made years ago,
+ when the exp_parity command was added. It is now absolutely
+ necessary now that people are doing matching with 8 bits.)
+
+ After the second occurrence of a system admin who broke grantpt
+ by removing setuid from the relevant system util, I added an
+ explicit test and explanation.
+
+ Disabled history in xkibitz. There seems to be some new
+ incestuous relationship between history and unknown now so that
+ redefining unknown leaves Tcl calling history but without
+ knowing what it is because it's never been defined (as it would
+ be by the traditional unknown).
+
+ Fixed quoting bug in passwd.cgi example.
+
+9/28/97 5.25.0 Switched back to hand-generating pkgIndex.tcl file after too
+ many complaints about problems running pkg_mkIndex.
+
+8/12/97 5.24.1 Chris Schanzle <chris@goof2.ncsl.nist.gov> pointed out that
+ install fails on a virgin file system because install_shared_
+ lib depends on a directory that hasn't yet been created.
+
+ Larry Virden gave corrections to URLs in README.
+
+8/21/97 5.24.0 Bo Johansson <bo.johansson@mbox2.swipnet.se> noted TclWordEnd
+ had changed and provided fix. This caused crash in expect.
+
+8/18/97 5.23.0 This version supports Tcl 8.0 and continues support for 7.6.
+ Refs to Tcl_Files dropped. inter_return and close became
+ obj cmds. Rewrote notifier (again) to accomodate new notifier
+ model. Lots of other miscellaneous tweaks. Also see debugger
+ HISTORY file.
+
+ Finally removed long-deprecated commands "continue -expect",
+ "send_spawn", and "getpid" and their exp_ versions.
+
+ Harold Brauer <harold.brauer@canada.cdev.com> reported problems
+ with an old SCO system (i386-unknown-sco3.2v5.0) that turned
+ out to be due to a typo in the configure script.
+
+ Jimmy Aitken supplied mods to config.guess for brand new and
+ very old Pyramid systems.
+
+ Buz Owen noted memory leak in use of expect_background (with
+ no args).
+
+ Jonathon Kamens noted provided patch for pty_termios.c for
+ modern Sequent (which ptmx).
+
+ Jonathon Kamens noted that TCL defined RANLIB for shared lib
+ (if --enabled-shared) which isn't appropriate when Expect tries
+ to build both shared and unshared libs.
+
+ Jonathon Kamens noted that shared lib config didn't work on
+ SunOS. I had used Tcl's SHLIB_SUFFIX instead of its
+ SHARED_LIB_SUFFIX.
+
+ Qingyi Liao <liao@casabyte.com> encountered core dump when
+ exp_bg -i $exp_spawn_any was retracted. Bug in ecmd_remove_fd.
+
+ Fixed a bunch of bugs in example/gethostbyaddr.
+
+ Josef Sachs noted that stty cannot be caught when no /dev/tty.
+ It calls exit instead of returning an error.
+
+ Gordon Chaffee <chaffee@plateau.CS.Berkeley.EDU> patched
+ Exp_WaitCmd - it was zeroing pid element instead of wait.
+
+ Bob Manson <manson@cygnus.com> provided fix for HP on which it
+ was possible for timer to be mistakenly deleted in
+ exp_get_next_event while processing a pty open event.
+
+ Jeff Slonaker <JSlonaker@osc.uscg.mil> noted that exp_poll.c
+ had wrong signature and poll had arguments out of order! That
+ would suggest that no one has ever used exp_poll.c before...
+
+ 5.22.1 Larry Virden noted that TCL_BUILD_LIB_SPEC can't be used if
+ build directory has been removed. Added check to configure.
+
+ Worked more on package command. Buz Owen pointed out that my
+ code wouldn't support redefinition of TCL_LIBRARY. Bumped up
+ minor version to avoid package loading mishaps.
+
+ Nigel Standing <nigel@idiom.com> noted lack of C-u binding in
+ tkpasswd - must be due to change in tk4.2.
+
+ Forced env(SHELL) to be defined inside kibitz for when using
+ with CGI.
+
+ Charles Packer <packer@fermi.gsfc.nasa.gov> noted that CRAY-YMP
+ needed sys/types.h in exp_console.c
+
+ Extra / when developing defn of TCL_LIBRARY. Shouldn't
+ actually cause any problems though.
+
+2/3/97 5.22.0 Fixed package support - again. Sigh.
+
+ David Pasirstein <dpasirst@sun.cs.wcupa.edu> noted that RedHat
+ Linux 2nd passwd prompt requires slightly different pattern -
+ modified mkpasswd and tkpasswd.
+
+ Toshiaki Nomura <nom@yk.fujitsu.co.jp> provided patch to
+ config.guess for Fujitsu DS/90.
+
+ Roger Brooks <R.S.Brooks@liverpool.ac.uk> noted C lib passed
+ argv[0] instead of file to first arg of execvp.
+
+ Cary D. Renzema <caryr@mxim.com> noted that a simple puts -nnl
+ might never appear - Expect closes all of its fds before Tcl
+ gets a chance to flush. Stdout is the obvious problem since
+ Expect thinks it can cavalierly close that too. Hmm.
+
+ At request of Tom Tromey, solved possible missing tclRegexp.h
+ problem by having Expect install it. Cleaned up TCLHDIR and
+ TCL_LIBRARY hackery in Makefile.
+
+12/27/96 5.21.7 Nelson Beebe noted unset is not portable in /bin/sh. Removed
+ and converted everything to understand CONFIG_SHELL.
+
+ Modified cryptdir to strip out shell metachars from filenames.
+
+12/10/96 5.21.6 Michael Schumacher noted that some systems cannot build
+ unshared libs from shared objects. Chose to go with BLT's
+ approach of building shared objs in separate shared directory.
+
+ Buz Owen <ado@bbn.com> noted that "package require Expect"
+ didn't work because it looked for Expect lib in the wrong
+ place (well, the "documented" place). The problem is that Tcl
+ insists libraries should be in the same directory as the
+ pkgIndex.tcl file while the natural thing to do would be to
+ split them up and put the .tcl file in the arch-indepent
+ app-specific scripts dir and the lib in the arch-dependent
+ common dir. Sigh. If this is ever fixed/changed, the
+ instructions in the Makefile should be fixed.
+
+ <Van.Trinh@siemenscom.com> noted that expect library name
+ exceed filename max on some systems - like his old SCO.
+
+12/4/96 5.21.5 Michael Schumacher noted new configure wasn't passing on Tcl's
+ shared lib cflags.
+
+10/26/96 5.21.4 Achyutram Bhamidipaty <ram@epic.com> ran into bugs in Expect's
+ file event handler which prevented expectk from entering
+ implied event loop. Also found one memory problem - thanks
+ to CenterLine.
+
+ Tom Tromey fixed handling of --enable-shared when overriding
+ Tcl's value et al. Tom also added missing "else true" to
+ Makefile: "In a Makefile, you have to always supply an "else"
+ clause for an "if", to work around a bug in certain versions of
+ sh. In some versions of sh, an "if" whose test fails will
+ return the status of the test if there is no "else" clause --
+ causing spurious make failures." See ChangeLog.
+
+10/18/96 5.21.3 Example directory was missing several examples.
+
+10/17/96 5.21.2 Debugger section of configure file corrupted.
+
+10/10/96 5.21.1 Oops, distribution unpacked into wrong version.
+
+ Tom Tromey provided patch for stty to understand OSF 4.0.
+
+9/28/96 5.21.0 Official Expect release for Tcl 7.5.
+
+ Junio Hamano <junio@twinsun.com> provided fixes for aclocal
+ for with_tcl/tkconfig.
+
+ Roger Billau <rfbilla@amtnet.sandia.gov> noted that C library
+ didn't work on Solaris 2.5. Turns out Solaris requires fflush
+ be called between input and output operations on FILE pointers.
+
+ Lots of Cygnus mods - see ChangeLog.
+
+ Sid Cowles <scowles@incyte.com> and Hans Riethmann
+ <hans@F1.telekurs.ch> noted relative path specs of tcl-includes
+ (and others) caused debugger config to fail since it is at a
+ different directory level.
+
+ Al Snow <asnow@fuwutai.att.com> noted -C failed due to typo.
+
+8/17/96 5.20b18 Andrew Rakowski <andrew.rakowski@nr.usu.edu> noted no defn of
+ LIB_RUNTIME_DIR, a creation of Tcl7.5p1.
+
+ Tom Tromey added -v to Expect and -version to Expectk.
+
+ Ben Boule <bboule@xylogics.com> noted that Interactive (IUNIX)
+ requires 9 char max length after -l. Looks like squeezing out
+ the "." is sufficient. He also noted that IUNIX needs -Xp in
+ LIBS to find strftime. This test should really be done by Tcl.
+
+8/12/96 5.20b17 Glen Biagioni <glen@prosoft.com> noted interact -re "A(xx)"
+ failed to match. Problem turned out to be that Tcl 7.5 changed
+ a constant which in the regexp code, which Expect didn't see
+ because it provides its own defn for interact. Alas, the one
+ thing Expect reuses from Tcl was where the change was. This
+ should really be fixed so Expect doesn't rely on Expect in this
+ way, but there's no point in putting in a lot of work on regexp
+ when we're anticipating a new one soon anyway.
+
+ Bjorn S. Nilsson <nilsson@nbivms.nbi.dk> noted fixcat hangs.
+ Turned out that new Tcl (7.5p1) now waits for all children to
+ disappear. But Expect still had a handle to a child. I added
+ an exit handler to close the connections before Tcl's exit
+ handler.
+
+ Tom Tromey provided patch to support augmenting CFLAGS on
+ Makefile invocation.
+
+ Gary Merinstein <gmerin@panix.com> noted that configure failed
+ on his linux unless it had --enabled-shared. Not quite sure
+ about how this can be, but the flag wasn't being passed to the
+ debugger's configure, so I've fixed that and hopefully this
+ will cure the original prob.
+
+ Added initial announcement of full version at beginning of
+ configure. This should ease my pain in responding to people
+ sending me config output without including version numbers.
+
+ Tom Tromey noted expect_cf.h was machine dependent. Fixed
+ expect_comm.h so that it no longer required expect_cf.h (which
+ should be renamed to indicate it is no longer public).
+
+ Bart Robinson <lomew@cs.utah.edu> provides mods to support
+ openpty() in FreeBSD/NetBSD. Without openpty, Expect doesn't
+ see the full pty namespace (ptyX[0-v]).
+
+7/15/96 5.20b16 Nathan Estey <nfe@the-hermes.net> noted that Makefile failed
+ on SunOS when shared libs were enabled due to incomplete dot
+ stripping in lib prefix.
+
+7/6/96 5.20b15 Malcolm Tredinnick <malcolmt@geko.net.au> noted that shared lib
+ has to be installed before building expect. Also noted that
+ ldconfig should be run on Linux 2.0 systems and maybe others.
+
+6/25/96 5.20b14 Tim Mooney provided fixes to obey --includedir and similar
+ configure conventions.
+
+6/25/96 5.20b13 A bug when installing Expect using new _installed targets.
+
+6/24/96 5.20b12 Numerous complaints from Solaris users about shared libraries.
+ Unfortunately, no one is giving me configure-ready fixes so
+ (and Tk's configure seems to have bugs as well) so fixing
+ these is like throwing darts.
+
+ Stan Brown <stanb@netcom.com> noted noidle example broke when
+ fed "-".
+
+ Gordon Irlam <gordoni@cygnus.com> noted typo in install-sh.
+
+ David Sheinberg <sheinb@bcmvision.neusc.bcm.tmc.edu> noted no
+ args test for spawn -open/leaveopen.
+
+ Misc patches from Tim Mooney to pacify much of gcc -wall.
+
+ Kayvan Sylvan insists Linux stty reads from stdin so added
+ hardcoding to configure.in for that. In xkibitz, Linux stty
+ -raw didn't disable all post-processing. How odd that it is
+ not a problem in interact. In the meantime, added extra stty
+ to xkibitz to do what was missed.
+
+5/30/96 5.20b11 Kayvan Sylvan <kayvan@sylvan.com> noted quoting bug in
+ autoexpect.
+
+5/22/96 5.20.b10 Patches from Larry Virden in Makefile.in and exp_int.h
+
+5/20/96 5.20.b9 Too many substitutions in configure caused sed failures on
+ DEC (limit 99) and HP (100). Commented out definitions
+ that weren't absolutely critical. Hopefully, this gets us
+ under the limit but can't be sure since there's no easy way
+ of knowing.
+
+ Numerous mods from Mark Diekhans to support clist-style ptys
+ on SCO OpenServer. (He says SVR4 ptys are broken on that
+ platform.)
+
+ Simon J. Gerraty <sjg@zen.void.oz.au> says that write() returns
+ 0 inside of exact_write on SunOS. This is outside the SunOS
+ spec so of course we have no idea what's going on. So I added
+ code to try and recover from (or at least warn of) this.
+
+ Tom Tromey unified decls of errno to #includes.
+
+5/13/96 5.20b8 Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu> pointed out
+ backwards stty test - this would have corrupted every platform!
+ He also pointed out that alpha-dec-osf3.2 (3.2c) complained
+ too many args to sed. Someone earlier said similarly about
+ HPUX 10, but I assumed it was the quotes in the weird stty
+ flag I was passing, so that "fix" wasn't. GNU sed has no
+ problem, but obviously this is not sufficient for many people.
+
+5/10/96 5.20b7 Renamed/numbered versions so that it's easier for others to
+ track.
+
+ Upgraded to autoconf 2.10.
+
+ Matthias Kurz <mk@baerlap.north.de> noted Makefile problems
+ with final Tcl7.5.
+
+ Blair Zajac <blair@gps.caltech.edu> noted configure mishandled
+ stty defaults on HP and shared lib must be installed executable
+ on HP.
+
+ autoconf insists on adding -O to CFLAGS when using gcc. Ack!
+
+3/23/96 5.20b1 Beta release 1 of Expect for Tcl 7.5.
+
+ Michael Hunter <mphunter@qnx.com> provided misc mods for QNX.
+
+ Various people reported problems with IRIX. Removing from the
+ stty list fixed the problem. Similar problem with Solaris.
+
+ Added explicit close to autoexpect. Added a mechanism for
+ enabling conservative mode after script is generated.
+
+ Hal Schechner <hal-j@netusa.net> pointed out passwd.cgi must
+ meet passwd's requirement that it not be run by an unrelated
+ user. Easy enough - just do an su first.
+
+3/26/96 5.20a5 Alpha release 5 of Expect for Tcl 7.5b3.
+
+ Added example passwd.{html,cgi} to change a password.
+
+ Many fixes from Stephen Williams <steve@icarus.com>
+ and Jonathon Kamens for Makefile and configure.
+
+3/22/96 5.20a4 Alpha release 4 of Expect for Tcl 7.5b3.
+
+ Added version number to lib directories (POTENTIAL
+ INCOMPATIBILITY).
+
+ Revised gethostbyaddr example - evidentally hadn't worked for
+ some time!
+
+ Jan Nijtmans <nijtmans@nici.kun.nl> provided pkgIndex.tcl.in.
+ Renamed Exp_Init to Expect_Init to support package cmd.
+ Provided #define so that Exp_Init will continue to work.
+
+ Revised exit handling so that it works if Expect is dynamically
+ loaded.
+
+ aclocal.m4 Patches from Tom Tromey.
+
+3/15/96 5.20a3 Alpha release 3 of Expect for Tcl 7.5b3.
+
+ Edward Haletky <elh@astroarch.com> noted that Machten required
+ inclusion of types.h in exp_tty_in.h.
+
+ Added various patches from Rob Savoye. One incompatibility
+ is that the static lib now ends with the version number.
+
+ Added support for TCL_SHLIB_{LD_LIBS,VERSION} in Tcl b3.
+
+ Jonathan Karges <J.Karges@dkfz-heidelberg.de> found that clib
+ was timing out immediately on -1.
+
+3/6/96 5.20a2 Alpha release 2 of Expect for Tcl 7.5b2.
+
+ Leland Joseph <leland@tec.tetd.bellcore.com> noted
+ expect-tests.exp exceeds the 14 character filename length.
+
+ Added config.{sub,guess} to support AC_CANONICAL_....
+
+ Rewrote much of aclocal, configure.in, and Makefile.in
+ to handle Tcl/Tk config.sh files and shared/dl support.
+
+ Simplified varargs/stdarg mess for Expect's C library.
+
+ Threw away closetcl junk. No longer required because
+ Tcl finally started doing close-on-exec.
+
+ Incorporated various fixes from Tom Tromey at Cygnus.
+ See ChangeLog for details.
+
+ Added require/provide support.
+
+ Rejiggered event handling to support new Tcl_File interface.
+
+ Removed libexpectk. Because event loop was moved into Tcl, it
+ is no longer necessary for it to be different than libexpect.
+
+ Removed all support for earlier versions of Tcl and Tk.
+
+ Numerous misc patches from Paul Eggert <eggert@twinsun.com>
+ most to support Tcl 7.5.
+
+ Arnold Robbins supplied yet another patch to fix earlier
+ problem noted by Hume Smith.
+
+ David Engel <david@ods.com> reported problem with Linux dumping
+ core. CenterLine, of course, immediately found the problem -
+ uninit'd lowercase buffer.
+
+ Peter Haggerty <haggerty@borg.lib.vt.edu> noted that his Next
+ died in cron. It seems that Next doesn't support O_NOCTTY
+ (even though the man pages says it does) and so during pty
+ testing, control terminal would get allocated and then kill
+ the process (by generating a HUP) when deallocated. Avoid
+ by ignoring HUP when doing pty testing on such machines.
+
+1/3/96 5.19.0 Fixed bug that made expect report wrong string when using
+ a terminating anchor in a positive-length glob match,
+ reported by Graham L. Randall <grandall@nit.airtouch.com>.
+
+ Added rlogin-display to included examples. rlogin-display
+ automatically propagates your $DISPLAY when you rlogin.
+
+ Hume Smith <hclsmith@localhost.isisnet.com> noted problem
+ with day of the week calc at year end/start. Arnold Robbins
+ supplied fixes.
+
+ Jonathan Kamens provided fix to make sync byte reads
+ recover from EINTR.
+
+ Henry Spencer noted errant line of spaces in Makefile.
+
+10/21/95 5.18.1 Began adding support for tcl7.5a1/tk4.1a1. (not finished!!)
+ - Make aclocal understand new Tcl/Tk directory layout
+ for finding tclInt.h and private libraries.
+ - Added support for Tcl_AsyncReady.
+
+ Paul Townsend <aab@aab.cc.purdue.edu> noted that distclean did
+ not remove some config cruft. Also recommended unsetting
+ M*FLAGS that cause make called from configure to fail.
+
+ Various fixes from Cygnus. See Changelog.
+
+ Deleted "-" before rm in loop in deinstall in Makefile as per
+ Doug Claar <dclaar@hprtnyc.ptp.hp.com>. Doug also found prob
+ involving recent STTY fix. Symptom was that pty wasn't
+ correctly inited in cgi scripts on HPs - and Cray pty support
+ blew up entirely.
+
+ Added exp_ prefix to tests so that they can be run with other
+ extensions.
+
+ Seth Ornstein <pp001465@pop3.interramp.com> noted bug in the
+ way rftp detected symlinks.
+
+ Upgraded to autoconf 2.4. This fixes a bug in AC_PROC_CPP
+ which blew up when CPP was defined in the environment. Noted
+ by John Pfuntner.
+
+ Jonathan Kamens noted that library didn't check return pipe()
+ return value.
+
+ Added vrfy example.
+
+ Przemek Klosowski <przemek@rrdjazz.nist.gov> Irix 6.0 fails
+ to use ptys that have been used by someone else. SGI admitted
+ this is a bug and the solution is to upgrade to 6.1.
+
+ Yoad Grinberg noted "expect -timeout" mistakenly ate next arg
+ as pattern.
+
+8/24/95 5.18.0 Wayne Christopher noted that the way exp_eval_with_one_arg
+ modifies the original argv makes the ICEM Tcl compiler unhappy
+ so I rewrote it to avoid that.
+
+ Ian Zimmerman <itz@rahul.net> found that a braced arg list of
+ a single pattern beginning with a \n caused expect to reeval
+ for multiple args twice. I added a -nobrace flag that expect
+ and/interact can use internally to prevent this.
+
+ Florian La Roche <florian@jurix.jura.uni-sb.de> noted a few
+ glitches in the way -ltcl was searched for in aclocal.
+
+ Joachim Posegga <posegga@ira.uka.de> noted lack of Tcl internal
+ includes should be an error during configure.
+
+8/10/95 5.17.8 Martin Wunderli <wunderli@baloo.limmat.net.ch> found missing
+ quote in config.
+
+ Danny Faught noted problems in Makefile when passing STTY defn
+ with quotes. Created another a STTY-less CPPFLAGS for cases
+ where additional reexpansion occurs.
+
+ Danny Faught noted bug in error handling for checking
+ permission problem with /tmp.
+
+8/1/95 5.17.7 Todd Rimmer <trimmer@mantis.ssw.com> noted that HP 10 with
+ optional streams package has both PTYM and PTMX which conflict
+ in pty_termios.
+
+ Rainer Wilcke provides fixes: scripts not listed as dependency.
+ distclean target used Makefile after deleting, and many fixes
+ to man pages.
+
+ Saad Mufti <mufti@hobbit.pls.com> noted bug in how C library
+ handled polling (when handling multiple fds).
+
+ Jeff Bowyer noted more autoexpect bugs.
+
+7/22/95 5.17.6 More features added to autoexpect (now version 1.3).
+
+ Sanjay <sanjay@clef.lcs.mit.edu> noted bug in TCLH config macro
+ which caused it to use 7.3 instead of 7.4.
+
+ Rodney Barnett <rlb@us.teltech.com> noted expectd.proto had a
+ few refs to interact_out where it should've had expect_out.
+
+ Terry Rhodes <tbr@88open.org> noted that Expect returned a 0
+ exit status upon syntax error unlike tclsh and wish.
+
+ Fred Obermann <fredo@conan.ids.net> noted that Unixware 2.01
+ native development tools don't permit configure to find memcpy
+ because memcpy is handled specially by the compiler and it
+ complains when it finds configure's default test with no args.
+ Changed to a hand-crafted test with args.
+
+7/12/95 5.17.5 Jeff Bowyer <jbowyer@muni.cz> noted minor bugs in autoexpect.
+
+ Rob Saul <robs@sco.com> noted that configure failed on SCO OSR5
+ because trap requested by Cygnus (to allow config in bg) used
+ higher traps than SCO sh knows about.
+
+ Changed "can't happen" to "xmkmf is broken" when configure
+ fails to compile simple C-Tk program.
+
+ John H. Chauvin <jchauvin@netcom.com> noted exp_tty_current and
+ cooked raised multiple def errors on SGI 5.3 with native cc.
+
+7/9/95 5.17.4 Wolfhardt Lotz <s11@blue.lrw.uni-bremen.de> noted Solaris
+ doesn't do case-insensitive man page lookups so I lowerized
+ the beginning of the .SH lines.
+
+ Henry Spencer noted unbackslashed quotes in the autoexpect
+ boilerplate.
+
+7/3/95 5.17.3 Modified VARARGS decls to support new Tcl 7.4 definitions.
+
+ Fine-tuned aclocal so that it would prefer later versions.
+
+ Added autoexpect example and man page.
+
+6/30/95 5.17.2 select-based dsleep() was returning an internal expect-style
+ return code instead of a Tcl-style.
+
+6/30/95 5.17.1 Kannan Varadhan <kannan@isi.edu> noted aclocal didn't
+ look in right directories to find Tk.
+
+6/30/95 5.17.0 Modified regexp interfaces to support Tcl 7.4b4.
+
+ Mods from Tony Isles <ittony@traf.com> for Sequent Dynix/ptx
+ V2.1.5 (which is really old).
+
+ Michael Schumacher <hightec@rz.uni-sb.de> noted that Solaris
+ 2.4 header files require __EXTENSIONS__ for all sorts of
+ traditional but non-standard definitions.
+
+ Modified aclocal to support new Tcl/Tk library names.
+
+ George Forman <forman@cs.washington.edu> requested support in
+ C lib for fds that already exist. I added exp_spawnfd.
+
+ Fixed bug preventing signal rearming on Linux (using SV-style
+ signal handling).
+
+ Wayne Christopher <wayne@pmac.icemcfd.com> noted missing interp
+ in call to exp_error.
+
+ Added null support to interact's exact matching.
+
+ Bruce Jerrick noted INSTALL was being used rather than
+ INSTALL_PROGRAM/DATA.
+
+ Dennis Ferguson <dennis@mci.net> noted that on Solaris 2.4
+ close(pty) occasionally returns EINVAL.
+
+ Added tests so that if we can't get a pty, we can give the user
+ much more help with what to do about it.
+
+ Steven Byrnes noted that Solaris has replaced TIOCCONS with
+ SRIOCISREDIR interface.
+
+ Technically speaking, interact shouldn't do buffer-shuffling
+ but I've added as a fail-safe mechanism to catch people who
+ use preposterous patterns.
+
+ Alan Heckert <heckert@tiber.nist.gov> noted missing decl in
+ Convex pty support.
+
+ Fixed all expectk examples for Tk4.
+
+ Bryan S. So <so@cs.wisc.edu> noted that interact -o eof failed
+ if an unbuffered pattern was partially in progress.
+
+ Added -timeout flag to expect command to override timeout var.
+
+ John Pfuntner <pfuntner@VNET.IBM.COM> noted that OpenMVS did
+ not notice @ inside of Makefile SETUID macro as suppression
+ but instead treated it as part of the program name.
+
+ Jim Porter <James.W.Porter@att.com> noted that exp_free_i freed
+ the variable name even if not allocated.
+
+ Yet more mods to aclocal and various .in files from Rob Savoye.
+
+4/21/95 5.16.3 Matija Grabnar <Matija.Grabnar@ijs.si> noted that sleep maxed
+ out after about 36 minutes. Turned out to be a poor assumption
+ in some interfacing code.
+
+4/19/95 5.16.2 rbd <uport@netcom.com> noted tcl_RcFileName multiply defined
+ when compiling with Tk4.
+
+4/16/95 5.16.1 Robert Nicholson <robert@steffi.dircon.co.uk> noted NextStep's
+ sys/wait.h is not POSIX-like so WNOHANG fails to get a defn.
+
+ Alexandre Rafalovitch <arafalov@socs.uts.edu.au> discovered
+ example on dislocate man page didn't work. I fixed it.
+
+4/8/95 5.16.0 gcc 2.3.3 complains about internal errors so I figure: time to
+ upgrade. Switched to Cygnus 2.6-95q1. Works now but now
+ complains about wait status. I trashed all the gory wait
+ status configure code and adopted autoconf's suggestion about
+ refusing to use sys/wait.h if not POSIX.1 compatible. Nice!
+
+ Jeffrey C Honig <jch@nr-tech.cit.cornell.edu> requested a -gmt
+ flag for timestamp command.
+
+ Chuck Ocheret <chuck@gigadactyl.com> noted that expect -pty
+ fails. Problem is that Tcl's exec blindly closes all the fds
+ between 3 and its own highest fd. See comments in code.
+
+ Loris Caren <loris@caren.demon.co.uk> noted eof in fg bombs on
+ Linux. Turns out to be analogous to eof in bg problem fixed
+ in 5.14.0.
+
+ Upgraded to autoconf 2.3. Continued making changed to config
+ script to take advantage of autoconf 2 capabilities.
+
+4/1/95 5.15.4 Steve Simmons noted .x remnant from earlier dir install proc.
+
+3/31/95 5.15.3 Forgot to export TCLHDIR defn when configuring debugger.
+
+3/29/95 5.15.2 Steve Simmons <scs@aisinc.com> noted Makefile multiple defined
+ distclean and it might be nice to provide aclocal.m4 even
+ though it isn't normally used.
+
+ cevans@resdev1.ppco.com added prompts to passmass for AIX.
+
+3/27/95 5.15.1 Fixed tkterm script - inadvertently left tic debugging on.
+ Also add support for Ctrl-space and Ctrl-@ as requested by
+ Zbigniew Wieckowski <wieckows@cs.umn.edu>.
+
+ Larry Virden asked that configure also check for .so libs.
+
+3/23/95 5.15.0 Everitt Beers <ebeers@scf.usc.edu> noted that Linux doesn't
+ support kill -STOP 0. Changed 0 to [pid].
+
+ zhengping (z.) you <you@bnr.ca> found bug where a bg expect did
+ not rearm a spawn id after a first bg expect (and another one)
+ to clear it.
+
+ Elliott Wolin <wolin@physics.wm.edu> noted that tkterm
+ complained if tic wasn't found. I'll have it override the
+ user misconfig in that case. Also noted that interact failed
+ on AIX. Evidentally, my new config tests for ISC found that
+ AIX looked just like it. Added additional test for tcsetattr
+ to distinguish them.
+
+ Rob Savoye asked for Dbg config.in to be distributed. Rob
+ supplied numerous other mods: install-sh replaced install.sh,
+ mkinstalldirs, testsuite mods, new aclocal.m4, support for
+ recursive make.
+
+ Fixed bugs in configuration of debugger.
+
+ Disabled configure's file-caching.
+
+ Kannan Varadhan <kannan@isi.edu> noted incorrect diag reporting
+ TCLHDIR in configure.
+
+ Marty Olevitch <marty@howdy.wustl.edu> noted that DEC Alpha
+ did not sleep correctly because configure didn't find sleep
+ and found poll (which is broken). Problem turned out to be a
+ bug in autoconf's AC_CHECK_FUNC. Got patch from Jim Meyering
+ <meyering@comco.com>
+
+ Fixed config probs for Edward Huie <huie@net.com> on Mac SE/30,
+ System 7.1, Tenon Intersystems' MachTen 2.1.1-G (BSD 4.3 on
+ Mach kernel) and MachTen X11R4 3.1.
+
+ Moved libraries forward in configure to allow for AC_CHECK_FUNC
+ to succeed when funcs are in other libraries.
+
+ Made configure test for Linux and unset CFLAGS=-g if so.
+
+2/25/95 5.14.3 Larry Virden noted configure was missing brackets in raw shell
+ cmds evidentally due to m4 interpretation.
+
+2/24/95 5.14.2 Larry Virden noted configure was not correctly rewriting from
+ --(exec-)prefix. Due to new autoconf. Also noted glob was
+ finding tclX directory.
+
+ Hal Peterson noted that because configure now actually attempts
+ a link before using a library, the code to check for -ltk would
+ have to worry about all the other utility libraries first.
+
+2/23/95 5.14.1 Hal Peterson noted that configure.in checked incorrectly for
+ tcllib.
+
+2/22/95 5.14.0 Jamal <root@lonestar.tlug.org> noted Linux has tic in a
+ different place than on my system - affected tkterm script.
+
+ Xiaokun Zhu <xiaokun@stats.gla.ac.uk> noted problem on DEC
+ Alpha OSF/1.3 evidentally due to backwards decl of index macro.
+
+ Greg McFarlane <gregm@nms.otc.com.au> noted that large args in
+ send cmd cannot be passed blindly to exp_error.
+
+ david d `zoo' zuhn <zoo@armadillo.com> requested modifying
+ configure so that it did not require Tcl/Tk to be built - only
+ configured. This means that it may not find installed
+ libraries. Hopefully, this won't cause anyone problems but its
+ not my preference.
+
+ Fixed error which caused spurious eof when changing patterns
+ in expect_bg.
+
+ Moved to autoconf-2.1 and m4-1.4. Rewrote a LOT of the config
+ file. Finally got my hands on an ISC box and fixed configure
+ for that.
+
+ Tony Booker <tb@sequent.com> provides mods for Sequent ptx 2
+ and 4.
+
+ Jeffrey Friedl <jfriedl@nff.ncl.omron.co.jp> provided fixes for
+ timezone handling in config and exp_strf.c.
+
+ David Schmitt <dschmitt@netcom.com> noted that library did
+ not detect eof on HP. I didn't think this was necessary for
+ read() but it evidentally is. I added the support for raw fds
+ although it is not obvious to me how to do it for FILEs.
+
+ James Carter <jimc@math.ucla.edu> noted expect_after couldn't
+ worked in the exp_bg because I had accidentally written BEFORE
+ instead of AFTER when checking the cases. He also found that
+ the eof body could be trashed in an exp_bg.
+
+ Ousterhout apologized for the Tcl7.4 change I noted in 5.13.1
+ and said he will undo it.
+
+ Eric Frias <efrias@vt.edu> found library bombed after timeouts.
+ exp_match_end was not updated - which makes sense since there
+ was no match - however the following expect call assumed that
+ exp_match_end was meaningful in order to do its buffer
+ shuffling.
+
+ Jonathan Kamens supplied new configure test for REARM_SIG after
+ noting old could fail if limit prevented creation of core file.
+ He also noted REARM_SIG had accidentally been commented out
+ of cf file.
+
+ Vincent D. Skahan <vds7789@aw101.iasl.ca.boeing.com> noted that
+ Apollo's stty reads stdout and doesn't complain if its bogus.
+
+ Yoad Grinberg <grinberg@vnet.ibm.com> noted that SIGCHLD does
+ not work for forked processes, only spawned processes. Fixed
+ this and added counting to make sure none get lost.
+
+ Hal Peterson contributed mods for Unicos. He noted that
+ configure should be more careful adding libs to the link line.
+ On the Cray, non-existent libs generate warnings which are not
+ detected by configure but which annoy make.
+
+ Bela Gazdy <bela@euch3e.chem.emory.edu> noted /etc/resolv.conf
+ misspelled in kibitz.
+
+ Rainer Wilcke noted that "send -null/break" mishandled return
+ code, and these and send/expect_tty were not in man page.
+
+ Dvorak example was missing -- in send -.
+
+1/12/95 5.13.2 Peter Wassenaar <peterw@stack.urc.tue.nl> noted that kibitz
+ didn't work on AIX. My fixcat script assumed that AIX's cat
+ was like HP's cat - buffered by default.
+
+1/7/95 5.13.1 Marc Bouron <mbouron@lhr-sys.bru-ro.DHL.COM> noted I forgot to
+ add virterm to distribution.
+
+ Marc W. Mengel <mengel@dcdmwm.fnal.gov> noted that configure
+ must be run in the foreground due to the stty tests. Added
+ this to documentation.
+
+ Modified interpreter to account for the change in Tcl7.4 which
+ forces Tcl_RecordAndEval to call Tcl_GlobalEval instead of
+ Tcl_Eval.
+
+ Changed ptys to be initialized based on current tty setting
+ rather than original tty setting.
+
+ Stephen Melvin <melvin@zytek.fr> noted that set -e is the real
+ problem with ash (see 5.13). I bet "[" is returning a value
+ and triggering it. It appears that the script can live without
+ the set, so out it goes.
+
+ Braun Brelin <bbrelin@netcom.com> noted pipe allocs in spawn
+ could fail with meaningless error message.
+
+12/15/94 5.13.0 Synchronize with appearance of "Exploring Expect". This
+ distribution corresponds to the book both in description of
+ Expect and in containing all the substantive examples.
+
+ Graham Mark <gam@lanl.gov> noted that his Cray (Unicos 7.0.6.1)
+ didn't recognize TCSETCTTY. Since this was in some Cray-
+ specific code, I guess Unicos must have changed some .h files.
+ I made it include either termios or termio. It, at least,
+ works on our Cray (Unicos 8.0.2.4).
+
+ Robert Withrow <witr@rwwa.com> noted that FreeBSD 1.1.5.1
+ supplied union wait but waitpid doesn't use it! So I modified
+ configure to be smarter. He also noted that its /bin/sh is
+ really ash which blows up on install.sh. It appears that it
+ doesn't handle uninitialized parameters correctly. I'm not
+ going to fix this because having a broken /bin/sh is so awful
+ probably other things are breaking too. He did note that it
+ worked if he switched to bash or the native install, but that
+ blows the whole point of install.sh - that we have found too
+ much variation in native installs. Rather than try and figure
+ out everyone's variation, we'd like to simplify our life and
+ use this common, simple-to-understand sh script.
+
+ Added more example scripts: Adrian Mariano's virterm (like
+ expect_term but without relying on Tk), gethostbyaddr, and
+ expectd.proto for telnet daemon.
+
+ Matt DiMeo <mdimeo@brooktree.com> noted that expect_background
+ failed to detect eof on HP. I had forgotten to pass the mask.
+
+ Josef Sachs noted that expect_background put Tk's event handler
+ in an infinite loop if it was listening to a pipeline that was
+ killed. I had aborted the cleanup procedure if Tcl's close
+ reported an error. That was a mistake.
+
+ Rick Lyons <rick@razorback.brisnet.org.au> noted a bug. C lib
+ expect would turn a normal read into a poll if remtime reached
+ zero on the nose.
+
+ Added ResetResult to Exp_Init to clean up diags in Expectk.
+ Made GENFUNCs return -1 on error as per ParseArgv's convention.
+
+11/13/94 5.12.0 Alon Albert noted that in clib, exp_match_end should be init'd
+ to exp_buffer before trying to match the pattern - if the
+ expect doesn't produce a match, exp_match_end is incorrect and
+ will be wrong for subsequent expects.
+
+ Steven Diamond noted that fg expect did not react to a change
+ in an indirect spawn id list if it was just waiting for I/O
+ (rather than looping in exp_continue).
+
+ Wait fix in previous version broke system() whose return value
+ is horribly overloaded.
+
+11/10/94 5.11.0 Stephen Fitzpatrick <sfitzp@cs.qub.ac.uk> noted that NeXT wait
+ macros do not accept int wait status. Switched to using Tcl's
+ detection of wait status type.
+
+ Made log_file -leaveopen leave file id open until close like
+ spawn -leaveopen did.
+
+ Bruce Jerrick <bruce@cse.ogi.edu> noted public include dir
+ wasn't getting created.
+
+ Karl Vogel noted 1) Pyramid has index instead of strchr, strf.c
+ needs sys/time.h instead of time.h in strf.c, needs to call
+ timezone(), and stty reads stdout but usual stty test fails.
+
+ Made expect_out(spawn_id) always be written to assist people
+ who want to log different procs to different files. This is
+ no longer an efficiency problem because interact can do so
+ much more then it used to. Made full_buffer condition write
+ forgotten chars even when full_buffer isn't explicitly
+ specified.
+
+ Bert Robben <Bert.Robben@CS.kuleuven.ac.be> noted that the
+ debugger needs to know about the presence of stdlib.h. I was
+ hoping to avoid this because it's a pain getting configure to
+ call another configure.
+
+ Rainer Wilcke provide several improvements for xkibitz and man
+ page.
+
+10/6/94 5.10.0 Moved example files around. Added password generation to
+ tkpasswd. Created standalone script to generate and set
+ passwords - good for all those adduser shell scripts.
+
+ Rick Cady <rickc@NSD.3Com.COM> found a bug when switching log
+ files.
+
+ Rainer Wilcke <wilcke@esrf.fr> noted that xkibitz died when
+ closing a connection. stdin was mistakenly being closed. He
+ also noted that killing xterms under HPUX 9 requires kill -9.
+
+ Enzo Michelangeli <enzo@airhk.air.org> noted that SCO 3.2.1
+ defined window size structure in ptem.h.
+
+ Josef Sachs <sachs@panix.com> found a bug when calling fg
+ expects repeatedly between bg expects. On the first fg expect,
+ it cached the fact that the filehandler was armed. The next
+ background expect disarmed it but failed to update the cache.
+
+ John P. Rouillard" <rouilj@dstar.iddis.com> provided configure
+ support for --with-{tcl,tk}{lib,include}.
+
+ Mike Figg <figg@pencom.com> noted that man page used old style
+ of continue command.
+
+8/23/94 5.9.1 Adrian Mariano noted it would be useful to have exp_continue
+ not reset the timer. Added flag to support this.
+
+ Morris Gasser <gasser@ksr.com> noted that lowering match_max
+ didn't work (lib was broken too).
+
+ Keith Hanlan provided a fix for exp_exact.
+
+ Added more examples: mkpasswd, tkterm, term_expect.
+
+ Put close_tcl_files in sep file for easier non-Tcl use of clib.
+
+8/21/94 5.9.0 Fixed window handling code - on AIX, termios does not define
+ TIOCGWINSZ. Instead, you have to include ioctl.h. Of course,
+ you have to avoid the trap of including both on OTHER systems
+ such as SunOS 4.1 where the include files conflict!
+
+ Dan MacDonald found that close in async routine caused sync
+ expect to blow up.
+
+ Missed deletion of last line of out macro in exp_inter.c
+
+ Simon Warfield <simonw@bwh.harvard.edu> noted bug in xkibitz
+ help message.
+
+ Fixed exp_background to use global scope instead of current.
+
+ Steve Diamond <sdd@aplcomm.jhuapl.edu> noted that -i "4 5"
+ only used spawn id 5.
+
+ Rob Nagler found yet another bug in log_file when called
+ incorrectly.
+
+ Expectk wasn't creating a window by default.
+
+7/25/94 5.8.1 Made exp_interp external. Users should be able to set this
+ explicitly.
+
+ David Barnett <davidb@cats.ucsc.edu> found that Linux was not
+ getting a controlling terminal. The original test for doing
+ that was based on Stevens and tested in a very nonspecific way
+ for the presence of a Sun via CIBAUD. Replaced this with a
+ more specific test.
+
+ It seems Tcl 7.3 broke my -nostack hack. The top-level interp
+ translates unknown return codes to TCL_ERROR. Sigh. I wish
+ Ousterhout would stop all of those translations. If the user
+ wants them, they can do so themselves, but now they're forced.
+
+ Martin Buchhoz <buchhlz@vnet.ibm.com> suggested adding
+ XKIBITZ_XTERM_ARGS environment variable to xkibitz. He also
+ noted that stty rows/columns support doesn't seem to work on
+ AIX. I haven't yet looked into this.
+
+ Copied 2nd sync mechanism from Expect to C library.
+ Added exp_child_exec_prelude hook.
+
+ Jonathan Kamens noted that "spawn cat;close;wait" returned
+ -1 on AIX and 0 on Sun. This is "correct", however to
+ address this, I added -ignore to spawn and otherwise made
+ signals default. Also added extra information to return value
+ of wait if caused by signal.
+
+ Dan MacDonald <hfvstud@bcarh80a.bnr.ca> noted that exp_continue
+ didn't cause timeout to get reread.
+
+ Ting Tan <utan@cisco.com> noted that when using -b, expect
+ hangs if open brace and doesn't stop in case of error.
+
+ Oops, broke "log_file" with no args.
+
+ Removed -timestamp from documentation. Use "timestamp" command
+ instead.
+
+ Keith Hanlan noted C library didn't test already arrived data
+ before attempting to read more. He also suggested I avoid
+ forcing the user to do save/restores of per-fd globals.
+
+6/24/94 5.8.0 Hubert Halkin <hhalkin@ucsd.edu> pointed out that interleaved
+ expect_bgs and spawns dump core. I had used the exp_f ptrs
+ as handles to TkCreateFileHandler but realloc shuffled them
+ around.
+
+ Rick Lyons <pclink@qus102.qld.tne.oz.au> provided misc. mods
+ for Pyramid.
+
+ Keith Hanlan <keithh@bnr.ca> noted that HP-UX C compiler causes
+ odd behavior in Expect when it is compiled with -O. -g works
+ fine.
+
+ Peter Gasche <zrspg01@compserv.zdv.uni-tuebingen.de> pointed
+ out that Convex 10.2 fails to build. New version of Convex OS
+ added getpty(). Naturally, it differs from old one. Testing
+ is tricky because there is no header file for it. Even worse,
+ the algorithm in the Convex man page is incorrect - it allows
+ you to allocate ptys already in use! Unfortunately, the man
+ page is too vague to allow the reader to see that immediately.
+
+ In contrast to BSD stty, Convex, Mach, and NeXT stty don't
+ complain if redirected to null. I'll just have to hardwire the
+ test in configure.
+
+ Added -nowait flag to wait command.
+
+ Upon suggestions from David Vezie <dv@xnet.ssl.berkeley.edu>:
+ Added -noappend, -open, and -leaveopen to log_file command.
+ Added -leaveopen flag to spawn and exp_open.
+ Modified spawn to close -open immediately.
+ Modified exp_open to close spawn_id immediately.
+
+ Between Jeff Wright <wright@spock.cen.encompass.com>, Brad
+ Skrbec, Arup Mukherjee <arup+@cmu.edu>, and the anonymous
+ Mach support group at CMU, finally got hard answers about Mach.
+ It is no longer supported and there is no intention to provide
+ full POSIX support. Now, at least, I can fix the configure
+ script to understand this.
+
+ Added "unbuffer" example.
+
+ Dana Chee <dana@dino.bellcore.com> provided configure hooks
+ for finding -lnsl and -lsocket.
+
+ Henry Spencer <henry@zoo.toronto.edu> noted timestamp doc did
+ not jive with C defn. Fixed doc and added timezone support.
+
+ Steve Pynes <fb@steve@ucsd.edu> noted that exp_win.c needs
+ _IBCS2 (Intel Binary Compat Standard #2!?!) before it will
+ recognize winsize. He also noted #out was redefined in inter
+ code if using simple_event.
+
+ Fixed defn of "stty cooked" to retain echo setting.
+
+ Bennett Todd noted dislocate's pidfile_read was missing close.
+ He also noted useless bind in tkpasswd.
+
+ Marty Leisner noted that ^C causes xkibitz to exit ungracefully
+ when in interpreter.
+
+ Added yet another sync mechanism (see 5.6) to spawn so that
+ child cannot eof before parent has prepped the pty (only a
+ probably on HPs, of course). I had actually written most of
+ the code, but left it disabled because I hoped that the
+ problem simply wouldn't happen in practice. Alas, Jonathon
+ Kamens found a case where it does.
+
+ Jimmy Aitken <jimmy@pyra.co.uk> noted problem on Pyramid. My
+ original code only looked for /dev/tty##. On pyramid, ptys
+ look like /dev/pts/4. term wants the last two characters, but
+ on the Pyramid, the first of the last two characters can be a
+ / in which case xterm wants a 0. I.e., suffix of /dev/pts/4
+ is "04". xterm fails completely with 3-digit ptys! I sent
+ a suggestion and patch to X Consortium for this and the pid
+ problem - xterm has no way of telling it to which pid to send
+ the SIGWINCH.
+
+ Poul-Henning Kamp <phk@TFS.COM> noted that -lm would make
+ autoconf forget about other libs.
+
+ Ram Bhamidipaty noted I forgot to document sleep.
+
+ Removed disasterous performance with * at beginning of glob.
+
+ Mods from Rob Savoye. See ChangeLog.
+
+ Earnest Hua <eh@c-cube.com> noted expectk.man need wasn't
+ installed.
+
+ Bogus arguments to expectk were not reported correctly.
+
+ Modified clib to catch when user changes match_max between
+ expects on two different fds and then switches back.
+
+ Rewrote timestamp to get rid of 200 char limit.
+
+ Ram Bhamidipaty <ram@xor.epi.wisc.edu> noted NetBSD .9 stty
+ complained "stdout appears redirected, but stdin is the
+ control descriptor". It compares dev(stdout) to dev(stderr)
+ and assumes if they are different then user thinks stty
+ ioctls stdout. This is one case when that assumption is wrong.
+ Fixed fd 2 so it points new 2 and is reset to old 2 if an
+ error occurs. This forced me to remove any diagnostic output
+ from child (in getptyslave) since this now went back to the
+ proc as child output rather than original stderr, sigh.
+
+ Stephan Winokur <swinokur@pinky.trevose.sgi.com> noted that
+ IRIX 4.2 had problems with gcc. While diagnosing, I found
+ PTY_TYPE was used before set. Make doesn't mind (how odd)
+ but I changed it anyway.
+
+ Made send understand "-null". Deprecated "-0".
+
+ Made Expect read .expect.rc from DOTDIR if present.
+
+3/30/94 5.7.0 Removed alpha status.
+
+ Added $(EVENT).o to library.
+
+ Finally deleted old shar file. Revised README.
+
+3/22/94 5.6.3 Phil Moore <phil@signals.geol.scarolina.edu> noted termios.h
+ should not come from sys even if it exists. (SGI doesn't have
+ sys/termios.h.)
+
+3/21/94 5.6.2 Paul Kinzelman <pkinz@cougar.tandem.com> noted that I forgot
+ to remove -update from documentation.
+
+ Fixed interact's -i so it understands indirect spawn ids.
+
+3/21/94 5.6.1 expect_background randomly failed. I forgot to save Tk's
+ event mask so occasionally events were incorrectly classified
+ as eof.
+
+ Added -buffer to expectk and made "nobuffer" the default so
+ scripts are read in much faster.
+
+3/15/94 5.6.0 Added cat_buffers marker to avoid "catu" option to scripts.
+
+ Got temporary use of an evaluation copy of TestCenter.
+ Promptly found several memory leaks. Oops.
+
+ Added a synchronization mechanism to spawn so that user cannot
+ send to pty before it is init'd. This also deals with the HP
+ trap more simply. Removed extra open added in 5.5.1. While
+ working on this, it occurred to me stty needs to temporarily
+ disable trap. Added exp_slave_control so that C programmers
+ can get to it portably.
+
+ Added "expect -ex" to documentation.
+
+ Fixed winsize bug on Solaris.
+
+ Added functions to allow user flexibility closing fds in child.
+
+3/8/93 5.5.1 Integrated bug fixes from Arnold Robbins <arnold@skeeve.atl.
+ ga.us> for his own strftime code.
+
+ Rob Savoye passed back a patch from OSF to cast ptsname.
+
+ Added a test for cat. R.K.Lloyd noted HP failed pid test.
+ Turned out to be another bug related to pty-trapping. The test
+ of course, was doing something that a user would never do.
+ Hope this doesn't break other HPs. Pty trapping is becoming
+ less and less clear to me. Ioctls generated by slave look like
+ modem ioctls. Added an artificial open because different
+ versions of HP's stty execute differing numbers of ioctls.
+ In test script, changed each cat to cat -u.
+
+2/17/93 5.5.0 Began a test suite based on Ousterhout's model: make test
+
+ Added passmass man page.
+ Added decl of exp_tty_original to pty_sgtty.c.
+ Added error_spawn_id
+
+ Alon Albert <al@mercury.co.il> provided a bug fix for new
+ buffer handling code in C library.
+
+ Fix fd leak related to spawn -open.
+
+2/7/94 5.4.0 Some installation improvements from Rob Savoye and Owen Rees.
+
+ Bug in handling empty string match - crept in recently.
+
+ Finally fixed longstanding oddness: stty -raw reset echo.
+
+ Made spawn close all file descriptors. Added exp_open command
+ to get old effect.
+
+1/26/94 5.3.5 Made rftp use /bin/ls to avoid -F from people's aliases.
+
+ Initialized auto_path.
+
+ Fixed exp_version so it fails if the major #s are not equal
+ (which is what the man page said).
+
+1/18/94 5.3.4 Jim Meyering <meyering@idefix.comco.com> gave config fixes
+ of X handling on Irix-4.0.5 and suggested that tknewsbiff
+ observe DOTDIR.
+
+1/18/94 5.3.3 Kevin Short <short@gdc.com> noted some remaining use of malloc
+ and free instead of ck versions.
+
+ Initialize tcl_interactive to 0 while processing -c flag to
+ avoid unreliable handling of unknown proc.
+
+1/17/94 5.3.2 Jeffry Abramson <jra@hrcms.att.com> noted that "spawn -pty"
+ hung on an HP. Problem was trapping was enabled so as soon
+ as I tried to open the slave, Expect blocked waiting for ack!
+
+1/14/94 5.3.1 Forgot to delete a bad call to strcat in exp_internal.
+
+1/13/94 5.3.0 Added -info flag to log_file, log_user, exp_internal, and
+ strace, so you could get original args back out.
+
+ Wrote tknewsbiff script (and was extremely pleased).
+
+ Fixed rftp. I must have broke it when I changed to using Tcl's
+ new switch cmd. Also sped it up by replacing split/join
+ nonsense with a single regexp.
+
+ Danny Faught <faught@convex.com> noted that glob patterns
+ returned shortest matches. While fixing this, found that glob
+ patterns ending in $ were broken, too.
+
+ Massaged libraries and include files. The include file for
+ using Expect with Tcl or Tk is now expectcl.h. libexpect.a
+ now suffices for using Expect's funcs with C or Tcl.
+
+ Add all the features from Expect into C library including
+ null and full buffer matching. Added exp_buffer (_end) and
+ some other variables to support fd multiplexing better.
+ Made unmatched chars from previous expects remain for future
+ matches.
+
+ Chen <johnny@e0sun3.ccl.itri.org.tw> found bug in exp_pid when
+ -i had no arg.
+
+ Rewrote expect_bg, after, and before so they all handle args
+ the same. Interact and all the expect variables now handle
+ indirects. exp_bg now handles -brace flag.
+
+ Geoff Bullen <geoff@itx.nsg.com.au> noted that interact put
+ terminal into raw mode even if stdin was redirected.
+
+ Rob Savoye provided more configure mods to better find Tcl/Tk.
+
+ Fixed bug in wait that didn't close down "busied" fds.
+
+ Kazuro Furukawa <furukawa@apricot.kek.jp> provided a better
+ default for SHORT_BINDIR in the Makefile and noted that DEC
+ doesn't understand "test -x".
+
+12/3/93 5.2.0 Recent fix was buggy and blew up when eof case still had data
+ in buffer.
+
+11/23/93 5.1.4 At request of Rod Beckwith <rodb@slugo.corp.sgi.com> fix some
+ minor things to which SGI cc was sensitive.
+
+ Fixed bug in dvorak script where eof could occur in nested
+ interact, upsetting original interact.
+
+ Forgot to change -flush to -nobuffer in man page.
+
+ Added some more places to search for X11 for Jeff Moore
+ <jbm@internet.sbi.com> note.
+
+ Added yet more fixes and notes for NeXT for Brad Skrbec
+ <skrbec@motcid.rtsg.mot.com> who found that NeXT has POSIX
+ include files but NOT the functions that go with them. Sigh.
+ Needless to say, configure is thrown off by this.
+
+11/14/93 5.1.3 John Pierce <jpierce@chem.UCSD.EDU> noted several declarations
+ that AIX's cc couldn't handle include a struct with same elt
+ name at two different levels. Also _IO is declared twice
+ in AIX include files but only checked once.
+
+ Fixed bad args in exp_spawnl call in chesslib examples. Can't
+ imagine how it ever worked before.
+
+ Richard Weidner <richard@cicero.jpl.nasa.gov> found a bug in
+ configure (test always treats a bare string as true!) that
+ caused NeXT to be declared as POSIX.
+
+ Fixed two bugs in Tcl_StringMatch2. One caused glob ranges to
+ succeed when they shouldn't. Another was how malformed ranges
+ are handled, and came right from Tcl. Reported to John.
+ Switched Expect library to use T_SM2 from Expect itself.
+
+ Blair Zajac <blair@olympia.gps.caltech.edu> noted expectk used
+ CLFLAGS instead of CFLAGS.
+
+ Forgot to fix mishandling of parens inside of alternation in
+ interact.
+
+11/9/93 5.1.2 Added "null" keyword and remove_nulls command to allow matching
+ ASCII 0 in expect/interact.
+
+ Rob Nagler <nagler@olsen.ch> noted that expect_background
+ failed if pattern didn't consume all data. event handler
+ knows nothing about data already arrived but not processed.
+
+ Made Expectk understand --
+
+11/8/93 5.1.1 Fixed yet another bug in setting expectk's argv0.
+
+11/6/93 5.1.0 Provided support to work with Tcl 7.[0-1] and Tk 3.[3-4].
+
+ Pasi Kaara <ppk@atk.tpo.fi> found an off-by-one in the buffer
+ shuffling when buffers fill up during an expect.
+
+ Changed \\\$ to \\$ in patterns that search for literal $.
+
+ Added "spawn -pty" support for xterm -S.
+
+ Fixed yet another argv problem in Expectk. When run using
+ expectk explicitly, script name was left in argv.
+
+ Fixed system command's return value to match exec new style.
+
+11/1/93 5.0.4 Mark Davies <mark@comp.vuw.ac.nz> noted that BSD4.4 sysconf
+ returns -1 (a bug). Rewrote to avoid requiring this info.
+ Switched from from explicit refs of sys_errlist to Tcl's
+ strerror.
+
+ As per Adrian Mariano <adrian@cam.cornell.edu>, added exp_sleep
+ command primarily to allow sleeping by sub-second intervals.
+ Also avoids exec overhead. Not yet documented.
+
+ Kartik Subbarao <subbarao@concorde.fc.hp.com> noted that on
+ HPUX 9, SC_OPEN_MAX should be ifdef'd on itself rather than
+ HAVE_SYSCONF.
+
+ Karl Vogel <vogelke@c-17igp.wpafb.af.mil> noted Pyramid
+ didn't like varargs included twice in exp_command.c.
+
+ Deleted expect_version variable (was never documented) and
+ deprecated expect_library to be exp_library for consistency.
+
+10/16/93 5.0.3 Lou-Salkind@deshaw.com found interpreter() could stomp past end
+ of input array. Same problem in debugger.
+
+ Bud Bach noted init.tcl wasn't being sourced, and Makefile
+ broke if all scripts were commented out.
+
+ Added interesting highlights and bindings to tkpasswd.
+
+ Made Makefile look for -ltk if libtk.a doesn't exist.
+
+ Rick Sladkey pointed out that -re patterns to look for $ should
+ "\\\$".
+
+ R.K.Lloyd noted config doesn't see prototypes with K&R cpp.
+
+10/8/93 5.0.2 Bud Bach noted tcl_interactive was not set.
+
+10/8/93 5.0.1 R.K.Lloyd noted various problems, some related to being on an
+ HP when a lot of #ifdefs kicked in.
+
+10/7/93 5.0.0 Added expect_background. In the Tk environment, this registers
+ actions to be called upon receipt of a pattern from a process.
+
+ Renamed "debug" as exp_internal" and made debugger available
+ as "debug" and "exp_debug".
+
+ Milan Gupta <mbg0@bunny.gte.com> noted that system() (at least
+ on his HP) hangs when SIGCLD is ignored.
+
+ <jason@vicor.com> noted that Tcl's exec command doesn't bother
+ to close fds, so force them with close on exec.
+
+ Renamed "continue -expect" as "exp_continue". "continue
+ -expect" will continue to work, just won't be documented. It's
+ just too dangerous when you start mixing extensions.
+ Renamed "return -tcl" as "inter_return". Had to do something
+ to avoid random return values from matching "-tcl". This
+ design was just wrong. Surprising that it never bit anyone.
+ Renamed "expect_version" as "exp_version" just to continue
+ this regularity.
+
+ Protected initial fd_new's with isatty so disconnect doesn't
+ lose redirected fds.
+
+ Allowed DFLT_STTY to be omitted entirely. Apollo doesn't need
+ it.
+
+ Modified fork to fail on failure instead of returning -1. This
+ made spawn failure match disconnect failure.
+
+ Dan Hyde <drh@citi.umich.edu> noted missing arg in exp_error.
+
+ Jerry Whelan <guru@stasi.bradley.edu> noted -buffer was botched
+ in man page. Hal Peterson noted that bug in man page caused
+ groff to choke.
+
+ wait now returns {pid, spawn_id, 0|-1, status (or error msg).
+ errorCode is now set if appropriate. wait -i -1 waits for any.
+
+ Propagated winsize to pty.
+
+ Documented "-open".
+
+ Quentin Stafford-Fraser <Fraser@europarc.xerox.com> noted that
+ interact -u was broken.
+
+ Fixed interact's default actions "return"/"interpreter" to be
+ writable. Removed ability to set default eof/timeout. Removed
+ dash from same.
+
+ Rewrote trap to use Tcl's async support.
+ Added -code switch and made interpreter understand "-nostack"
+ coming from error to use ^C to easily return to interpreter.
+ Introduced following incompatibilities:
+ - ONEXIT interface disappeared. Use "exit -onexit". (Thinking
+ of this as a signal bought nothing but complexity.)
+ Added "exit -noexit" to run all expect-related exit
+ handlers without exiting or destroying interp or ".".
+ Useful for when other apps have exit handlers.
+ - trap command takes missing action as a query. Use "" or
+ SIG_DFL to delete or reset a trap.
+ - SIGCLD gone. Now always called CHLD even if underlying
+ system only knows about CLD.
+ All sig handlers and exit handlers run at global level.
+
+ Removed setjmp/longjmp crap. Not needed since systems which
+ wait in read don't restart system calls.
+
+ Added support in expect for "-gl" and allowed longer forms to
+ match Tcl's switch command. Similarly for "-ex" in interact.
+ Rewrote arg parsing for send.
+
+ Added "stty" command to support stty of ttys other than
+ /dev/tty. Better for /dev/tty, too. This should fix
+ security complaint from BSD's Net2 stty.
+
+ <R.K.Lloyd@csc.liv.ac.uk> gave fixes for configure and noted
+ exp_main_tk was missing exp_conf.h.
+
+ Added "exp_timestamp" command. Fixed bug in interpreter cmd.
+ It wouldn't return anything with TCL_OK.
+
+ Renamed -flush to -nobuffer.
+
+ Make interact default to executing actions in raw mode.
+ Accept -reset to execute in cooked mode. Ignore -f.
+ Fixed examples. Fixed bug in "-o -timeout".
+
+ Deprecated getpid (due to Tcl's pid), added exp_pid.
+
+ Put "rm -f" inside catch. SunOS 4.1.3 and some version of AIX
+ complain despite the -f!
+
+ Added "send -break" for Dave Mielke.
+
+ Fixed argv handling of expectk to match expect for Steve Clark.
+
+ Switching to Tcl 7.0
+
+8/21/93 4.7.7 Cygnus added support for OSF/1 style ptys.
+
+ Brian Bebeau <brian@cblph.att.com> found bug in PTC support,
+ HAVE__GETPTY, timestamp doc, and provides some mods for config
+ AT&T StarServer.
+
+ Detection of direct spawn ids failed on -1.
+
+8/18/93 4.7.6 Removed zone and gmtoff from timestamp. Not ANSI.
+ Removed getpid confusion.
+ Once again, added "cat -u" into kibitz (this time for AIX 3.2).
+
+8/18/93 4.7.5 De Clarke <de@lick.UCSC.EDU> hit error in exp_global.h because
+ tcl.h had not been included.
+
+8/16/93 4.7.4 Richard Kasperowski <richk@icad.COM> found that Ultrix 4.1-2
+ failed to allocate controlling terminal. Ultrix's setsid is
+ evidentally buggy. Switched back to setpgrp - which fixed it.
+
+ Fixed type defn of exp_tty_original.
+
+ Dave Mielke found two bugs in interact: re-failure prevented
+ other patterns from matching a particular point in the stream,
+ and two or more -inputs didn't actually work. Also found bug
+ in HP trap handling - despite what docs say, other things
+ besides open/close have to be handled. Specifically, slave was
+ generating an ARGGET. Backed off on trying to wait immediately
+ for two OPENs to just waiting for one OPEN. Perhaps zero?
+ Also found deficiency in return -tcl - failed to return arg.
+
+ At Dave's request, made cmdfile by read in a single gulp rather
+ than line by line. Added -b (buffer) flag for old behavior.
+ Old behavior performs badly on very long procedures but is use-
+ ful for reading commands from pipes. Made "system stty" return
+ status of raw/echo.
+
+ Made log_user return previous value irrespective of args.
+
+ Fixed mishandling of parens inside of alternation noted by
+ Bud Bach <bachww@rtsg.mot.com>.
+
+ Added -timestamp, -iread, and -iwrite to interact and
+ expect.
+
+ Added -onexec flag to close to solve problem posed by
+ Bellave Jayaram <bjayaram@slee01.srl.ford.com>.
+
+ Added -0 to send. Removed capability of send to send multiple
+ strings.
+
+ Chip Rosenthal noted bug in releasing trap 0's action. Also
+ modified exit handler to allow recursive invocation. Instead
+ of complaining, it skips handlers that have already been
+ invoked and forces the process to exit.
+
+ Added new names for most command prefaced by "exp_".
+ Deprecated send_spawn.
+
+ Switched to Ousterhout's ckalloc and attitudes towards failure.
+
+ Started adding Tcl 7.0 support. getpid renamed to pid. Added
+ exp_pid to support things that Tcl 7 does with its pid.
+
+6/12/93 4.7.3 fnf@fishpond.cygnus.com noted minor type problems. Rob Savoye
+ noted trap SIGINT overrode debugger handler. Default should
+ be reverse.
+
+6/8/93 4.7.2 Added debugger to public release.
+
+6/7/93 4.7.1 Ed Oskiewicz <eo@ansa.co.uk> noted prototype botch - exp_cook.
+ Owen Rees <rtor@ansa.co.uk> noted missing decl - tclRegexpError
+
+6/6/93 4.7.0 Gert Bultman <bultman@dgw.rws.nl> exposed a bug in interact's
+ -update.
+
+5/27/93 4.6.0 Rick Sladkey <jrs@world.std.com> fixed a bug in send_log -
+ checking a master needlessly and indexing off the end of an
+ array.
+
+ Rob Savoye made change for detecting libpt.a, modified
+ autoconf for better handling of X, exec_prefix, and ranlib.
+
+ Kris Woeppel <krisw@cs.athabascau.ca> said SVR3 doesn't have
+ wait.h.
+
+ Made libexpect.a understand regexp. Reorganized code. It
+ now requires Tcl to be installed first, although it uses only
+ a few utility routines. Hopefully this isn't a problem for
+ anyone.
+
+ Zack Xu <zack@cs.wisc.edu> noted exp_main.h needed C++ support.
+
+ Pascal Meheut <pascal@cnam.cnam.fr> gave fix for skipping over
+ null bytes while interact is pattern matching.
+
+ Added "--" to expect, interact, and send.
+
+ Added support for associating multiple -i's with a single
+ pattern, and -i's with no pattern for use with spawn_id_any.
+
+ Made interact work with systems that lack select/poll.
+
+ Added code and #defines for debugger. Debugger itself is not
+ yet available.
+
+4/19/93 4.5.2 Achim Flammenkamp <achim@HRZ.Uni-Bielefeld.DE> noted that I
+ documented full_buffer as buffer_full.
+
+ Ted Stockwell <ted@sirius.aggregate.com> noted that wait arg
+ was missing an & in configure test.
+
+ Scott Hess noted that systems can have wait4 without waitpid.
+
+ Jonathan Kamens <jik@gza.com> noted/fixed some things that
+ weren't autoconf'd correctly: pid_t, RETSIGTYPE, malloc.
+
+ Gary Shea noted that a recent change to expectk made it not
+ default to interactive.
+
+4/12/93 4.5.1 At request of Rusty Wilson <zrlw05@hou.amoco.com>, added
+ "-console" to spawn.
+
+ Pang Wai Man Raymond <wmpang@cuse1.se.cuhk.hk> reported that
+ passmass didn't grok DEC's passwd prompts for root.
+
+4/7/93 4.5.0 Fixed bug in interact regexp preventing match of multichar
+ literals.
+
+4/6/93 4.4.3 Bennett Todd <bet@sbi.com> noted missing example scripts
+ timed-read and time-run.
+
+3/29/93 4.4.2 Bill Houle <Bill.House@SanDiego.NCR.COM reported fixes
+ for SVR4 pty support to compile.
+
+ Made string matcher understand *$. Documented tty_spawn_id.
+ Made command line -i override -f.
+
+ For Tuan Doan <tdoan@bnr.ca> on HP, make kibitz use domainname
+ as fallback and used whoami instead of env(USER).
+
+ Fixed bug in the generic pty code that could report out of ptys
+ because an earlier slave slowly deleted the lock file.
+
+3/25/93 4.4.1 Stephen House <sdhouse@bnr.ca> reported exp_tk.c wouldn't
+ compile on HP. Fixed.
+
+3/24/93 4.4.0 Added back SVR4-style pty allocation which got omitted in the
+ autoconfig process. Fixed bug in interact's -update handling.
+ Fixed bug in weather script that cut off long reports.
+
+3/15/93 4.3.0 Cleaned up /tmp files used during pty locking.
+
+ Added command "parity" to enable parity stripping. Fixed
+ match_max to do -i correctly.
+
+3/15/93 4.2.4 Fixed to work on new SGI which returns slave-close via excep
+ (select) or POLLERR (poll) rather than thru read(). Why do you
+ people do things like this?
+
+3/12/93 4.2.3 Fixed to work on AIX (using /dev/ptc) and UTS (using getpty).
+
+3/11/93 4.2.1-2 Fixed numerous bugs relating to HP ptys. It's amazing that for
+ their bewildering complexity, they couldn't support generation
+ of EOF to the master (or at least enable trapping of just
+ close), rather than forcing the code to know about opens, too.
+
+3/8/93 4.2.0 Integrated Rob Savoye's autoconfig code.
+
+ Interact mishandled new -eof flag. Added -update.
+
+ Gary Shea <shea@cs.ukans.edu> noted that tkwait hung if
+ expect had been called. Rewrote most of tk_event.c and fixed
+ some other problems related to efficiency & multiple timeouts.
+
+ E Beck <beck@qtp.ufl.edu> suggested mods to more easily support
+ Extended Tcl.
+
+ Bill Mitchell <mitchell@mdd.comm.mot.com> reported problems on
+ 4.3+BSD. Added support for TIOCSCTTY.
+
+ Dana Burd <dana@wrs.com> noted that "exit" caused by ^C during
+ expect didn't work - just returning to expect. Fixed, and then
+ removed "feature" of ^C to abort a timeout. This feature
+ proved a lot less useful than I thought it would.
+
+2/21/93 4.1.0 Bill Tierney <wtierney@leland.stanford.edu> noted that double
+ close dumped core. Rewrote fd_to_f and close/adjust functions.
+
+ Interactive interpreter() didn't properly wait in
+ get_next_event, so Tk stopped responding to events.
+ Wrote version of interpreter that shares expect's input buffers
+ but can't think of a use. Left as an ifdef SHARE_CMD_BUFFER.
+
+1/26/93 4.0.1 Added eof check to xpstat. Removed incorrect and unnec.
+ #includes from exp_main_exp.c
+
+ Chip Rosenthal <chip@chinacat.unicom.com> found my refs to
+ tclRegexpError need externs on systems that don't use Tcl's
+ string.h. string.h should probably be changed not to refer to
+ tclInt.h.
+
+ Added FAQ about Expect's copyright status.
+
+ Mark Christopher <christo@bnr.ca> pointed out some really
+ stupid errors in the HP support for select.
+
+12/16/92 4.0.0 Rewrote interact. Made re-entrant thru event-handler for Tk.
+ (Same for Expect.) Abstracted out common code so that
+ remainder is specific to select vs poll vs tk (although
+ "simple" was impossible to handle). Added timeouts, regexps
+ (at request of numerous people), ability to set up arbitrary
+ graphs of process flows, and some miscellaneous but useful
+ functionality. New flags are: -input, -output, -re, -echo,
+ -flush, -eof.
+
+ Added "-noecho" to spawn command.
+
+ Added getpid command. Something with this functionality should
+ be added to the Tcl core. When it is, this function will go
+ away.
+
+ Removed assumption of global "interp" handle. Rewrote init
+ and other routines for use as libraries. Added appropriate
+ glue to Makefile.
+
+ At request of Rob Savoye <rob@cygnus.com> added "send_log" and
+ disabled buffering on all output. The only affect unbuffered
+ output will cause users is if they pass large strings in
+ multiple args to send.
+
+ Ray Davis <rdavis@masschaos.de.convex.com> reported Convex
+ could not do job control from spawned procs. I added a symbol
+ DO_SETSID to force this.
+
+ Martin Leisner modified rftp to understand iftp. I added it
+ to the publicly donated scripts directory.
+
+11/17/92 3.24.1 Martin Leisner suggested Makefile use $(MAKE) and support Tcl
+ as a Sun shared library.
+
+ Seth Perlman <seth@welchgate.welch.jhu.edu> suggested interact
+ support timeout. I've added this as "-timeout" in inter_select
+ but left undocumented while we experiment with interface.
+
+ Joe VanAndel <vanandel@ncar.ucar.edu> pointed out that su2
+ script still used old syntax. Fixed.
+
+ Konrad Haedener <haedener@iacrs1.unibe.ch> fixed a bug in
+ POSIX tty handling on AIX. Surprisingly, we discovered AIX
+ worked just fine when pty_bsd is used and without -DPOSIX!
+
+ Doug (George Jetson) <pynq@midway.uchicago.edu> pointed out
+ that a spawn_id for /dev/tty would be really handy. I added
+ tty_spawn_id for this purpose.
+
+11/4/92 3.24.0 After problem reported by James Ward <jew@sunquest.com> added
+ to man page describing delays required by hardware such as for
+ UART switching.
+
+ Recoded all \C sequences as \### in examples and man page in
+ anticipation of them going away in next version of Tcl.
+
+ Switched to printing errorInfo during errors instead of the
+ command and only the top-level error message. Since this
+ includes entire stack, this should be very helpful.
+
+ J. Cazander <cazander:pasichva via serigate@phcoms.seri.
+ philips.nl> reported that purify found a write beyond the end
+ of an input buffer. Lucked, it was just before a double-word
+ boundary, so it probably isn't a problem. I fixed it anyway.
+
+10/9/92 3.23.1 Tor Lillqvist <tml@tik.vtt.fi> supplied support for HP 8.0.7 in
+ POSIX-mode, and a bugfix for POSIX tty mode switching
+
+10/8/92 3.23.0 Larry Rogers <lrr@Princeton.EDU> reported that "weather" blew
+ up in spawn. I'll add a catch-all to the script to report
+ similar problems (out of ptys, processes, etc.)
+
+ Ting Leung <tleung@bnr.ca> notes that log() in human_write can
+ receive a 0 (domain error). Fixed unit_random to avoid that.
+
+ Tony Primavera <aprima@xox.ssc.af.mil> notes that the sample
+ archie script needs to understand mcgill's limit of 10 users.
+ Tor Lillqvist <tml@tik.vtt.fi> noted that a lesser-used pattern
+ ("unknown...") is incorrect.
+
+ Grant Taylor <gat@pecan.cray.com> found a problem when forking
+ (using Expect's fork) multiple processes, each of which spawned
+ something. In the BSD pty support, I had used the pid to build
+ a temporary file for testing the pty before actual use. When
+ multiple processes tried to use the same tempfile, it blew up.
+
+8/12/92 3.22.13 Corey Satten pointed out that -u on cat caused kibitz to slow
+ down on Ultrix. I see the same behavior on SunOS. I added an
+ option to fix it for systems that need it. Corey also noted
+ arg miscounting in kibitz, and pointed out that world-readable
+ fifos could be a security problem. He gave a fix for this and
+ also a fix to force ptys to be put into raw mode.
+
+ Terrence Brannon <tb06@pl122e.eecs.lehigh.edu> reported rftp
+ referenced the undefined variable 'transfer'. Turned out to be
+ a bug in the code to handle symbolic links.
+
+7/20/92 3.22.12 Added O_NOCTTY (if defined) in pty_bsd.c to avoid gaining
+ control terminal while testing pty when running as daemon.
+
+ At request of Michael D. Riley <riley@mbeya.research.att.com>
+ added explanation to man page - how expect_after/before deal
+ with spawn_id.
+
+ Charles Hannum discovered the problem with AIX (see earlier)
+ was a missing "extern" in the errno declaration. Also, the
+ compiler was sensitive to a lack of access to the defn of
+ struct expect_special.
+
+ Dave Coombs gave me yet another fix for the weather server to
+ accomodate its ever continual change.
+
+7/2/92 3.22.11 Yet more work. Discovered that SunOS and Ultrix really like
+ setpgrp(0,0) much better than setpgrp(0,getpid()) but the
+ manual doesn't describe well why this seems to work better.
+ (The old call worked inconsistently.)
+
+6/30/92 3.22.10 Did more work on modifications to dissolve connection between
+ stdio and devtty. Eventually, I'd like to add a separate
+ spawn_id for devtty (expect_devtty?).
+
+6/5/92 3.22.9 Hansel Wan <hhw0@gte.com> noted that $errorInfo was clobbered
+ by prompt1. To prevent this, I added a default definition
+ for prompt1 (and prompt2 while I was at it).
+
+ Unnati Amin <uxa@po.cwru.edu> noted that the example scripts
+ checked for $ in prompts which didn't work. This bug was
+ created when $ was turned into a "match end-of-input" char
+ in the transition from v2 to v3. Solution: backslash the $.
+
+ A few parts of code assumed spawn_id was always stdin, which
+ caused "send" to send to stdout, which meant succeeding
+ expect's hung, waiting forever. Fixed is_user macro.
+ This was a problem with scripts that redirected stdin or
+ somehow reused fd 0. Surprising that no one ever did that
+ before - also surprising that it didn't bother cron jobs.
+
+6/2/92 3.22.8 Man pages fixes from Matt Crawford crawdad@fncent.fnal.gov.
+
+5/12/92 3.22.7 Missing ; in Makefile, screwed up chmod.
+
+ Fixed bug that caused interact to think the modes had changed
+ when they hadn't.
+
+5/11/92 3.22.6 Added regression paper to ftp archive - published in the 1992
+ USENIX San Antonio Proceedings.
+
+ Swapped setpgrp and fork in disconnect command for sysV88.
+ According to Dave Schmitt <daves@techmpc.csg.gss.mot.com>,
+ original code (right out of Stevens) starts the child with
+ closed stdio fds.
+
+ Fixed bug in interact that changed /dev/tty modes even if
+ interact was used to connect two completely different ttys.
+ Had never been a problem before, but today I wrote some code
+ that actually calls interact from cron! Also, copied the
+ experimental fix from 3.22.5 to inter_poll.
+
+ Jeremy Nussbaum <jeremy@world.std.com> says cat needs "-u" in
+ kibitz for his HP 8.0 system to work. I wonder why this has
+ never been a problem on earlier HP and other systems?
+
+ Forced Makefile to mark scripts executable.
+
+4/12/92 3.22.5 Fixed bugs reported by Matt Ranney <mjr@uther.Calvin.EDU>
+ including a syntax error (!) in expect.c on ecases_inuse.
+ I didn't even compile this before pushing out? He also noted
+ some # were not in column 1.
+
+ I put in an experimental fix to interact (only in select
+ version currently) to fix when pattern matching from master
+ and user needs to continue typing in order to complete match.
+
+4/3/92 3.22.4 Charles Hannum (mycroft@gnu.ai.mit.edu) pointed out that I
+ screwed up a comment in the brand new pty_aix3.c. He also gave
+ me a fix for an arg-less expect, which did a malloc(0). And
+ he said that AIX ptys return EOF in yet a new way - read()
+ returns -1 with errno == 0. Yuck.
+
+3/29/92 3.22.3 Jay Schmidgall gave me yet another pty_aix3.c. He also gave
+ ifdefs for POSIX terminal support.
+
+3/18/92 3.22.2 Jay Schmidgall <shmdgljd+@rchland.ibm.com> modified pty_sgi3.c
+ to make a pty interface for recent versions of AIX.
+
+ Steve Summit <scs@adam.mit.edu> noted that "trap 0" could
+ actually call signal(0...)
+
+ Martin Leisner <Martin_A._Leisner.Henr801C@xerox.com> noted
+ that rftp was broken. It seems I never handled symlinks. They
+ are interesting. You can't tell from the listing whether they
+ are files or directories, so you just have to blindly go ahead
+ and assume it's one or the other and see what happens!
+
+3/11/92 3.22.1 In talking to Dave Schmitt ,daves@techmpc.csg.gss.mot.com>,
+ realized the documentation for wait had never been updated
+ from the way it used to work in v2 (returning any pid).
+
+3/11/92 3.22.0 Another question from Ron, prompted me to find another bug.
+ interact -o wrongly manipulated the user buffer at one point.
+
+3/10/92 3.21.0 Ron Young <ron@nevada.edu> found that spawn failed on a
+ DECstation 3100 running Ultrix 4.2. I had forgotten to test
+ that cmdfile was valid before comparing against stdin in fix
+ related to fflush in 3.20.0.
+
+ While I was on a DECstation, I noticed that it does not accept
+ setpgrp(...,0). Changed 2nd arg to getpid().
+
+3/6/92 3.20.2 Stefan Farestam <farestam@orion.cerfacs.fr> provided a new
+ version of pty_sgi.c which uses _getpty. I renamed the old
+ one pty_sgi3.c
+
+3/3/92 3.20.1 Brian Woodson requested I update the dates and version numbers.
+
+3/1/92 3.20.0 Prompted by a question from Ken Mandelberg, added -raw to
+ noidle and kibitz script.
+
+ Fixed fflush(cmdfile) again, having been authoritatively told
+ by net wisdom that there is no way to portably fflush a shared
+ read-stream. (I take back my claim about a bug in HP's fclose!)
+
+ John Sellens gave me some more fixes for non-DEC MIPS OS.
+
+2/22/92 3.19.1 John Sellens <jmsellen@watmath.waterloo.edu> gave me a bug
+ fix for NOWAITPID.
+
+2/21/92 3.19.0 Found a bug in HPUX fclose!! It moves the I/O pointer in the
+ shared file table entry! This explains the symptoms I reported
+ earlier. Fortunately, it's easy to code around (by me - it is
+ no longer necessary to fudge the scripts).
+
+ Added some stuff to the man page to explain why expect behaves
+ the way it does in an emacs shell window and how to live with
+ it.
+
+2/21/92 3.18.0 Worked on the HP port some more. The HP causes a real problem
+ by insisting SIGCLD be delivered in order for wait to return
+ a status. This royally complicated the code, partly because
+ of the special casing all over the place in the trap command,
+ the asynchronous delivery of SIGCLD and also because Tcl itself
+ is not prepared to have system calls be interrupted. Cleverly,
+ the HP also defines both CLD and CHLD which threw my macros
+ off at first. Thanks, but I don't this kind of help!
+
+ Anyway, the end result is that on the HP, SIGCLD is ignored.
+ The manual claims wait status will not be delivered but it
+ seems to be anyway. Good grief! (Even if it were ignored,
+ it would not be such a calamity, since wait is used mainly
+ to discard zombies on other systems.)
+
+ A remaining problem is that there appears to be some odd
+ interaction, perhaps with fork, such that the script is rolled
+ back at eof if a spawned process happens to exit at the same
+ time. The solution for now is to exit all scripts via exit
+ rather than letting exit be called implicitly. There must be
+ some real bug, but I'm unable to find anything after lots of
+ testing, line and Saber. At the moment, I'm highly suspicious
+ of the HP itself rather than expect.
+
+ Bob Proulx and Jeff Okamoto supplied me with patches for
+ inter_select.c. HP transmits some pty interactions via the
+ exception field in select.
+
+ Michael Grant gave me a mod to grok ~ in the logfile and
+ debug commands.
+
+2/17/92 3.17.1 Brian Keves <keves@meaddata.com> pointed out that the man page
+ still referred to "expect_match" instead of "expect_out".
+
+2/12/92 3.17.0 Eric Arnold <Eric.Arnold@corp.sun.com> ran into a problem
+ when running in the background. interact did ioctl(0...)s to
+ change the terminal mode, ignoring the -u flag.
+
+ Fixed a bug in kibitz which blew up when asking for a password
+ due to a spelling error. The drawbacks of interpreters...
+
+2/4/92 3.16.3 Dongchul Lim <lim@doctor.chem.yale.edu> noted that scripts can
+ hang in the background. I had assumed isatty(0) was enough to
+ contrast bg/fg but it returns 1 if the script was started with
+ a & from the terminal. I added code to watch if any ioctl(0)s
+ were done. If so, than it is safe to do more, in particular
+ in the exit handler to reset the terminal modes.
+
+1/28/92 3.16.2 Fixed a bug on SV systems causing errors when trying to do
+ further reads after a SIGCLD had already arrived on a spawn_id.
+
+ Peter Funk <pf@artcom0.north.de> gave mods for SCO XENIX 386.
+
+1/24/92 3.16.1 Oops. Forgot to add pty_svr4.c to shar.
+
+1/13/92 3.16.0 Karl Lehenbauer <karl@sugar.NeoSoft.Com> a tiny change for
+ getting a clean compile on SCO 3.2.2.
+
+ My getimeofday-avoidance code wasn't right, sigh. Kibitz
+ noticed. Fixed two other bugs in kibitz - password request
+ was for wrong user and it timed out but shouldn't have.
+
+ Note: seems to work fine with new version of Tcl: 6.2
+
+1/13/92 3.15.1 Added a bit of code to avoid gettimeofday system calls when
+ timeout == -1. Fixed minor bugs in kibitz relating to cleaning
+ up and returning error messages.
+
+ Redid support for stdlib.h including making it default to fix
+ problem in Ultrix 4.2 reported by Oliver Kretzschmar <viskretz
+ @ikesg1.energietechnik.uni-stuttgart.de>.
+
+ Ian Johnstone <ianj@sequent.com> said his system (DYNIX 3.2)
+ needed an additional include <ctype.h> in inter_select.
+
+ Dave Coombs <cme.nist.gov> added logic to test/weather to
+ accomodate a new feature in the weather server.
+
+ Hal Peterson fixed some SV code that I just added for handling
+ SIGCLD properly. He made the Cray-extra-child timeout in half
+ the normal timeout to allow distinguishing between eof and real
+ timeout. Finished rest of Jeff Okamoto's fixes for HPUX.
+
+ Wally Strzelec <packman@tamuts.tamu.edu> provided mods for
+ Amdahl which has its own pty-handling functions. Ifdef'd into
+ pty_usg.
+
+12/30/91 3.15.0 Fixed a bug that struck when eof occurred when reading from
+ multiple processes simultaneously and no user-supplied eof
+ handler.
+
+12/26/91 3.14.1 Ted Gibson <tgibson@logdis11.hq.aflc.af.mil> gave me some mods
+ for a 3B2 having to do with termio vs termios, etc.
+
+12/24/91 3.14.0 Deprecated expect 2. Expect 3 is now the official version.
+
+ Parag Patel <parag@netcom.netcom.com> gave me some #includes
+ necessary for A/UX 2.
+
+ Brian Woodson noticed "send a b" generates incorrect debug
+ output.
+
+ Working with Jeff Okamoto to run expect on HP/UX 8.0, we fixed
+ SIGCLD catching (he says HPUX doesn't ignore them by default?),
+ obviating longjmp from stomping locals, fixed a bug in cmdWait
+ that would prevent the wait status from being collected in
+ rare situations.
+
+12/17/91 3.13.1 James Davis suggested fixing Makefile to handle case where no
+ example scripts should be installed. I added similar logic
+ for script man pages.
+
+ Pete Siemsen fixed a bunch of things in the Makefile including
+ where to get expect when invoking fixline1. He suggested defs
+ for supporting install and multiple MAN targets.
+
+12/12/91 3.13.0 Matthew Freedman <mattf@cac.washington.edu> noted mismatch
+ between lib man page (said "stty_init") and lib code (said
+ "exp_stty"). He also found a screwup in the library such that
+ the pty slave wasn't being set up correctly.
+
+ Added note to kibitz man page on how to kibitz with 3 or more.
+
+12/12/91 3.12.0 "expect *" worked incorrectly if it was first expect after
+ spawn, due to buffer not being initialized.
+
+ Added a good example for "expect -continue" to man page.
+ Added an FAQ about a gcc problem that seems to be common.
+
+12/11/91 3.11.2 James Davis noted I forgot to put kibitz.man in distribution.
+ I changed kibitz to read domain from resolv.conf instead of
+ calling domainname(1) for systems upon which NIS domainname
+ differs from Internet.
+
+ Pete Siemsen <siemsen@barnard.usc.edu> noted slight error in
+ libexpect man page.
+
+12/10/91 3.11.1 A couple tiny mods to the Makefile courtesy of James B. Davis
+ and Michael Grant (guest worker from Sun, temporarily at
+ <mgrant@xdr.ncsl.nist.gov>. Both of them also noted a problem
+ caused by incorrect installation of gcc that caused expect to
+ say "ioctl(set): Invalid something or other" upon exit.
+
+ Fixed complaint about exit() while compiling without STDC.
+
+12/9/91 3.11.0 beta!
+
+ Hal Peterson provided fixes for UNICOS 6.1 and 7.0 on both
+ CRAY-2 and CRAY Y-MP. He also fixed a problem in interact
+ where malloc(0) could've occurred.
+
+ Added support for allowing user to set interpreter prompt.
+
+ Added forgotten -d flag to match_max in rftp script.
+ Made kibitz understand user@host.
+
+ Expect's internal buffer-full-handling incorrectly copied
+ the latter buffer half beginning from the end of the buffer.
+
+12/5/91 3.10.1 Massaged Makefile to allow for more flexibility in
+ installation, especially with regards to scripts. #! is now
+ reset.
+
+ Added "kibitz", a really cute script to let two people control
+ one program. Example users are for one person to help another
+ remotely, logging a conversation (run emacs or whatever inside
+ kibitz and your conversation can be logged, scrolled backwards,
+ etc., or of course, playing games together.
+
+12/4/91 3.10.0 Tightened up arg checking for "wait" - it core dumped when it
+ should've said "syntax error".
+
+ Rick Cady <rickc@nsd.3com.com> noted minor inconsistency in man
+ page describing strace.
+
+ I fixed a bug that prevented "system stty -echo raw" from
+ working. The raw data was clobbering the -echo data.
+
+12/3/91 3.9.0 Brian Woodson noted that "close -i ..." evoked a syntax error.
+ I had parsed the arguments incorrectly.
+
+ After the nth request, I finally set up pub/expect/scripts as
+ a directory for scripts.
+
+12/2/91 3.8.0 Phil Sheperd <pshepher@loki.uni.edu.au> fixed a major bug in
+ exp_spawnv() preventing one side of the pty from being set up
+ correctly. Thus nothing worked! He also reported that his
+ system didn't have strdup, so I added an explicit defn of it.
+
+ James B. Davis fixed a couple nroff-bugs on the man page, and
+ said someone already gave him a dump script (see below).
+
+ Richard (R.C.) Vieregge <richv@bnr.ca> found a $ was missing
+ from test/ftp.exp.
+
+11/22/91 3.7.2 James B. Davis <james@solbourne.com> straightened out a couple
+ things in the Makefile and asked if anyone had written a script
+ for dump.
+
+ Jeff Okamoto <okamoto@hpcc25.corp.hp.com> had a couple changes
+ for HPUX 7 and 8 compat, involving termio stuff.
+
+ Prompted by Andy Norman, added note to man page describing how
+ to disable all argv processing while using #!.
+
+ Converted passmass and rftp over to new version.
+
+11/15/91 3.7.1 Brian Woodson asked me about the Tcl_WaitPids "got unknown
+ process" panic. This is a Tcl bug that John has promised
+ to fix. I'll document how to avoid it in the man page.
+
+ Incidentally, I'm going under the knife tomorrow for three
+ torn cartilage in my wrist. The doctors say it may be a couple
+ days to couple months. Until I get back, hang in there.
+
+11/13/91 3.7.0 Yet another bug discovered (and fixed). "expect eof" was
+ failing to remember the buffer, and expect_out(buffer) was
+ empty upon return.
+
+ Brian Woodson noted I forgot to document the -i flag of close.
+
+11/12/91 3.6.0 Sean Cunningham <sean@moorenet.com> reported that he couldn't
+ open /dev/tty from 'at'. 'spawn' was incorrectly not executing
+ code to claim it was a controlling tty. BSD only.
+
+11/11/91 3.5.1 Brian Woodson notes that version 2 and 3 treat the following
+ differently.
+
+ proc p {} {spawn s}; expect
+
+ In v3, spawn_id is locallized by the proc, and thrown away when
+ p returns. Unfortunately, in v2 due to some sloppy coding on
+ my part, spawn always affected the global value of spawn_id.
+ This differed from the handling of other variables, and in v3,
+ this unusual behavior had to go, because the multiprocess
+ handling and the large number of variables implicitly set
+ (especially by the expect command) demanded that I be more
+ systematic about how this was done.
+
+ Since I never depended on this behavior, I never documented it
+ as being something you should rely upon. Alas. To fix it, add
+ the line
+
+ global spawn_id
+
+ to the beginning of any proc that calls spawn and needs the
+ value of spawn_id implicitly defined outside of the proc.
+
+11/6/91 3.5.0 Drew Whitehouse <Drew.Whitehouse@anu.edu.au> hit a bad pointer.
+ I forgot an initialization in expect.c which caused problems
+ when an EOF occurred which had no eof pattern.
+
+11/2/91 3.4.0 Added FAQ from various questions people have sent me and my
+ replies. Made CONVERTING file on converting from 2 to 3.
+
+ Nelson H. F. Beebe <beebe@math.utah.edu> found a missing
+ declaration for exp_tty_original in bye() of main.c. How come
+ the Sun C compiler doesn't complain about this!?!!?
+
+ Nelson also reported that SunOS 4.0.3 had a problem including
+ varargs. It turned out that old varargs had check for
+ reinclusion, and tclInt.h also includes it. So I added an
+ #ifdef va_dcl and put my inclusion after tclInt.h.
+
+10/31/91 3.3.0 Converted most of the examples. Three more to go.
+ Worked on man page some more.
+
+ Modified expect so that if timeout > 0, and nothing in the
+ buffer matched, it will force a read, no matter how long the
+ preceeding code took. This may be hard to understand, but is
+ the intuitive behavior that I always desired.
+
+10/30/91 3.2.0 Fixed bug in eof handling. Converted some more of the
+ examples, and added to Makefile.
+
+10/29/91 3.1.0 Fixed slight bugs in tty mode switching, pty initialization
+ (via stty).
+
+ Fixed expect library. Fixed compatibility code for non-BSD
+ systems. As usual, I could only test it so far, not having
+ all these systems at my disposal. I don't expect major
+ problems though, since the basic functions I depend on haven't
+ changed.
+
+ Completely rewrote handling of continue, return, etc in
+ expect, interact, interpreter. It's actually systematic now.
+
+ Checked with John O. about some code to bounce wild return
+ codes, which he said was a mistake and would remove, so now I
+ can pass my own return codes different from Tcl's.
+
+To get | to return -> TCL_RETURN TCL_OK (no return)
+ V
+ expect return default continue -expect
+ interact return -tcl return default
+ interpreter return -tcl return default
+
+ What this table says is, to get "interpreter" (for example) to
+ return TCL_RETURN to its caller, you must say "return -tcl",
+ because "return" makes it return TCL_OK.
+
+ The "argumented" versions are considered to be the uncommon
+ form. In particular, I'd be surprised if anyone ever uses
+ the -tcl argument, but it's there for completeness and
+ consistency now.
+
+ Put together a FAQ. Needs more work, but hopefully worthwhile
+ as is.
+
+ Computing Systems with Expect article appeared a couple days
+ ago. How ironic that it describes the old version of Expect.
+ Nonetheless, it looks ok.
+
+10/25/91 3.0.0 alpha!
+ First release of Tcl-6.0-ready code.
+ It might fly for a couple seconds.
+
+ Here is a quick list of changes. Besides Tcl incompatibilities, Expect
+ incompatibilities are flagged below as:
+
+ ** major - scripts definitely won't run if they depend on this
+ * minor - scripts probably will run but there is some subtle
+ change that should be examined).
+
+ ** Select renamed 'ready' and undocumented. Seems pointless now.
+
+ Added support to expect command for waiting on patterns from
+ different processes. The old version implemented this via
+ 'select' but but it is much simpler via expect. Added -i to
+ a number of commands to signify a spawn_id which overrides
+ the variable.
+
+ Added any_spawn_id to match any spawn_id.
+ An explicit null pattern, forces a spawn_id to be considered
+ when all it can possibly match are any_spawn_id patterns.
+
+ * output is no longer flushed to expect_match upon timeout.
+ May be multiple buffers now, so it doesn't make sense to
+ flush just one.) -n was added to disable transfers from input
+ buffer to expect_match var. I suspect it will only be used
+ for experimentation.
+
+ Added expect -re for regular expressions. Added expect_out
+ array to retain indices and strings of partial matches for
+ ** for both glob and re. expect_match has been renamed
+ expect_out(buffer).
+
+ A la Tcl, added -nocase for both types of patterns. (Oddly,
+ Tcl's case only does it for regexps.)
+
+ By popular demand, unanchored glob patterns. Old patterns
+ will continue to work, since earlier interpretation was much
+ stricter. Unfortunately, unanchored matches make certain user
+ errors easier. For instance, people will send answers before
+ seeing all of the question. Typically, output can 'look'
+ ugly, as answers land in the middle of other things.
+
+ To anchor patterns, use ^ in beginning and/or $ at end.
+
+ Added expect_out(spawn_id) to report which spawn_id was read.
+
+ Made expect and variants understand all args as one arg.
+
+ Added 'default' pattern.
+
+ Added continue_expect command.
+
+ Added expect_before, expect_after commands which take same
+ args as expect, but continue to stay in effect for all expects.
+
+ ** Added match_max command, deleted it as a variable. The old
+ way was too coarse for use over multiple spawn_ids. With no
+ arg, returns current max. Takes -i flag and -d for default.
+
+ Added globbing to spawn command.
+
+ Added optional -i spawn_id to wait.
+
+ Added optional -i to send (and all its variants).
+
+ Renamed trace to 'strace' since it conflicts with Tcl's new
+ trace command. Since 'trace' traces variables, I figured
+ 'strace' wasn't too bad (for "statement trace"). I felt
+ obliged to make it short and not as obliged to make it as
+ meaningful since it will probably invariably be typed by hand.
+
+ Made timeout == -1 mean infinity.
+
+ Made interact do pattern matching in both directions via
+ use of -o flag.
+
+ Added -F flag for convenience. If -f or -F used, interact
+ can no longer be overrun. In particular, if more characters
+ arrive then match a pattern, remaining characters will be
+ buffered rather than thrown away (old behavior).
+
+ Patterns may now be substrings of one another.
+
+ Made interact optionally take all args as one.
+
+ Default action is now 'interpreter' (see below).
+ interpreter now forces cooked mode, and echos results
+ so you don't have to constantly say "send_user [...]\n"
+
+ * Interact reads characters that have been buffered but not
+ matched by expect. And vice versa. Does anyone care?
+ (My rogue script did.)
+
+ From discussion with John Conti, I decided to make
+ 'interpreter' a separate command to start up interactive
+ command processor. Changed default action in interact to this.
+ Added eval depth and event id to prompt to interpreter.
+
+ Added expect_library which contains path for commonly
+ sourced expect scripts. Automatically source expect.rc
+ out of expect_library unless -N given. Automatically source
+ ~/.expect.rc unless -n given.
+
+ Added expect_version command to print and/or verify script
+ is compatible with running expect. Tcl version is also tested.
+ Felt it was worth making this a command because it's such a
+ pain to tear apart version strings.
+
+ Tcl's close and exit are both subsumed by expect's commands
+ of the same name.
+
+ Rewrote mode switching code so that "system stty" is handled
+ specially. This allows interact and interpret to get the modes
+ they want, without burning the user. It is now much easier
+ to leave expect in raw mode all the time, but the choice is
+ up to the user.
+
+ Added vgrindefs, courtesy of Brian Fitzgerald.
+
+9/23/91 Tcl 6.0 released. This new Tcl has some incompatibilities
+ with the old Tcl, so as long as everyone is changing their
+ scripts already, I'm taking the opportunity to make some
+ incompatible changes to Expect that I've wanted to do for a
+ long time.
+
+9/11/91 2.67 Ed Klein <eklein@syrinx.umd.edu> added support for SVR4 in the
+ form of pty_svr4.c and mods to command.c.
+
+ Added explanation to man page of how to create unreadable but
+ executable scripts. (No, chmod 111 doesn't work.)
+
+ Mark Diekhans <markd@grizzly.COM> pointed out to me that there
+ is a potential problem with the trap command:
+
+ "There is no control over when the signal will cause Tcl_Eval
+ to be executed. There is a chance that code in the Tcl library
+ will be executing when the signal comes in and the interpreter
+ data structure will be in an inconsistent state. This could
+ cause all sorts of nasty things to happen. In our Extended Tcl
+ (4.0) we added signal handling. but the way we implemented it
+ was to have the signal handler set a global flag. We modified
+ Tcl_Eval to check the flag after it finishs executing each
+ command. If the signal came in, Tcl_Eval then returns an error
+ such as: "SIGINT signal received". Signals may then be caught
+ with the catch command and processed."
+
+9/10/91 2.66 Don Jackson <Don.Jackson@Eng.Sun.COM> found a syntax error in
+ the usage error message of the example ftp-rfc script.
+
+ Marty Olevitch <marty%cosray@wuphys.wustl.edu> provided mods to
+ support MORE/bsd. Namely, added #include types.h to expect.c
+ and extern int errno to a number of files.
+
+ Scott Hess <scott@nic.gac.edu> noted a potential problem in
+ interact. Since interact only checks patterns at beginning
+ of reads, user can conceivably type fast enough so that
+ patterns are typed in the middle of a read. In reality this
+ doesn't happen, but Scott was driving one expect with another
+ expect and in this way provoked the behavior.
+
+ The solution is to read chars one at a time, either by
+ read(,,1) or buffering in a stdio-like way, but I'm not going
+ to do that because the code should really be rewritten entirely
+ and it just isn't worth it, since it is so easy to get around
+ at the user level.
+
+ Steve Legowik found that spawn-disconnect sequences fail. The
+ pty testing I added in version 2.55 causes expect to regain the
+ slave as a controlling tty, which generated SIGHUPs. If anyone
+ knows a clean way to avoid regain controlling ttys, let me
+ know. For now, I just set SIGHUP to SIG_IGN in the disconnect
+ command.
+
+8/14/91 2.65 Old passmass script changed root password. I renamed it to
+ passmass.old, and made a new one which works for any account.
+ It also supports yppasswd, telnet/rlogin, different names for
+ accounts on different machines. Handles VMS machines, too.
+
+ Added Computing Systems paper to expect distribution and moved
+ all expect-related things to separate expect directory in our
+ ftp directory.
+
+8/5/91 2.64 Achille Petrilli <achille@miss.cern.ch> found that on an SGI,
+ the expect command ocassionally returned "no more processes".
+ He traced the problem back to O_NDELAY in the open, which was
+ taken as-is from the man page, by someone else who's code I
+ didn't look at too closely at the time. The result works now.
+ Oddly I thought I fixed this error myself when the SGI support
+ was first installed, but I cannot find it. I evidentally
+ screwed up.
+
+7/31/91 2.63 Steve Legowik <legowik@cme.nist.gov> wanted to implement
+ callback by having a modem dial out and NOT go away, but
+ interact in the reverse direction. I added "interact -u" to
+ support the idea of changing the user from the default stdio
+ to a second spawned process. The result is that we can now
+ write a modem callback program that doesn't depend on the cute
+ trick of having getty recognize DTR which only worked when the
+ modem was directly connected to the computer. In Steve's case,
+ there were several network switches in the way.
+
+ Added "overlay" function which is similar to plain "exec" in
+ shell. (Too bad Tcl took the name already.)
+
+ Added robohunt scripts to the test directory. I wrote these
+ back in January, '91 and forgot about them til now. But I
+ suppose they are illustrative (at the very least of how to
+ generate truly random numbers). Ha.
+
+7/20/91 2.62 Carl Witty <cwitty@jessica.stanford.edu> pointed out my fdset
+ implementation (for systems that don't have it) wasted some
+ space. I had commented it correctly, however, making the
+ incorrect code obvious (except to me).
+
+ Robert Howland <howland@rahjr.ame.nd.edu> pointed out that
+ expect complained about not running from a real terminal under
+ cron. Oops! So I added a test to skip saving/restoring
+ terminal modes when fd 0 is not a tty, since this is obviously
+ pointless.
+
+7/19/91 2.61 Oops. Forgot to include getline and getline.exp examples even
+ though they have been documented!
+
+7/17/91 2.60 UMich changed interface to weather system necessitating change
+ to weather script.
+
+7/9/91 2.59 Didn't correctly comment things right in Makefile. Fixed.
+
+ Changed 'close' in gethostbyaddr example to 'catch close'.
+
+6/22/91 2.58 Made new file (pty_sgi.c) for supporting Silicon Graphics ptys.
+ Silicon Graphics select fails to see eof immediately but poll
+ works ok. Unfortunately, there was an error in inter_poll
+ (bad_io was uninitialized). Silicon Graphics works now.
+
+ Andy Norman <ange@hplb.hpl.hp.com> notes that linking expect
+ with the BSD compatibility library under HP-UX, libc.a must
+ be loaded before libBSD.a. Modified Makefile to reflect this.
+ He notes that there is a problem with expect not reading an EOF
+ from the current process. This should go away with HP-UX 8.0
+ when select has been enhanced to flag exceptions in the readfds
+ argument. Probably inter_poll would work.
+
+ Edward Haines <haines@bbn.com> notes that close returns EPERM
+ ("Not owner") on his Sun 4.0.3. This is rather startling!
+ (That's what I get for checking the return value of close!)
+ He said it is possible that they have modified things (viz.
+ DDN X.25 is loaded), but it still sounds incredible. For now,
+ I told him to either "catch" all closes or to remove the check
+ in the source code.
+
+ Added example scripts: ftp-rfc retrieves an RFC from uunet
+ via ftp. archie mails back a listing from the archie server.
+
+ Add the rest of Hal Peterson's changes for Cray support, 1)
+ fixing a problem where spawned processes flushed unread I/O
+ upon process exit, and 2) creating processes with the correct
+ uid. See his comments in command.c for more info.
+
+6/6/91 2.57 (On Cray) made signal handler declarations right. Added
+ missing #endif. Added includes to pty_unicos.c. Fixed bug
+ in two bugs in CmdSend, one involving send_stderr, the other
+ send_user. All of these are from Hal Peterson.
+
+ Added gethostbyaddr as example script. Given an internet
+ address, it returns the domain name. By querying neighboring
+ hosts if the name server fails, a much higher probability of
+ returning the name is obtained.
+
+5/30/91 2.56 Mispelled "match_max" as "max_match" in rftp script. This
+ caused files after the 2000 byte mark (per directory) to be
+ skipped.
+
+5/21/91 2.55 Revisited BSD pty code to reject ptys that have either slave or
+ master side already open. This fixes problems rare problems
+ such as expect not being able to see EOFs from the child proc.
+ (because another process still has the pty slave side open).
+ USG and Cray pty code could probably use this code, too.
+
+ Fixed bug in expect library (lib_exp.c) which caused output to
+ be copied to stderr instead of logfile when logfile_all was
+ set. Per Sreedhar Muppala <muppalla@nssdca.gsfc.nasa.gov>.
+
+5/16/91 2.54 Fixed weather script to accomodate occasional Weather Watch
+ that would cause an unexpected initial question to pop up.
+
+5/15/91 2.53 Added comment to BUG section of man page describing pty
+ misbehavior with non-interactive programs (search for "553061"
+ below), as per Hal Peterson <hrp@cray.com>.
+
+ Removed note from README about asking Ousterhout for SV TCL
+ at his request.
+
+5/11/91 2.52 Fixed a syntax error that Bruce Larson <ires@kaspar.ires.com>
+ found in inter_poll.c
+
+4/23/91 Computing Systems accepted paper on Expect for issue 4.2.
+
+4/18/91 2.51 Added some example scripts:
+ weather - retrieves weather forecasts from National Weather
+ Service via University of Michigan server.
+ rftp - ftp a directory hierarchy (i.e., recursively).
+
+4/18/91 2.50 Changed timeout to apply to total time in expect rather than
+ per read(). Original behavior hung forever when my modem test
+ script started listening to a modem than spit out 1 spurious
+ character every 10 seconds (very consistently).
+
+ Hal Peterson <hrp@pecan.cray.com> noted that exp_spawnv's args
+ didn't match documentation. Fixed in favor of documentation.
+ Several other funcs don't match header file (but typechecking
+ is avoided during compilation), because it was too hard for me
+ to make the header file ANSI compliant and support varargs
+ (which is undeniably more portable than stdargs at this point).
+ Fixed prototype declarations (again) in expect.h for C++ and
+ Standard C. Verified with GNU, G++ and Sun C (proto-less).
+
+ Added exp_disconnect to library. Moved alarm calls closer
+ to read() to tighten windows.
+
+4/11/91 2.49 Changed passmass script to use timeout of 1000000 instead of
+ 10000000000 after discovering that Ultrix sleep(3) doesn't
+ sleep at all for large values!
+
+ Added support for systems without dup2 (SVR2) per
+ <elston@edwards-tems.af.mil>.
+
+ Added test/Makefile to shar as per Chris Pribe
+ <cpribe@park.bu.edu>.
+
+4/4/91 2.48 Fixed possible problem with poll in inter_poll.c for systems
+ that check for a valid address even though no members are used.
+
+3/27/91 2.47 Added support for Cray Unicos 6.0, which of course is different
+ from Unicos 5.1 (which was different from everything else)!
+ This and other minor bugs fixed courtesy of Pete Termaat.
+
+3/19/91 2.46 Removed a "feature" which caused patterns with no whitespace
+ not to be run through SplitList. While not documented not to
+ do so, this was mystifying even to me when I saw it. For
+ William Waite. The result actually simplified the internal
+ handling of multiple patterns, removing some excessively
+ complex logic that I thought would be helpful for speed, but
+ that in retrospect, was not that important.
+
+3/16/91 2.45 Added my own definition of FD_SET, fd_set, etc, test for
+ SIGABRT, and support different types of signal arg func
+ definitions to support SunOS 3.5 as requested by William Waite
+ <waite@scotty.colorado.edu>.
+
+3/14/91 2.44 Removed redundant def'n of pty_stty in pty_usg.c, redef of
+ sprintf and added signal.h to command.c to make compiles
+ cleaner on SV3 and HPUX machines. All compliments of Mike
+ Gourlay.
+
+3/10/91 2.43 Added -s (for slow) and -h (for human) flags to send. This
+ had been requested by several people including Frank Terhaar-
+ Yonkers (who actually wrote and tested a "send_slow" command),
+ and Steve Simmons who suggested the "human" option (over a year
+ ago), and Brian Woodson (brianw@swqa-sun.ESD.3com.com), who
+ requested both! Thanks to NIST statistician, Keith Eberhardt,
+ who taught me about the Weibull Distribution.
+
+ According to Jim Thomas <jthomas@nmsu.edu>, 3b2 requires
+ defines for R_OK and W_OK. Added to pty_usg.c.
+
+ Added support for "-" as file name on command line to mean
+ stdin as requested by Steve Clark <clark@cme.nist.gov>.
+
+ Wrote passmass (change root password on a set of machines) as
+ requested by Ken Manheimer <klm@cme.nist.gov>. Added to test
+ directory.
+
+2/21/91 2.42 Removed reinstallation of signal 0 in signal handler.
+
+ Added hook for setting initial pty parameters when started in
+ the background. Should've done this a long time ago, but I
+ was never really happy with my solution and had hoped I would
+ think of a nicer method. I only hope this is clean enough.
+
+2/10/91 2.41 Added buffer_full keyword to solve Brian Fitzgerald's problem.
+ It disables "forgetfullness" so that when expect's internal
+ buffer hits match_max, whatever it has returns at that point.
+ Didn't add this to the library version, because I want to think
+ for awhile about the cleanest way to do it.
+
+2/4/91 2.40 Per Brian Fitzgerald (fitz@mml0.meche.rpi.edu), fixed error in
+ interact example on man page which incorrectly implied that
+ "kill" was built-in.
+
+ Added fork/disconnect functions. This solved the problem of
+ Jerry Friesen (jafries@snll-arpagw.llnl.gov) who wanted to run
+ an expect script that asks for a password and then goes to
+ sleep for awhile before waking up to run in the background (to
+ run a program using Kerberos).
+
+1/30/91 2.39 Per Jim Johnson (jaj@mlb.semi.harris.com), added declaration
+ and documentation for exp_pid in libexpect.
+
+1/10/91 2.38 More mods from Frank Terhaar-Yonkers. Also, some requests
+ from Pete TerMaat (pete@willow.cray.com) for features:
+
+ 1) a single-step facility. Yeah, that would be nice. No
+ ideas on how to do this easily.
+
+ 2) Generate scripts automatically after watching a session.
+ This is hard. Read more about this in the FAQ.
+
+1/10/91 2.37 Added support for Cray Unicos 5.1, all courtesy of Frank
+ Terhaar-Yonkers (fty@sunvis.rtpnc.epa.gov). Most of it had to
+ do with pty support.
+
+1/8/91 2.36 Modified expect.h to support C++ and ANSI prototypes. Added
+ appropriate example in test directory based on chesslib.c.
+
+1/7/91 2.35 At the request of Jan Norden (jano@imdpy1.im.se) added
+ NO_MEMCPY and NO_STRING_H defines for Pyramid.
+
+1/3/91 2.34 Added a check to protect against a longjmp occurring between
+ i_read and alarm(0). Didn't think this would be a problem but
+ evidentally a function return modifies the stack, so it cannot
+ be returned to again. Drat! This appeared in the robohunt
+ script I wrote which plays hunt automatically and uses 1
+ second timeouts.
+
+12/19/90 2.33 Add signal to sighandler, to reinstall signal for those systems
+ that need it.
+
+12/12/90 2.32 Removed test for args to expect. I only recently realized that
+ no args still allows a valid way to check for timeout and eof!
+
+12/6/90 2.30-1 Mike Gourlay (mike@penguin.gatech.edu) found and fixed quite a
+ few SV-related problems that I had introduced since Clem's
+ fixes. We eventually got it to run on his HPUX machine, a
+ mixed breed of BSD/USG stuff. But spawning a shell worked but
+ always produced a complaint about "no access to tty" which we
+ were never able to get rid of, and he had a problem with
+ exp_fexpect (but not exp_expect), although it still isn't clear
+ if that was expect's fault. He said he would speak to some HP
+ engineers about what he found.
+
+12/5/90 2.29 Fixed a malloc off-by-one bug in new C library. After
+ contemplation, revised interfaces. Decided that rather than
+ following the original 'expect' style, it should be more like
+ what a C programmer is used to, so I made the file descriptors
+ be parameters to exp_expect rather than globals, added an
+ exp_popen which is a popen equivalent, and added exp_fexpect
+ versions which are stream equivalents.
+
+ Am not happy with exp_fexpect. It is much less efficient than
+ exp_expect, because there is no way to (portably) get fread()
+ to return the way read() does, with less then the number of
+ characters you supplied a buffer for. Instead, I have to call
+ fgetc for every char. Ugh.
+
+ Add a couple new examples, including lpunlock, time.exp,
+ chesslib.c (using file descriptors) and chesslib2.c (which uses
+ stream pointers).
+
+12/3/90 2.28 Created C library version of expect.
+
+11/29/90 2.27 Fixed bug in interact - when no string actions were defined,
+ the mapping table length wasn't set at all.
+
+ Made interact call printify when debugging so that crlf and
+ other nonprintables are visible. Fixed bug in printify which
+ interpreted some characters wrong due to parity.
+
+ Added some more examples to the distribution (lpunlock, dvorak,
+ timed_read) and put in another tip in the TCL HINTS section of
+ the man page.
+
+11/18/90 2.26 Fixed mismatched comment per Craig Warren (ccw@deakin.oz.au).
+ Also improved man page entry for "interact".
+
+11/17/90 2.25 Added -f (fast) on interact options, and made default case a
+ little more efficient. Added explicit support for SIG_IGN and
+ SIG_DFL in trap command. Added ability to specify signals
+ symbolically for portability.
+
+11/15/90 2.24 Craig Warren (ccw@deakin.oz.au) wanted to exit expect while in
+ interact with a single character. Dan Bernstein
+ (brnstnd@kramden.acf.nyu.edu) wanted to suspend with a single
+ character. So I generalized interact's escape character to
+ string-action pairs.
+
+11/7/90 2.23 Tired of getting reports that various (Ultrix 3.1, BSD4.3) C
+ compilers can't handle ternary conditionals returning ptr to
+ func returning void. Made all (2) such statements into
+ if-then-elses. Per Steve Simmons (scs@iti.org).
+
+10/8/90 2.22 Allow "log_file" even when no log is open. This makes user
+ programming a little simpler - they don't have to remember
+ whether they opened the log or not.
+
+9/27/90 2.21 Fixed bug, v2.19 introduced. debuglog(unknown string) requires
+ a "%s" as formatting for protection against %'s in the unknown
+ string.
+
+9/17/90 2.20 4 syntax errors in interact_poll.c, vik@sequent.com. Added
+ quotes to all the sends (now that this is more efficient) in
+ the examples and man pages. Also removed a misstatement in the
+ man page about the behavior of double quotes.
+
+9/15/90 2.19 Removed buffering from send command. Originally, I buffered
+ the args, so I could do it all in one write. But to send
+ variables bigger than the buffer didn't work. I didn't think
+ about this before. But Joe Gorman
+ (Joe.Gorman@elab-runit.sintef.no) asked me if you could "send"
+ a file in one command, and of course you can using [exec cat]
+ as the argument to send, but the damn buffering prevented big
+ files from being sent. Anyway, now it works.
+
+9/14/90 Fixed the declarations of nflog and nferrlog. Added a #define
+ so lack of pid_t could be controlled from the Makefile. Per
+ Andy Holyer (and@ux.rfhsm.lon.ac.uk)
+
+9/4/90 2.18 Added trap command to catch signals. This is nice as (among
+ other things) it allows you to turn off the conversion of ^C to
+ timeout which was requested by John Conti <jconti@cisco.com>.
+
+8/21/90 2.17 Fixed bug in printify. Forgot to reset ptr to beginning of
+ print buffer. Made debugging info wrong. Possibly screwing up
+ other things on overflow.
+
+ Paper accepted into USENIX LISA!
+
+8/15/90 Cleaned up man page. Made tabs line things up correctly,
+ finally.
+
+ Found another problem with ptys (at least under SunOS 4.1 and
+ earlier). When last pty-slave fd closed, any unread output is
+ lost after a short window of time (around 10 seconds on a
+ Sun 3/60). Sent example ptybug.c to Sun demonstrating this and
+ EIO problem found earlier. (Service Order #553061)
+
+8/6/90 2.16 Added -f to debug command, -a to log_file command. This
+ required significant changes, including revisiting all the
+ logging routines, plus miscellaneous output done in special
+ places. Noted that it cannot be done with getopt, since it
+ could be called during main's getopt, and getopt is not
+ reentrant! (Guess how I discovered this!!)
+
+ I'm not particularly happy with the design, but maybe others
+ won't be. In any case, I like the benefit of it and am now
+ glad that -a was asked for. Per Harry Bochner and Ira Fuchs
+ (fuchs@pucc.bitnet).
+
+ Changed behavior of argv, so that 0 == [length $argv] when no
+ script/args supplied.
+
+8/4/90 2.15 Added debug command, so -d-ness could be changed while expect
+ is running.
+
+7/20/90 2.14 Fixed small bug in -d output from expect, which printed ^Z as
+ ^:
+
+7/18/90 2.13 Added wait command. A waitpid/waitspawnid would be nice and
+ cleaner, too, but since csh doesn't need it, it is probably not
+ worth much.
+
+ Consequently, removed SIGCHLD handling from command.c. It
+ worked under SV but not BSD. By forcing users to explicitly
+ code waits, resulting scripts are more portable.
+
+ Rewrote rogue example. rogue sometimes misses EOF (generated
+ by close on our side) and continues reading.
+
+7/16/90 2.12 Removed buffering from variadic log routines. This was
+ faulting when the buffers overflowed.
+
+ Cleaned up the -d output from expect, so it is much more
+ readable. For example, control characters are now visible.
+
+7/14/90 2.11 Added declaration for errno, to support 4.3BSD. Per Alan
+ Crosswell. Added -i flag and related behavior.
+
+7/12/90 2.10 Fixed bug where timeout = 0 waited forever rather than not
+ waiting at all.
+
+7/11/90 Fixed man page example which didn't include the blank on the
+ end of an ftp prompt.
+
+7/9/90 2.9 Fixed bug in send when spawn_id = $user_spawn_id.
+
+6/27/90 2.8 Integrated some mods from clem cole (clemc@ccc.com) to support
+ System V.3 (386/ix Version 2.02). Unfortunately, he didn't do
+ "select".
+
+6/25/90 2.7 Test that cmdfile and logfile are open before fclosing in child
+ while spawning. Per Corey Satten <corey@cac.washington.edu>
+
+6/24/90 2.6 Pty master returns EIO instead of EOF when pty slave closes.
+ Bug in pty driver? Until I figure this out, I have put in code
+ to interpret EIO to EOF.
+
+6/21/90 Added new section to expect man page - Tcl hints.
+
+6/14/90 Spoke at USENIX. Went well. Added USENIX paper as separate
+ ftp archive.
+
+6/4/90 2.5 Fixed bug in ^C catching during expect. Changed man page to
+ accurately describe what ^C does. Fixed bug that caused "send"
+ to screw up when handed 0 arguments. All per Harry Bochner.
+
+6/1/90 2.4 Made trailing empty action in expect optional, primarily to
+ make straightline code easier to read.
+
+5/15/90 2.3 Changed expect to strip nulls from program output since there
+ is no way for Tcl to handle them, per Harry Bochner.
+
+5/5/90 Added "send_error" command.
+
+4/26/90 Got USENIX paper back from Kolstad to proof. Am depressed at
+ how awfully they formatted it.
+
+4/25/90 2.2 Eric Newton found that expect's special variables weren't being
+ found inside of user subroutines. Had to do with new Tcl,
+ which now differentiates between variables that are undefined
+ vs. empty.
+
+4/24/90 Upgraded Tcl from 2.1 to 3.3.
+
+4/22/90 Added special behaviors of ^C in expect, and when profiling.
+ Profiled rogue (at urging of Ousterhout).
+
+4/10/90 2.1 Added select command. Added support for user_spawn_id so that
+ you could treat user just like another process (i.e. with send
+ and expect). Decided to leave send_user/expect, since scripts
+ are more readable with them.
+
+4/2/90 2.0 Changed syntax of expect to provide alternatives (a la Tcl
+ case), per suggestion of John Ousterhout. Note that this
+ breaks pre-2.0 scripts.
+
+3/31/90 Got great comments from Ousterhout. (This time he said that he
+ really liked the idea. Maybe he realizes how much it will
+ promote Tcl!)
+
+3/30/90 Got comments from dpk. Made me think more about Perl.
+
+3/28/90 Evi said I should turn the paper in unformatted and they will
+ format it. (She's kidding, I hope.)
+
+3/27/90 1.8 Rewrote interface so that raw arguments can be passed in like a
+ shell. I'd been thinking about this for some time, but Eric
+ Newton finally prodded me into action.
+
+3/25/90 Got first corrections for paper - from Sue Mulroney!
+
+3/24/90 Observed that it is possible to use the #! syntax with expect.
+ I asked John O. about this (his choice of # as a comment
+ character), and he said it was pure coincidence. Deprecated
+ request to end scripts in ".exp".
+
+ Ted Hopp volunteered to be my Center WERB reader.
+
+3/23/90 Finished 1st draft of USENIX paper and sent copies to John
+ Ousterhout and panel chair, dpk@morgan.com.
+
+3/20/90 1.7 Deprecated "stty", and added more general "system" command.
+
+ Sent Evi some complaints about the business of not allowing
+ camera-ready at USENIX.
+
+3/17/90 Sent copies of man page to Doug Gwyn and Larry Wall for
+ comments. Note that gwyn downloaded it.
+
+3/16/90 Am really irritated by USENIX. My paper has been put in a
+ session against another session, the BSD people. Furthermore,
+ they called my paper an application, when it is no more so than
+ any other shell or language. Better I should be in "lessons
+ learned". Mashey said take a hike, i.e., it was too late to
+ change the schedule. On top of that, our session has four
+ people in it, so I'll have very little time to speak. Grrrr.
+
+3/13/90 1.6 Added "stty", because without it you can't do things like
+ turning off echo to accept a password.
+
+3/8/90 1.5 Abstract was accepted into USENIX!!!! Time to start writing
+ it! Sent man page to Ousterhout. He didn't seem too
+ impressed.
+
+ Added "send_user/expect_user" after listening to Ken complain
+ about how shell could not do timed reads. Actually it can, but
+ expect does it much more naturally. Deprecated echo. Now, I
+ realize that expect can be viewed as a shell!
+
+ Changed logfile/loguser to log_file/log_user to match all the
+ variables with underscores in them.
+
+ Barry Warsaw asked if there was any way one could execute any
+ command from interact (apparently without any reason in mind).
+ Nonetheless, it is a wonderful idea, and I changed the "abort
+ character" in interact to an "escape mechanism". After
+ escaping, you may execute any command. return duplicates the
+ old action of the abort character. Now you can do interactive
+ job control, recursive interacts, etc. You can bet I didn't
+ get this right the first time!
+
+ At Scott's request, fixed bug related to pty initializing.
+ Scott was putting expect in the background which disassociated
+ it from a tty, and I was blindly copying the tty parameters
+ without checking to see if they were meaningful or not.
+
+ Tightened up exit code. Fixed bug in spawn so it would print
+ error messages when it failed. Spawn sends back the error
+ message in the pty, if the fork succeeds but exec fails. Cute!
+
+ Added "close" command. Makes scripts much shorter and cleaner.
+
+ Return string matched by expect directly, rather than setting a
+ special variable.
+
+ Added "match_max" feature. Probably no one will ever use it.
+
+ Added trace command.
+
+3/6/90 1.4 Rob Densock was the second user, and suggested (demanded?) the
+ idea of the loguser command. I added it and changed "log" to
+ "logfile" making the first incompatibility with existing
+ scripts (sorry, Steve).
+
+3/1/90 1.3 Trying to make pty code more robust. Many questions unanswered
+ by manuals. Did a lot of guessing. While debugging, looked
+ through pty code in gnuemacs to see if I might increase
+ portability somehow. I almost barfed when I saw all the funky
+ ifdefs on weird ioctls. Found lots of comments like "this
+ might work".
+
+2/28/90 Sent a short Tcl bug list to John Ousterhout. He thanked me!
+
+2/22-3/90 1.2 Hooked my first user, Steve Ray. Surprisingly, he only found
+ one bug in the code (exit didn't handle args correctly), but it
+ was obvious that I need to put more explanation in the man
+ page. Many of the examples in the man page are based upon his
+ probl.. questions. Thanks, Steve!
+
+2/20/90 Posted news about expect to "general" newsgroup locally.
+
+2/15-20/90 Talked to local POSIX reps and then to Steve Albert (AT&T)
+ about portability of select, wait and other system calls. I'm
+ not impressed by 1003.1.
+
+2/9/90 John Ousterhout answered some questions I had about Tcl syntax.
+ I like this language!
+
+2/8/90 1.1 Sandy Ressler suggested the idea of being able to spawn
+ multiple programs at the same time although he didn't say how.
+
+ It took about a day to design and code the spawn_id hook.
+ Extremely difficult to support this with uucp-style kludge.
+ Switched to using select. So much for portability.
+
+ I investigated how to do this portably, and spent some time
+ talking to NIST & AT&T POSIX representatives. Unfortunately,
+ portability (especially when it comes to select()) remains a
+ dream. Provided multiple versions of "interact" depending upon
+ what OS you are running.
+
+2/7/90 1.0 Completed first cut of "sex" (for "Smart EXec" or
+ "Send/EXpect"). Supports send, expect, echo, log, spawn,
+ interact.
+
+ Spent a lot of time making "log" write to log in just the right
+ order (across fork and while debug flag enabled). Ended up
+ writing a bunch of variadic log routines.
+
+ Fooled around with uucp-style multiple processes versus one
+ process doing select() to read asynchronously. Using
+ uucp-style for now, since it is more portable.
+
+ Gave up on pipes, and switched to ptys. Pipes seem to be
+ messed up by ftp, perhaps because it goes into raw mode? Ptys
+ are more efficient and cleaner to program albeit less
+ well-documented and portable from system to system.
+
+ Ken Manheimer helped me explain what the program does. I kept
+ saying it does "send/expect" processing, and he kept insisting
+ that was meaningless to everyone. (In fact, it comes from
+ uucp, and I guess uucp hackers are indeed a dying breed.) Ken
+ gave me an elegant enough sentence that I expanded it into an
+ abstract and sent it in to the USENIX conference the following
+ day (two days after the deadline).
+
+ I noted that the uucp documentation I referenced in the
+ submission is dated October 31, 1978!
+
+1/30/90 0.0 Got a copy of Tcl and went to work. Tcl was exactly what I
+ need. Plus, it is easy to use, AND it is documented.
+
+1/25/90 Attended Winter 1990 USENIX in DC, with the goal of banging
+ heads with some other gurus in hopes of finding a good
+ send/expect language for a generalized stelnet. Had looked at
+ uucp and kermit but found nothing general enough.
+
+ Listened to John Ousterhout's presentation on Tcl. By the
+ middle of the talk, I had found religion. At the end when he
+ said it was public-domain, I was ready to orgasm.
+
+*/*/88-89 Spent a lot of time telling Scott how useful his program could
+ be if he made it more general. I thought it wouldn't be that
+ difficult to make more generic. Scott was interested but not
+ enough to do it.
+
+9/25/87 Helped Scott Paisley write a program called stelnet, that
+ forked a telnet and did very simple send/expect processing.
+ It used pipes, not ptys. It had no pattern matching, and only
+ straight-line control without error handling. Nonetheless,
+ this got me to thinking about making stelnet more generic.
diff --git a/expect/INSTALL b/expect/INSTALL
new file mode 100644
index 00000000000..1b6680dd841
--- /dev/null
+++ b/expect/INSTALL
@@ -0,0 +1,253 @@
+This file is INSTALL. It contains installation instructions for Expect.
+
+If you do not have Tcl, get it (Expect's README explains how) and
+install it. The rest of these instructions assume that you have Tcl
+installed.
+
+If you are installing Expect on a single architecture, or are just
+trying it out to see whether it is worth installing, follow the
+"Simple Installation" below. If you are installing Expect on multiple
+architectures or the "Simple Installation" instructions are not
+sufficient, see "Sophisticated Installations" below.
+
+--------------------
+Permissions
+--------------------
+
+On a Cray, you must be root to compile Expect. See the FAQ for why
+this is.
+
+If you want shared libs on Linux, you must be root in order to run
+ldconfig. See the ldconfig man page for more info.
+
+--------------------
+Simple Installation
+--------------------
+
+By default, the Tcl source directory is assumed to be in the same
+directory as the Expect source directory. For example, in this
+listing, Expect and Tcl are both stored in /usr/local/src:
+
+ /usr/local/src/tcl8.0 (actual version may be different)
+ /usr/local/src/expect-5.24 (actual version may be different)
+
+If Tcl is stored elsewhere, the easiest way to deal with this is to
+create a symbolic link to its real directory. For example, from the
+Expect directory, type:
+
+ ln -s /some/where/else/src/tcl8.0 ..
+
+The same applies for Tk, if you have it. (Tk is optional.)
+
+Run "./configure". This will generate a Makefile (from a prototype
+called "Makefile.in") appropriate to your system. (This step must be
+done in the foreground because configure performs various tests on
+your controlling tty. If you want to do this step in the background
+in the future, automate it using Expect!)
+
+Most people will not need to make any changes to the generated
+Makefile and can go on to the next step. If you want though, you can
+edit the Makefile and change any definitions as appropriate for your
+site. All the definitions you are likely to want to change are
+clearly identified and described at the beginning of the file.
+
+To build only the stand-alone Expect program, run "make expect". This
+is appropriate even if you still haven't decided whether to install
+Expect, are still curious about it, and want to do the minimum
+possible in order to experiment with it.
+
+To build everything, run "make". If "configure" found Tk and X on
+your system, this will build "expectk" (Expect with Tk).
+
+Once expect is built, you can cd to the example directory and try out
+some of the examples (see the README file in the example directory).
+
+"make install" will install Expect. If you built Expectk, that will
+be installed as well. So will the documentation and some of the most
+useful examples.
+
+If you want shared libs on Linux, you must now su to root and run
+ldconfig on the shared library. See the ldconfig man page for more
+info.
+
+A handful of people running "pure" 4.2BSD systems have noted that
+expect fails to link due to lack of getopt and vprintf. You can get
+these from uunet or any good archive site.
+
+--------------------
+Sophisticated Installations
+--------------------
+
+The following instructions provide some suggestions for handling
+complex installations.
+
+--------------------
+Changing Defaults
+--------------------
+
+The configure script allows you to customize the Expect configuration
+for your site; for details on how you can do this, type "./configure
+-help" or refer to the autoconf documentation (not included here).
+Expect's configure supports the following flags in addition to the
+standard ones:
+
+ --verbose Cause configure to describe
+ what it is checking and what it decides.
+
+ --enable-shared Compile Expect as a shared library if it
+ can figure out how to do that on this
+ platform. (You must have already
+ compiled Tcl with this flag.)
+
+ --disable-load This switch is ignored so that you can
+ configure Expect with the same configure
+ command as Tcl. If you want to disable
+ dynamic loading, configure Tcl with this
+ flag and then reconfigure Expect.
+
+ --enable-gcc This switch is ignored so that you can
+ configure Expect with the same configure
+ command as Tcl. If you want to enable gcc,
+ configure Tcl with it and then reconfigure
+ Expect. Expect will inherit the definition
+ that way. It is not safe to modify the
+ Makefile to use gcc by hand. If you do
+ this, then information related to dynamic
+ linking will be incorrect.
+
+ --with-tclconfig=... Specifies the directory containing Tcl's
+ configure file (tclConfig.sh).
+
+ --with-tclinclude=... Specifies the directory containing Tcl's
+ private include files (such as tclInt.h)
+
+ --with-tkconfig=... Specifies the directory containing Tk's
+ configure file (tkConfig.sh).
+
+ --with-tkinclude=... Specifies the directory containing Tk's
+ private include files (such as tkInt.h)
+
+Some of the defaults in "configure" can be overridden by environment
+variables. This is a convenience intended for environments that are
+likely to affect any program that you configure and install.
+
+The following environment variables are supported. If you use these,
+consider adding them to your .login file so that other installation
+scripts can make use of them.
+
+CC C compiler
+CFLAGS Flags to C compiler
+CPPFLAGS Flags to C preprocessor
+LDFLAGS Flags to linker
+LIBS Libraries
+CONFIG_SHELL Shell for configure and Make
+
+Settings can also be given on the command line. For example, you
+could tell configure about flags from a Bourne-compatible shell as
+follows:
+
+ CFLAGS=-O2 LIBS=-lposix ./configure
+
+Although configure will do some searching for Tcl (and all of this
+discussion holds true for Tk as well), configure likes to find the Tcl
+source directory in the parent directory of Expect and will use that
+Tcl if it exists. To make sure Tcl can be found this way (if it is
+located somewhere else), create a symbolic link in Expect's parent
+directory to where the Tcl directory is.
+
+By default, configure uses the latest Tcl it can find. You can
+override this by creating a symbolic link of "tcl" which points to the
+release you want.
+
+If you can't or don't want to create symbolic links, you can instead
+indicate where Tcl and Tk are by using the following environment variables:
+
+with_tclconfig Directory containing Tcl configure file (tclConfig.h)
+with_tclinclude Directory containing Tcl include files
+with_tkinclude Directory containing Tk include files
+with_tkconfig Directory containing Tk binary library (tkConfig.h)
+
+--------------------
+Multiple-Architecture Installation
+--------------------
+
+You might want to compile a software package in a different directory
+from the one that contains the source code. Doing this allows you to
+compile the package for several architectures simultaneously from the
+same copy of the source code and keep multiple sets of object files on
+disk.
+
+To compile the package in a different directory from the one
+containing the source code, you must use a version of make that
+supports the VPATH variable. GNU make and most other recent make
+programs can do this.
+
+cd to the directory where you want the object files and executables to
+go and run configure. configure automatically checks for the source
+code in the directory that configure is in and in .. If configure
+reports that it cannot find the source code, run configure with the
+option --srcdir=dir, where dir is the directory that contains the
+source code.
+
+You can save some disk space by installing architecture-independent
+files (e.g., scripts, include files) in a different place than
+architecture-dependent files (e.g., binaries, libraries). To do this,
+edit the Makefile after configure builds it, or have configure create
+the Makefile with the right definitions in the first place. To have
+configure do it, use the following options to configure:
+
+ --prefix=indep
+ --exec-prefix=dep
+
+where dep is the root of the tree in which to store
+architecture-dependent files and indep is the root in which to
+store -dependent files. For example, you might invoke configure this
+way:
+
+ configure --prefix=/usr/local/bin --exec-prefix=/usr/local/bin/arch
+
+--------------------
+Test Suite
+--------------------
+
+Patterned after the Tcl test suite, I have begun building a test suite
+in the subdirectory "test". It is still incomplete however you may
+use by typing "make test" in this directory. You should then see a
+printout of the test files processed. If any errors occur, you'll see
+a much more substantial printout for each error. See the README file
+in the "tests" directory for more information on the test suite.
+
+Note that the test suite assumes the existence of certain programs to
+use as interactive programs. If you are missing these or they behave
+differently, errors may be reported. Similarly, the test suite
+assumes certain other things about your system, such as the sane stty
+parameters.
+
+You may also try some of the programs distribute in the example
+directory (see the README file in the example directory). They are a
+strong indication of whether Expect works or not. If you have any
+problems with them, let me know.
+
+--------------------
+Uninstalling
+--------------------
+
+"make uninstall" removes all the files that "make install" creates
+(excluding those in the current directory).
+
+--------------------
+Cleaning Up
+--------------------
+
+Several "clean" targets are available to reduce space consumption of
+the Expect source. The two most useful are as follows:
+
+"make clean" deletes all files from the current directory that were
+created by "make"
+
+"make distclean" is like "make clean", but it also deletes files
+created by "configure"
+
+Other targets can be found in the Makefile. They follow the GNU
+Makefile conventions.
+
diff --git a/expect/Makefile.in b/expect/Makefile.in
new file mode 100644
index 00000000000..18941cc7f06
--- /dev/null
+++ b/expect/Makefile.in
@@ -0,0 +1,834 @@
+#
+# Makefile for Expect
+#
+
+# Requires at least Tcl 7.5
+# Known to work with up to Tcl 7.5
+
+# While Tk is optional, if you do use Tk, it must be at least Tk 4.1
+# Known to work with up to Tk 4.1
+
+VERSION_FULL = \"@EXP_VERSION_FULL@\"
+# Tcl's tclConfig requires VERSION have a short-style version string.
+VERSION = @EXP_VERSION@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+SUBDIRS = @subdirs@
+
+EXEEXT = @EXEEXT@
+
+######################################################################
+# The following lines are things you may want to change
+######################################################################
+
+# Tcl include files. (If you haven't installed Tcl yet, read the README file).
+# This must point to the directory that contains ALL of Tcl's include
+# files, not just the public ones.
+TCLHDIR = @TCLHDIR@
+ITCLHDIR = @ITCLHDIR@
+TCLHDIRDASHI = @TCLHDIRDASHI@
+# Tcl's Tcl library (definitions of parray, etc)
+TCL_LIBRARY = @TCL_LIBRARY@
+
+# Tcl library uninstalled. Should be something like -ltcl or ../tcl/libtcl.a
+TCLLIB = @TCL_BUILD_LIB_SPEC@
+ITCLLIB = @ITCLLIB@
+# Tcl library installed. Should be something like -ltcl or ../tcl/libtcl.a
+TCLLIB_INSTALLED = @TCL_LIB_SPEC@
+
+# The following definitions are only nec. if you want to use Tk with Expect.
+# Tk include files
+TKHDIR = @TKHDIR@
+TKHDIRDASHI = @TKHDIRDASHI@
+
+# Tk library
+TKLIB = @TK_BUILD_LIB_SPEC@
+TKLIB_INSTALLED = @TK_LIB_SPEC@
+
+# X11 include files and other flags to compiler
+X11_CFLAGS = @TK_XINCLUDES@
+# X library
+X11_LD_FLAGS =
+# XXX Temporarily commented out until expectk is working again.
+#X11_PROGS = @X_PROGS@
+# X11_PROGS_INSTALLED should really be a separate symbol generated by configure but we're
+# hitting configure's limit on substitutions, so be crude and use one less symbol.
+# XXX Temporarily commented out until expectk is workign again.
+#X11_PROGS_INSTALLED = @X_PROGS@
+
+# Flags to pass to both cc and ld
+# You should be able to leave this just the way it is. However, here are some
+# note if you run into problems:
+#
+# Avoid -O (optimize) unless you are convinced your optimizer is flawless
+# (hint: not a chance). I have heard many reports of -O causing Expect to
+# misbehave.
+# I encourage you to use -g (debugging). While it is unlikely you will
+# encounter an internal error in Expect, should this happen, I may just need
+# the -g information and then you will need to recompile Expect. As an aside,
+# Expect is not a space or time pig, so this won't affect the performance of
+# your Expect scripts.
+# Note: On Linux systems which only have dynamic X libraries, the -g prevents
+# the linker from using them. So do not use -g on such systems.
+# From now on, CFLAGS is never used. Instead, use XCFLAGS. This is done so
+# that we can provide a public interface for CFLAGS thereby allowing users
+# to add to it on the Make command-line and still get the rest of the flags
+# computed by configure. Do this at your own risk - it obvious goes against
+# the idea of configure's interface, however this is established tradition
+# at some sites (e.g., Cygnus)!
+CFLAGS = @CFLAGS@
+XCFLAGS = $(CFLAGS) @EXP_CFLAGS@ @EXP_SHLIB_CFLAGS@
+#XCFLAGS = @CFLAGS@ @EXP_CFLAGS@ @EXP_SHLIB_CFLAGS@
+XCFLAGS = @CFLAGS@ @EXP_CFLAGS@
+
+# Flags to pass only to linker (after .o files but before libraries)
+LDFLAGS = @EXP_LDFLAGS@
+
+# Which C compiler to use. For simplicity, we inherit the same definition
+# used when Tcl was compiled. Changing this definition here can screw up
+# deductions that the configure script made on the assumption that you were
+# using a different compiler.
+CC = @CC@
+
+# By default, "make install" will install the appropriate files in
+# /usr/local/bin, /usr/local/lib, /usr/local/man, etc. By changing this
+# variable, you can specify an installation prefix other than /usr/local.
+# You may find it preferable to call configure with the --prefix option
+# to control this information. This is especially handy if you are
+# installing Expect several times (perhaps on a number of machines or
+# in different places). Then you don't have to hand-edit this file.
+# See the INSTALL file for more information. (Analogous information
+# applies to the next variable as well.)
+prefix = @prefix@
+
+# You can specify a separate installation prefix for architecture-specific
+# files such as binaries and libraries.
+exec_prefix = @exec_prefix@
+
+# The following Expect scripts are not necessary to have installed as
+# commands, but are very useful. Edit out what you don't want installed.
+# The INSTALL file describes these and others in more detail.
+# Some Make's screw up if you delete all of them because SCRIPTS is a
+# target. If this is a problem, just comment out the SCRIPTS target itself.
+SCRIPTS = timed-run timed-read ftp-rfc autopasswd lpunlock weather \
+ passmass rftp kibitz rlogin-cwd xpstat tkpasswd dislocate xkibitz \
+ tknewsbiff unbuffer mkpasswd cryptdir decryptdir autoexpect
+# A couple of the scripts have man pages of their own.
+# You can delete these too if you don't want'em.
+SCRIPTS_MANPAGES = kibitz dislocate xkibitz tknewsbiff unbuffer mkpasswd \
+ passmass cryptdir decryptdir autoexpect
+
+# Short directory path where binary can be found to support #! hack.
+# This directory path can be the same as the directory in which the binary
+# actually sits except when the path is so long that the #! mechanism breaks
+# (usually at 32 characters).
+# The solution is to create a directory with a very short name, which consists
+# only of symbolic links back to the true binaries. Subtracting two for "#!"
+# and a couple more for arguments (typically " -f" or " --") gives you 27
+# characters. Pathnames over this length won't be able to use the #! magic.
+# For more info on this, see the execve(2) man page.
+SHORT_BINDIR = @bindir@
+
+# If you have ranlib but it should be avoided, change this from "ranlib"
+# to something innocuous like "echo". Known systems with this problem:
+# older SCO boxes.
+RANLIB = @TCL_RANLIB@
+UNSHARED_RANLIB = @UNSHARED_RANLIB@
+
+# Change EVENT_ABLE to "noevent" if your system is:
+# old SCO because poll doesn't exist and select is broken on ptys
+# 3b2 SVR3 because select doesn't exist and poll is broken on ptys
+# If you do use "noevent":
+# 1) you must also edit expect_cf.h and change
+# "#undef SIMPLE_EVENT" to "#define SIMPLE_EVENT",
+# 2) you cannot use any event facilities such as "after" or anything in Tk.
+# 3) you cannot expect or interact with two or more processes simultaneously
+#
+EVENT_ABLE = @EVENT_ABLE@
+
+# Change EVENT_TYPE to poll if your system is:
+# NCR SVR4 (1.03.01) where select is broken on ttys
+# StarServer (SVR3 and SVR4.0) where select is broken on ttys
+#
+# You will need to change EVENT_TYPE to select if your system is:
+# Pyramid OSx in the att universe where poll is broken (see LIBS below)
+#
+EVENT_TYPE = @EVENT_TYPE@
+
+# Define default parameters for ptys. This is used when 1) running in the
+# background, 2) user has not defined the variable STTY_INIT to initialize
+# ptys, and 3) the pty-driver's defaults suck.
+#
+# If your system doesn't understand "sane", try "cooked". Apollo systems
+# need nothing at all and should delete this line. Systems using 8-bit
+# character sets may need to disable parity.
+# Systems that define sane to use @ as line kill and # as erase should
+# use something like "sane kill  erase ".
+STTY = -DDFLT_STTY="\"@DEFAULT_STTY_ARGS@\""
+
+######################################################################
+# End of things you may want to change
+#
+# Do not change anything after this
+######################################################################
+
+bindir = @bindir@
+bindir_arch_indep = $(prefix)/bin
+libdir = @libdir@/expect$(VERSION)
+tcl_libdir = @libdir@
+# CYGNUS LOCAL: use datadir, not $(prefix)/lib.
+libdir_arch_indep = @datadir@
+# END CYGNUS LOCAL
+
+mandir = @mandir@
+man1dir = $(mandir)/man1
+man3dir = $(mandir)/man3
+infodir = @infodir@
+includedir = @includedir@
+
+# Expect's utility script directories - arch-independent and arch-non-
+# independent. These correspond to the variables "exp_library" and
+# "exp_exec_library".
+SCRIPTDIR = $(libdir_arch_indep)
+EXECSCRIPTDIR = $(libdir)
+
+SHELL = @EXP_CONFIG_SHELL@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+AR = ar
+ARFLAGS = cr
+
+LOCAL_EXPECT=LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./expect$(EXEEXT)
+
+# These definitions are used by the "subdirs_do" target to pass
+# the compile flags down recursively.
+FLAGS_TO_PASS = \
+ "CC=$(CC)" \
+ "CFLAGS=$(XCFLAGS)" \
+ "CFLAGS_INT=$(CFLAGS_INT)" \
+ "HDEFS=$(HDEFS)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "RUNTEST=$(RUNTEST)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+ "SHLIB_CFLAGS=$(@EXP_SHLIB_CFLAGS@)" \
+ "prefix=$(prefix)" \
+ "exec_prefix=$(exec_prefix)"
+
+#
+# Following defines are for DejaGnu
+#
+
+# These let the DejaGnu test suite run when DejaGnu isn't
+# installed yet, so run it from the srcdir and objdir.
+EXPECT = ` \
+ if [ -f $${rootme}/expect$(EXEEXT) ] ; then \
+ echo $${rootme}/expect$(EXEEXT) ; \
+ else echo expect ; fi`
+
+RUNTESTFLAGS =
+RUNTEST = ` \
+ if [ -f ${srcdir}/../dejagnu/runtest$(EXEEXT) ] ; then \
+ echo ${srcdir}/../dejagnu/runtest$(EXEEXT) ; \
+ else echo runtest ; fi`
+
+PTY_TYPE = @PTY_TYPE@
+PTY = pty_$(PTY_TYPE)
+CFILES = exp_command.c expect.c $(PTY).c \
+ exp_inter.c exp_regexp.c exp_tty.c \
+ exp_log.c exp_main_sub.c exp_pty.c \
+ exp_printify.c exp_trap.c exp_strf.c \
+ exp_console.c exp_glob.c exp_win.c Dbg.c exp_clib.c \
+ exp_closetcl.c exp_memmove.c exp_tty_comm.c \
+ exp_$(EVENT_TYPE).c exp_$(EVENT_ABLE).c
+OFILES = exp_command.o expect.o $(PTY).o exp_inter.o exp_regexp.o exp_tty.o \
+ exp_log.o exp_main_sub.o exp_pty.o exp_printify.o exp_trap.o \
+ exp_console.o exp_strf.o exp_glob.o exp_win.o Dbg.o exp_clib.o \
+ exp_closetcl.o exp_memmove.o exp_tty_comm.o \
+ exp_$(EVENT_TYPE).o exp_$(EVENT_ABLE).o
+SHARED_OFILES = shared/exp_command.o shared/expect.o shared/$(PTY).o \
+ shared/exp_inter.o shared/exp_regexp.o shared/exp_tty.o \
+ shared/exp_log.o shared/exp_main_sub.o shared/exp_pty.o \
+ shared/exp_printify.o shared/exp_trap.o \
+ shared/exp_console.o shared/exp_strf.o shared/exp_glob.o \
+ shared/exp_win.o shared/Dbg.o shared/exp_clib.o \
+ shared/exp_closetcl.o shared/exp_memmove.o shared/exp_tty_comm.o \
+ shared/exp_$(EVENT_TYPE).o shared/exp_$(EVENT_ABLE).o
+
+# Expect libraries (both .a and shared)
+EXP_LIB_FILES = @EXP_LIB_FILES@
+# default Expect library (shared if possible, otherwise static)
+EXP_LIB_FILE = @EXP_LIB_FILE@
+# Expect object library (.a)
+EXP_UNSHARED_LIB_FILE = @EXP_UNSHARED_LIB_FILE@
+# Expect object library (shared, if possible)
+EXP_SHARED_LIB_FILE = @EXP_SHARED_LIB_FILE@
+
+# expect must be setuid on crays in order to open ptys (and accordingly,
+# you must run this Makefile as root).
+# See the FAQ for more info on why this is necessary on Crays.
+SETUID = @SETUID@
+# SETUID = chmod u+s
+
+# allow us to handle null list gracefully, "end_of_list" should not exist
+SCRIPT_LIST = $(SCRIPTS) end_of_list
+SCRIPT_MANPAGE_LIST = $(SCRIPTS_MANPAGES) end_of_list
+
+# flags to pass only to the C compiler (not to ld)
+# because STTY can include whitespace and quotes, pass STTY separately
+CPPFLAGS = -I. -I$(srcdir) $(TCLHDIRDASHI) $(TKHDIRDASHI) $(X11_CFLAGS) \
+ -DEXP_VERSION=\"$(VERSION)\" \
+ -DSCRIPTDIR=\"$(SCRIPTDIR)\" \
+ -DEXECSCRIPTDIR=\"$(EXECSCRIPTDIR)\" \
+ -DTCL_DEBUGGER
+
+# Flags to pass to cc (i.e. add to the end of the CLDFLAGS line below).
+# Note that setting one will not set others automatically. Set all that
+# are relevant.
+#
+# NOTE THAT THESE FLAGS ARE NO LONGER SUPPORTED. THE FUNCTIONALLY IS REPLACED
+# BY THE AUTOMATIC CONFIGURATION CODE. ONLY MESS WITH THE FOLLOWING DEFS IF
+# YOU ARE POSITIVE THE AUTO CONFIG CODE IS FAILING.
+#
+# -DSYSV3 if you are running SVR3 or later.
+# -DSYSV4 if you are running SVR4. This option does not preclude -DSYSV3.
+# -DAUX2 if you are running Mac A/UX 2.
+# -DMIPS_BSD if you are on a Mips machine using the BSD universe.
+# -D_BSD_SIGNALS if you are on a Silicon Graphics AND want BSD semantics when
+# using the expect library. Otherwise, you are better off just sticking
+# with rearming signals.
+
+# Flags to pass to ld
+# You may need to add additional ones to the end of the LIBS line below:
+# -lc -lBSD If you are using the BSD compatibility library on an HP/UX,
+# force libc.a to be loaded first.
+# -lsocket For SCO UNIX 3.2.2 (this should now be done automatically)
+# -lX11 For Pyramid OSx, poll is broken, so use select from X lib
+# /usr/ucblib/libucb.a is needed for solaris 2.0 after -lm
+EXP_AND_TCL_LIBS = $(LDFLAGS) @EXP_AND_TCL_LIBS@
+EXP_AND_TK_LIBS = $(LDFLAGS) @EXP_AND_TK_LIBS@
+
+CFLAGS_INT = $(MH_CFLAGS) $(CPPFLAGS) $(XCFLAGS)
+
+LIB_INSTALL_DIR = $(tcl_libdir)
+LIB_RUNTIME_DIR = $(tcl_libdir)
+# I don't understand why Tcl splits these up, but it does. LIB_RUNTIME_DIR
+# can appear as part of the LD_SEARCH_FLAGS inherited by configure.
+
+.c.o:
+ $(CC) -c $(CFLAGS_INT) $(STTY) $(HDEFS) $<
+ if [ "@EXP_SHLIB_CFLAGS@" != "x" ] ; then \
+ if [ ! -d shared ] ; then \
+ mkdir shared ; \
+ else true; fi ; \
+ $(CC) -c $(CFLAGS_INT) @EXP_SHLIB_CFLAGS@ $(STTY) $(HDEFS) $< -o shared/$@ ; \
+ fi
+
+
+all: expect$(EXEEXT) $(EXP_LIB_FILES) ${X11_PROGS}
+ @$(MAKE) subdir_do DO=$@ $(FLAGS_TO_PASS)
+
+info:
+dvi:
+
+# build expect binary that does not depend on Expect's shared libs
+expect$(EXEEXT): exp_main_exp.o $(EXP_UNSHARED_LIB_FILE)
+ $(CC) $(XCFLAGS) @TCL_LD_FLAGS@ -o expect$(EXEEXT) exp_main_exp.o @EXP_BUILD_LIB_SPEC@ $(TCLLIB) $(EXP_AND_TCL_LIBS)
+ $(SETUID) expect$(EXEEXT)
+
+expecti$(EXEEXT): exp_main_exp.c $(EXP_UNSHARED_LIB_FILE)
+ $(CC) $(CFLAGS_INT) $(STTY) $(HDEFS) $(ITCLHDIR) $(XCFLAGS) @TCL_LD_FLAGS@ -o expecti$(EXEEXT) -DUSE_ITCL $(srcdir)/exp_main_exp.c @EXP_BUILD_LIB_SPEC@ $(TCLLIB) $(ITCLLIB) $(EXP_AND_TCL_LIBS)
+
+# install Expect library
+# This is done before the install target because the libraries have to be
+# in place before the installed expect is built. Actually, only the shared
+# lib has to be handled this way, but do both here for consistency.
+# Can't seem to embed shell comments in backslashed lines, so comments here:
+# - To allow bare "load" commands, install shared libs in tcl_libdir rather
+# than Expect's lib-specific directory (libdir).
+# - install hand-generated pkgIndex.tcl file.
+# Local copy is pkgIndex rather than pkgIndex.tcl because pkgIndex.tcl.in
+# is too long for some filesystems, sigh.
+install_shared_lib: $(EXP_LIB_FILES)
+ ${srcdir}/mkinstalldirs $(libdir)
+ if [ -s $(EXP_UNSHARED_LIB_FILE) ] ; then \
+ $(INSTALL_DATA) $(EXP_UNSHARED_LIB_FILE) $(libdir)/$(EXP_UNSHARED_LIB_FILE) ; \
+ $(UNSHARED_RANLIB) $(libdir)/$(EXP_UNSHARED_LIB_FILE) ; \
+ $(INSTALL_DATA) $(EXP_UNSHARED_LIB_FILE) $(tcl_libdir)/$(EXP_UNSHARED_LIB_FILE) ; \
+ $(UNSHARED_RANLIB) $(tcl_libdir)/$(EXP_UNSHARED_LIB_FILE) ; \
+ else true; fi
+ if [ -s $(EXP_SHARED_LIB_FILE) ] ; then \
+ $(INSTALL_PROGRAM) $(EXP_SHARED_LIB_FILE) $(tcl_libdir)/$(EXP_SHARED_LIB_FILE) ; \
+ $(INSTALL_PROGRAM) pkgIndex $(libdir)/pkgIndex.tcl ; \
+ else true; fi
+
+expect_installed$(EXEEXT): exp_main_exp.o $(EXP_LIB_FILE) install_shared_lib
+ $(CC) $(XCFLAGS) @EXP_SHLIB_CFLAGS@ @TCL_LD_FLAGS@ -o expect_installed$(EXEEXT) exp_main_exp.o @EXP_LIB_SPEC@ $(TCLLIB_INSTALLED) $(EXP_AND_TCL_LIBS)
+ $(SETUID) expect_installed$(EXEEXT)
+
+# Build Expect with TestCenter
+expect.tc$(EXEEXT): exp_main_exp.o $(OFILES)
+ proof $(CC) $(XCFLAGS) @EXP_SHLIB_CFLAGS@ @TCL_LD_FLAGS@ -o expect.tc$(EXEEXT) $(OFILES) exp_main_exp.o $(TCLLIB) $(EXP_AND_TCL_LIBS)
+ $(SETUID) expect.tc$(EXEEXT)
+
+# Build an executable with both Expect and Tk.
+# Yes, I know that the link line can have libraries repeated. This is a
+# consequence of Tcl's configure combining the Tcl and X dependent libs
+# together. I could fix it by testing all the libraries (again, in Expect's
+# configure) separately for Expectk, but as far as I know, it doesn't hurt
+# anything here, so I'm not worrying about it.
+expectk$(EXEEXT): exp_main_tk.o $(EXP_UNSHARED_LIB_FILE)
+ $(CC) $(XCFLAGS) @TCL_LD_FLAGS@ -o expectk$(EXEEXT) exp_main_tk.o @EXP_UNSHARED_LIB_SPEC@ $(TKLIB) $(TCLLIB) $(X11_LD_FLAGS) $(EXP_AND_TK_LIBS)
+ $(SETUID) expectk$(EXEEXT)
+
+expectk_installed$(EXEEXT): exp_main_tk.o $(EXP_LIB_FILE)
+ $(CC) $(XCFLAGS) @EXP_SHLIB_CFLAGS@ @TCL_LD_FLAGS@ -o expectk_installed$(EXEEXT) exp_main_tk.o @EXP_LIB_SPEC@ $(TKLIB_INSTALLED) $(TCLLIB_INSTALLED) $(X11_LD_FLAGS) $(EXP_AND_TK_LIBS)
+ $(SETUID) expectk_installed$(EXEEXT)
+
+# Build Expectk with TestCenter
+expectk.tc$(EXEEXT): exp_main_tk.o $(OFILES)
+ proof $(CC) $(XCFLAGS) @TCL_LD_FLAGS@ -o expectk.tc$(EXEEXT) $(OFILES) exp_main_tk.o $(TKLIB) $(TCLLIB) $(X11_LD_FLAGS) $(EXP_AND_TK_LIBS)
+ $(SETUID) expectk.tc$(EXEEXT)
+
+$(EXP_UNSHARED_LIB_FILE): $(OFILES)
+ -rm -f $(EXP_UNSHARED_LIB_FILE)
+ $(AR) $(ARFLAGS) $(EXP_UNSHARED_LIB_FILE) $(OFILES)
+ -$(RANLIB) $(EXP_UNSHARED_LIB_FILE)
+
+# the dependency should really be SHARED_OFILES rather than OFILES
+# but there's no way to write a rule that says shared/XYZ.o should
+# depend on XYZ.c in a different directory (except by writing the
+# rule out for each file, sigh).
+$(EXP_SHARED_LIB_FILE): $(OFILES)
+ -rm -f $(EXP_SHARED_LIB_FILE)
+ @TCL_SHLIB_LD@ -o $(EXP_SHARED_LIB_FILE) $(SHARED_OFILES) @EXP_LD_SEARCH_FLAGS@ @EXP_SHLIB_LD_LIBS@
+
+.PHONY: install-info install info
+install-info:
+
+# CYGNUS LOCAL: minimal/angela
+install-minimal: expect$(EXEEXT) pkgIndex
+ ${srcdir}/mkinstalldirs $(man1dir) $(bindir)
+# install Expect
+ $(INSTALL_PROGRAM) expect$(EXEEXT) $(bindir)/expect$(EXEEXT)
+# install Expect man page
+ $(INSTALL_DATA) $(srcdir)/expect.man $(man1dir)/expect.1
+# END CYGNUS LOCAL
+
+install: expect$(EXEEXT) expect_installed$(EXEEXT) ${X11_PROGS_INSTALLED} pkgIndex install_shared_lib
+ ${srcdir}/mkinstalldirs $(man1dir) $(man3dir) $(bindir) $(libdir) $(includedir)
+# install Expect
+ $(INSTALL_PROGRAM) expect_installed$(EXEEXT) $(bindir)/expect$(EXEEXT)
+# install Expectk (and man page) if present
+ -if [ -s expectk_installed$(EXEEXT) ] ; then \
+ $(INSTALL_PROGRAM) expectk_installed$(EXEEXT) $(bindir)/expectk$(EXEEXT) ; \
+ $(INSTALL_DATA) $(srcdir)/expectk.man $(man1dir)/expectk.1 ; \
+ else true; fi
+# install Expect man page
+ $(INSTALL_DATA) $(srcdir)/expect.man $(man1dir)/expect.1
+# install man page for Expect and Expectk libraries
+ $(INSTALL_DATA) $(srcdir)/libexpect.man $(man3dir)/libexpect.3
+# install Expect's public include files
+# $(INSTALL_DATA) expect_cf.h $(includedir)
+ $(INSTALL_DATA) $(srcdir)/expect.h $(includedir)
+ $(INSTALL_DATA) $(srcdir)/expect_tcl.h $(includedir)
+ $(INSTALL_DATA) $(srcdir)/expect_comm.h $(includedir)
+# force installation of Tcl's private regexp definition - we simply have to
+# make it public in order for people to use Expect's C lib.
+ $(INSTALL_DATA) $(TCLHDIR)/tclRegexp.h $(includedir)
+# install Debugger's public include file (just in case it's not there)
+ $(INSTALL_DATA) $(srcdir)/Dbg.h $(includedir)
+
+install-scripts: $(SCRIPTS)
+# some people don't install Tcl, sigh
+ TCL_LIBRARY=$(TCL_LIBRARY) ; \
+ export TCL_LIBRARY ; \
+ if $(LOCAL_EXPECT) $(srcdir)/fixcat ; then \
+ $(INSTALL_DATA) $(srcdir)/fixcat $(EXECSCRIPTDIR)/cat-buffers ; \
+ else true; fi
+# install standalone scripts and their man pages, if requested
+ ${srcdir}/mkinstalldirs $(bindir_arch_indep) $(man1dir) $(SCRIPTDIR) $(EXECSCRIPTDIR)
+ -for i in $(SCRIPT_LIST) ; do \
+ if [ -f $$i ] ; then \
+ $(INSTALL_PROGRAM) $$i $(bindir_arch_indep)/$$i ; \
+ rm -f $$i ; \
+ else true; fi ; \
+ done
+ -for i in $(SCRIPT_MANPAGE_LIST) ; do \
+ if [ -f $(srcdir)/example/$$i.man ] ; then \
+ $(INSTALL_DATA) $(srcdir)/example/$$i.man $(man1dir)/$$i.1 ; \
+ else true; fi ; \
+ done
+ $(INSTALL_DATA) pkgIndex.tcl $(SCRIPTDIR)
+
+$(SCRIPT_LIST):
+ TCL_LIBRARY=$(TCL_LIBRARY) ; \
+ export TCL_LIBRARY ; \
+ $(LOCAL_EXPECT) $(srcdir)/fixline1 $(SHORT_BINDIR) < $(srcdir)/example/$@ > $@
+
+# Delete all the installed files that the `install' target creates
+# (but not the noninstalled files such as `make all' creates)
+uninstall:
+ -rm -f $(bindir)/expectk \
+ $(man1dir)/expect.1 \
+ $(man1dir)/expectk.1 \
+ $(libdir)/$(EXP_SHARED_LIB_FILE) \
+ $(tcl_libdir)/$(EXP_SHARED_LIB_FILE) \
+ $(libdir)/$(EXP_UNSHARED_LIB_FILE) \
+ $(tcl_libdir)/$(EXP_UNSHARED_LIB_FILE) \
+ $(man3dir)/libexpect.3 \
+ $(includedir)/expect_cf.h \
+ $(includedir)/expect.h \
+ $(includedir)/expect_tcl.h \
+ $(includedir)/expect_comm.h \
+ $(EXECSCRIPTDIR)/cat-buffers
+# debugger is not removed, since other things could depend on it
+# remove standalone scripts and man pages
+ -for i in $(SCRIPT_LIST) ; do \
+ rm -f $(bindir_arch_indep)/$$i ; \
+ done
+ -for i in $(SCRIPT_MANPAGE_LIST) ; do \
+ rm -f $(man1dir)/$$i.1 ; \
+ done
+
+###################################
+# Targets for Makefile and configure
+###################################
+
+Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) config.status
+ @echo "Rebuilding the Makefile..."
+ $(SHELL) ./config.status
+
+# CYGNUS LOCAL: Don't have dependancies, cause people get upset
+# when autoconf gets run automatically.
+#configure: $(srcdir)/configure.in $(srcdir)/Makefile.in \
+# $(srcdir)/expect_cf.h.in $(srcdir)/aclocal.m4
+# Let "make -f Makefile.in" produce a configure file
+configure:
+ @echo "Rebuilding configure..."
+ if [ x"${srcdir}" = x"@srcdir@" ] ; then \
+ srcdir=. ; export srcdir ; \
+ else true ; fi ; \
+ (cd $${srcdir}; autoconf)
+
+config.status: $(srcdir)/configure
+ @echo "Rebuilding config.status..."
+ $(SHELL) ./config.status --recheck
+
+check:
+ @if [ -f testsuite/Makefile ]; then \
+ cd testsuite && $(MAKE) $(FLAGS_TO_PASS) check; \
+ else true; fi
+
+# Original Dbgconfig.in comes from the NIST Tcl debugger distribution.
+# CYGNUS LOCAL: Don't have dependancies, cause people get upset
+# when autoconf gets run automatically.
+#Dbgconfigure: $(srcdir)/Dbgconfig.in $(srcdir)/Makefile.in \
+# $(srcdir)/Dbg_cf.h.in $(srcdir)/aclocal.m4
+Dbgconfigure:
+ @echo "Rebuilding Dbgconfigure..."
+ @if [ x"${srcdir}" = x"@srcdir@" ] ; then \
+ srcdir=. ; export srcdir ; \
+ else true ; fi ; \
+ (cd $${srcdir}; rm -fr Dbgconfigure ; \
+ autoconf Dbgconfig.in > Dbgconfigure ; \
+ chmod a+x Dbgconfigure)
+
+################################################
+# Various "clean" targets follow GNU conventions
+################################################
+
+# delete all files from current directory that are created by "make"
+clean:
+ -rm -rf *~ *.o shared core \
+ expect$(EXEEXT) expect_installed$(EXEEXT) \
+ expecti$(EXEEXT) expecti_installed$(EXEEXT) \
+ expectk$(EXEEXT) expectk_installed$(EXEEXT) \
+ dumb exho devtty \
+ $(EXP_UNSHARED_LIB_FILE) $(EXP_SHARED_LIB_FILE) \
+ $(SCRIPT_LIST)
+ @$(MAKE) subdir_do DO=$@ $(FLAGS_TO_PASS)
+
+# like "clean", but also delete files created by "configure"
+distclean: clean
+ @$(MAKE) subdir_do DO=$@ $(FLAGS_TO_PASS)
+ -rm -f Makefile config.status config.cache config.log expect_cf.h
+ -rm -f Dbg_cf.h
+
+# like "clean", but doesn't delete test utilities or massaged scripts
+# because most people don't have to worry about them
+mostlyclean:
+ -rm -f *~ *.o shared core \
+ expect$(EXEEXT) expect_installed$(EXEEXT) \
+ expecti$(EXEEXT) expecti_installed$(EXEEXT) \
+ expectk$(EXEEXT) expectk_installed$(EXEEXT) \
+ $(EXP_UNSHARED_LIB_FILE) $(EXP_SHARED_LIB_FILE)
+ @$(MAKE) subdir_do DO=$@ $(FLAGS_TO_PASS)
+
+# delete everything from current directory that can be reconstructed
+# except for configure
+realclean: distclean
+
+##################################
+# Targets for development at NIST
+##################################
+
+# the unsets allow calling this via Makefile.in
+
+nist:
+ unset CC ; \
+ configure --verbose --prefix=/depot/tcl --exec-prefix=/depot/tcl/arch
+
+epg:
+ unset CC ; \
+ echo configure --verbose --prefix=/home/libes --exec-prefix=/home/libes/arch
+
+mink:
+ unset CC ; \
+ configure --verbose --prefix=/usr/tmp --exec-prefix=/usr/tmp/arch
+
+cam:
+ unset CC ; \
+ configure --verbose --prefix=/tmp_mnt/home/fs1a/libes \
+ --exec-prefix=/tmp_mnt/home/fs1a/libes/arch
+
+granta:
+ unset CC ; \
+ configure --verbose --prefix=/home/nist/libes/cray --exec-prefix=/home/nist/libes/cray/arch
+
+
+hudson:
+ unset CC ; \
+ configure --verbose --prefix=/granta/home/nist/libes/ibm --exec-prefix=/granta /home/nist/libes/ibm/arch
+
+# report globals that shouldn't be public but are
+bad_globals:
+ nm $(EXP_UNSHARED_LIB_FILE) | egrep -v " [a-zU] | _exp| _Exp| _Dbg"
+
+LINTFLAGS = -h -q -x
+
+lint:
+ lint $(LINTFLAGS) $(CPPFLAGS) $(STTY) $(CFILES) exp_main_exp.c $(TCLLINTLIB) | tee expect.lint
+
+# after copying source directory, reestablish all links
+symlink:
+ rm -rf Dbg* e ek testsuite/aclocal.m4
+ ln -s ../tcl-debug/configure.in Dbgconfig.in
+ ln -s ../tcl-debug/Makefile.in DbgMkfl.in
+ ln -s ../tcl-debug/Dbg_cf.h.in
+ ln -s ../tcl-debug/Dbg.h
+ ln -s ../tcl-debug/Dbg.c
+ ln -s ../aclocal.m4 testsuite
+
+#########################################
+# Targets for building with CodeCenter
+#########################################
+
+GCCROOT = /depot/gnu/arch/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3
+GCCLIB = $(GCCROOT)/libgcc.a
+GCCINC = -I$(GCCROOT)/include
+# following only on Sparcs
+SABERDEFINE = -D__sparc__
+
+# Following target builds expect under CodeCenter.
+# If using ObjectCenter, before loading, type: setopt primary_language C
+exp: $(CFILES) exp_main_exp.c
+ #load $(CPPFLAGS) $(STTY) $(CFILES) exp_main_exp.c $(TCLLIB) $(GCCLIB) $(EXP_AND_TCL_LIBS)
+
+# Following target builds expectk under CodeCenter. Notes:
+# Because of explicit #includes of <X11/...> in tk.h, you need to create
+# a symlink from your X11 include directory to this directory
+tk: $(CFILES) exp_main_tk.c
+ #load $(CPPFLAGS) $(STTY) $(CFILES) exp_main_tk.c $(TKLIB) $(TCLLIB) $(EXP_AND_TK_LIBS)
+
+# Follow definitions are for building expect and expectk under ObjectCenter
+oexp: $(CFILES) exp_main_exp.c
+ #load $(CPPFLAGS) $(STTY) -C $(CFILES) exp_main_exp.c $(TCLLIB)
+
+otk: $(CFILES) exp_main_tk.c
+ #load $(CPPFLAGS) $(STTY) -C $(CFILES) exp_main_tk.c $(TKLIB) $(TCLLIB) $(EXP_AND_TK_LIBS)
+######################################
+# Targets for pushing out releases
+######################################
+
+# until we are completely switched over, keep updating old ftp site too
+OLDFTPDIR = /proj/elib/online/pub/expect
+FTPDIR = /proj/itl/www/div826/subject/expect
+
+# make a private tar file for myself
+tar: expect-$(VERSION).tar
+ mv expect-$(VERSION).tar expect.tar
+
+# make a release and install it on ftp server
+ftp: expect-$(VERSION).tar.Z expect-$(VERSION).tar.gz
+ cp expect-$(VERSION).tar.Z $(FTPDIR)/expect.tar.Z
+ cp expect-$(VERSION).tar.gz $(FTPDIR)/expect.tar.gz
+ cp HISTORY $(FTPDIR)
+ cp README $(FTPDIR)/README.distribution
+ cp example/README $(FTPDIR)/example
+ cp `pubfile example` $(FTPDIR)/example
+ rm expect-$(SHORT_VERSION).tar*
+ ls -l $(FTPDIR)/expect.tar*
+# update old ftp site too
+ cp expect-$(VERSION).tar.Z $(OLDFTPDIR)/expect.tar.Z
+ cp expect-$(VERSION).tar.gz $(OLDFTPDIR)/expect.tar.gz
+ cp HISTORY $(OLDFTPDIR)
+ cp README $(OLDFTPDIR)/README.distribution
+ cp example/README $(OLDFTPDIR)/example
+ cp `pubfile example` $(OLDFTPDIR)/example
+# delete temp files
+ rm expect-$(VERSION).tar*
+ ls -l $(OLDFTPDIR)/expect.tar*
+
+# make an alpha relase and install it on ftp server
+alpha: expect-$(VERSION).tar.Z expect-$(VERSION).tar.gz
+ cp expect-$(VERSION).tar.Z $(FTPDIR)/alpha.tar.Z
+ cp expect-$(VERSION).tar.gz $(FTPDIR)/alpha.tar.gz
+ cp HISTORY $(FTPDIR)
+ rm expect-$(VERSION).tar*
+ ls -l $(FTPDIR)/alpha.tar*
+
+# make a beta relase and install it on ftp server
+beta: expect-$(VERSION).tar.Z expect-$(VERSION).tar.gz
+ rm -rf $(FTPDIR)/alpha.tar*
+ cp expect-$(VERSION).tar.Z $(FTPDIR)/beta.tar.Z
+ cp expect-$(VERSION).tar.gz $(FTPDIR)/beta.tar.gz
+ cp HISTORY $(FTPDIR)
+ rm expect-$(VERSION).tar*
+ ls -l $(FTPDIR)/beta.tar*
+
+expect-$(VERSION).tar: configure
+ rm -f ../expect-$(VERSION)
+ ln -s `pwd` ../expect-$(VERSION)
+ rm -f ../pubfile
+ ln pubfile ..
+ cd ..;tar cvfh $@ `pubfile expect-$(VERSION)`
+ mv ../$@ .
+
+expect-$(VERSION).tar.Z: expect-$(VERSION).tar
+ compress -fc expect-$(VERSION).tar > $@
+
+expect-$(VERSION).tar.gz: expect-$(VERSION).tar
+ gzip -fc expect-$(VERSION).tar > $@
+
+test: expect
+ rm -f .tmp
+ echo "set objdir" `pwd` > .tmp
+ if [ "$(srcdir)" = "." ] ; then \
+ echo "set srcdir" `pwd` >> .tmp ; \
+ else echo "set srcdir" $(srcdir) >> .tmp ; fi
+ echo "cd \$${srcdir}/tests" >> .tmp
+ echo "source all" >> .tmp
+ rootme=`pwd`; export rootme; \
+ srcdir=${srcdir} ; export srcdir ; \
+ if [ -f ./expect ] ; then \
+ TCL_LIBRARY=$(TCL_LIBRARY) ; \
+ export TCL_LIBRARY ; fi ; \
+ $(LOCAL_EXPECT) -f .tmp
+ rm -f .tmp
+
+###########################
+# Targets for producing FAQ and homepage
+###########################
+
+#WEBDIR = /proj/elib/online/pub/expect
+WEBDIR = /proj/itl/www/div826/subject/expect
+
+# create the FAQ in html form
+FAQ.html: FAQ.src FAQ.tcl
+ FAQ.src html > FAQ.html
+
+# create the FAQ in text form
+FAQ: FAQ.src FAQ.tcl
+ FAQ.src text > FAQ
+
+# generate Expect home page
+homepage.html: homepage.src homepage.tcl
+ homepage.src > homepage.html
+
+# install various html docs on our web server
+install-html: FAQ.html homepage.html
+ cp homepage.html $(WEBDIR)/index.html
+ cp FAQ.html $(WEBDIR)
+# cp FAQ.src $(WEBDIR)
+# cp FAQ.tcl $(WEBDIR)
+
+# add recursive support to the build process.
+subdir_do: force
+ @for i in $(SUBDIRS); do \
+ echo "Making $(DO) in $${i}..." ; \
+ if [ -d ./$$i ] ; then \
+ if (rootme=`pwd`/ ; export rootme ; \
+ rootsrc=`cd $(srcdir); pwd`/ ; export rootsrc ; \
+ cd ./$$i; \
+ $(MAKE) $(FLAGS_TO_PASS) $(DO)) ; then true ; \
+ else exit 1 ; fi ; \
+ else true ; fi ; \
+ done
+force:
+
+## dependencies will be put after this line... ##
+Dbg.o: $(srcdir)/Dbg.c Dbg.h
+exp_$(EVENT_ABLE).o: $(srcdir)/exp_$(EVENT_ABLE).c expect_cf.h expect.h \
+ exp_command.h exp_event.h
+exp_$(EVENT_TYPE).o: $(srcdir)/exp_$(EVENT_TYPE).c expect_cf.h expect.h \
+ exp_command.h exp_event.h
+exp_command.o: $(srcdir)/exp_command.c expect_cf.h exp_tty.h \
+ exp_rename.h expect.h exp_command.h \
+ exp_log.h exp_printify.h exp_event.h exp_pty.h
+exp_inter.o: $(srcdir)/exp_inter.c expect_cf.h \
+ exp_tty_in.h exp_tty.h exp_rename.h expect.h exp_command.h \
+ exp_log.h exp_printify.h exp_regexp.h exp_tstamp.h
+exp_log.o: $(srcdir)/exp_log.c expect_cf.h expect.h \
+ exp_rename.h exp_log.h exp_printify.h
+exp_main_exp.o: $(srcdir)/exp_main_exp.c expect_cf.h \
+ expect.h exp_rename.h exp_command.h exp_log.h exp_printify.h
+exp_main_sub.o: $(srcdir)/exp_main_sub.c expect_cf.h \
+ exp_rename.h \
+ expect.h exp_command.h exp_tty_in.h exp_tty.h exp_log.h \
+ exp_printify.h exp_event.h
+#exp_main_tk.o: $(srcdir)/exp_main_tk.c expect_cf.h Dbg.h
+
+exp_main_tk.o: $(srcdir)/exp_main_tk.c expect_cf.h Dbg.h
+ $(CC) -c @TK_DEFS@ $(CFLAGS_INT) $(HDEFS) $<
+shared/exp_main_tk.o: $(srcdir)/exp_main_tk.c expect_cf.h Dbg.h
+ $(CC) -c @TK_DEFS@ $(CFLAGS_INT) $(HDEFS) $<
+exp_noevent.o: $(srcdir)/exp_noevent.c expect_cf.h exp_prog.h exp_command.h \
+ exp_event.h
+exp_poll.o: $(srcdir)/exp_poll.c expect_cf.h expect.h \
+ exp_command.h exp_event.h
+ $(CC) -c $(CFLAGS_INT) @TCL_DEFS@ $(HDEFS) $<
+shared/exp_poll.o: $(srcdir)/exp_poll.c expect_cf.h expect.h \
+ exp_command.h exp_event.h
+ $(CC) -c $(CFLAGS_INT) @EXP_SHLIB_CFLAGS@ @TCL_DEFS@ $(HDEFS) $< -o shared/$@
+exp_printify.o: $(srcdir)/exp_printify.c expect_cf.h
+exp_pty.o: $(srcdir)/exp_pty.c expect_cf.h exp_rename.h exp_pty.h
+exp_regexp.o: $(srcdir)/exp_regexp.c expect_cf.h \
+ expect.h exp_regexp.h
+exp_select.o: $(srcdir)/exp_select.c expect_cf.h \
+ expect.h exp_command.h exp_event.h
+exp_simple.o: $(srcdir)/exp_simple.c expect_cf.h \
+ expect.h exp_command.h exp_event.h
+exp_strf.o: $(srcdir)/exp_strf.c
+exp_trap.o: $(srcdir)/exp_trap.c expect_cf.h expect.h \
+ exp_command.h exp_log.h exp_printify.h
+exp_tty.o: $(srcdir)/exp_tty.c expect_cf.h \
+ expect.h exp_rename.h exp_tty_in.h exp_tty.h exp_log.h \
+ exp_printify.h exp_command.h
+exp_win.o: $(srcdir)/exp_win.c exp_win.h
+expect.o: $(srcdir)/expect.c expect_cf.h \
+ exp_rename.h expect.h exp_command.h \
+ exp_log.h exp_printify.h exp_event.h exp_tty.h exp_tstamp.h
+lib_exp.o: $(srcdir)/lib_exp.c expect_cf.h exp_rename.h expect.h \
+ exp_printify.h
+pty_sgttyb.o: $(srcdir)/pty_sgttyb.c expect_cf.h exp_rename.h exp_tty_in.h \
+ exp_tty.h exp_pty.h
+pty_termios.o: $(srcdir)/pty_termios.c expect_cf.h exp_win.h \
+ exp_tty_in.h exp_tty.h exp_rename.h exp_pty.h
+pty_unicos.o: $(srcdir)/pty_unicos.c expect_cf.h exp_rename.h
diff --git a/expect/NEWS b/expect/NEWS
new file mode 100644
index 00000000000..457aa507622
--- /dev/null
+++ b/expect/NEWS
@@ -0,0 +1,562 @@
+This file is the NEWS file from the Expect distribution.
+
+======================================================================
+======================================================================
+
+Date: 8/18/96
+
+Expect now works with Tcl 8.0.
+
+No changes were made to take advantage of 8.0 features such as
+namespaces. (If you want to put the Expect commands in a namespace,
+declare a namespace before loading them in.)
+
+Even thought Tcl allows embedded nulls in commands, Expect still does
+not. Tcl still doesn't support embedded in patterns and regexps.
+I'll wait til Tcl supports that before rewriting Expect's null
+support.
+
+
+======================================================================
+======================================================================
+
+Date: 9/28/96
+
+There is now an Expect FAQ and home page. Feedback is encouraged.
+You can get to the FAQ from the home page and vice versa, so you only
+need to remember one of the links, but here are both for completeness:
+
+home page: http://expect.nist.gov
+FAQ: http://expect.nist.gov/FAQ.html
+
+
+
+======================================================================
+======================================================================
+This section describes the changes to Expect 5, many due to changes
+from Tcl 7.4 to 7.5.
+
+Improvements
+==============================
+
+You can now use expect_background from Tcl along with all the
+Tcl-based event stuff such as "after". You can also do fun things
+such as have "after" actions run while expect is waiting for input.
+It's worth comparing the difference between commands such as expect
+(which waits in the event loop) and gets (which doesn't).
+
+Incompatibilities
+==============================
+
+libexpectk is gone. Because of the event loop was moved into Tcl,
+this is no longer necessary. Just use the regular Expect library.
+This only affects you if are hand-linking.
+
+The name of the static C library now has the extension on the end -
+just like Tcl. This only affects you if are hand-linking.
+
+
+==============================
+Some obvious questions and answers
+
+Nothing in the user interface has changed. All your old scripts
+should run. Tcl now has commands that replace Expect functionality in
+the area of version control and date handling. I encourage you to use
+Tcl's support rather than Expect's for any new scripts that you write.
+However, I won't be removing Expect's commands, so don't worry about
+having to convert old scripts.
+
+It is my understand that shared/dl libs work. (I say "it is my
+understanding", because my own environment doesn't handle it, sigh.
+My system admins tell me that they're working on it.) So I've had to
+guess on some things - in fact, I've talked to a number of people and
+I get the feeling that a lot of people are guessing on shared/dl libs.
+I have yet to talk to anyone that REALLY understands this stuff (by
+"understand", I mean "can write the configure/Makefile portably and
+correctly". So much for my griping. In theory, the shared/dl support
+is pretty much a freebie because Tcl itself provides all the support
+for this. (There is some reorganization that could be done to improve
+shared library memory use - I'll get to it eventually - it shouldn't
+affect most people.) Don't send me complaints about shared/dl libs
+unless you are *positive* it is something that I am responsible for.
+Even if Tcl works and Expect fails, it is likely to be a Tcl error (or
+more precisely, a configuration problem that is more appropriately
+fixed from the Tcl distribution).
+
+For Tcl-package purposes, Expect is called "Expect". (Duh...)
+
+Expect's multiple interpreter support is minimal. It should work for
+most things, serendipitously. I haven't spent any time making this
+perfect.
+
+No, this release isn't portable to Windows or Mac. Let me know if
+you're seriously interested in a lot of work. I'm not saying it's not
+possible. It's definitely possible and the porting working at Sun has
+made it easier than before. But it's still not a weekend hack.
+
+Industrial support for the NT port, would be very helpful. If you are
+interested, either as a student or an industrial sponsor, let me know.
+
+==============================
+Building the code
+==============================
+
+Expect builds as usual. (See the INSTALL file for details.)
+
+The only significant change is that Expect now has to find the
+tclConfig.sh file (and tkConfig.sh if you want). So if you like to
+store Tcl where Expect can't find it, you'll need to use even more
+configure flags than you used to.
+
+Shared/dl Expect libraries are built if you configured Tcl for
+shared/dl libraries.
+
+All support for earlier versions of Tcl and Tk have been removed from
+Expect. For example, if you're still using Tcl 7.4 (or earlier),
+don't bother to install this release.
+
+======================================================================
+======================================================================
+This section describes the changes from Expect 4 to Expect 5.
+
+The changes that people will find most interesting or annoying are as
+follows. Some of them may seem rather arbitrary but fix inconsistencies
+leading to much cleaner coding both internally and externally.
+
+
+-- Expect version 5.20 and above is designed to work with Tcl 7.5 and
+Tk 4.1. Expect 5.20 and above will not work with earlier versions.
+
+-- Glob-style patterns do longest-possible matches (from the earliest
+possible position) just like regexps. Previously, they matched the
+shortest-possible strings. However, the documentation didn't actually
+say this (it didn't say anything)
+
+-- Exact patterns are now supported from expect. Use the "-ex" flag.
+Exact patterns work just like those in interact. No special handling
+is made of *, ^, etc.
+
+-- The new command "expect_background" registers patterns that are to
+be tested against spawned process output whenever it appears (i.e.,
+asynchronously). This only works in the Tk environment. The
+arguments are the same as the expect command.
+
+-- expect_before and expect_after now handle their arguments like
+expect_background. Previously, a command such as "expect_before"
+with no arguments deleted patterns for all spawn ids. Now, it only
+deletes patterns for the current spawn id. Similarly with the "-i"
+form.
+
+-- expect_background/before/after support an -info flag to query what
+the current patterns are. The results are returned in such a way that
+they can be re-used by a new expect command.
+
+The -info flag must be the first flag in the command. With no other
+arguments, it returns the setting for the current spawn id. With a -i
+descriptor, information is returned for that spawn id. The argument
+-noindirect may be used to suppress indirects which also match a
+direct spawn id. Only a single -i specification may be given with
+-info. With the argument "-all", all spawn id specifications are
+reported.
+
+-- There is now a sleep command. It understands decimal values such as
+
+ sleep .5
+
+Interrupts and other asynchronous events are processed while Expect sleeps.
+
+-- Traps now use Tcl's "Async" support. This has advantages and
+disadvantages. One advantage is that traps have no chance of screwing
+up the Tcl internals. One disadvantage is that trap handlers are
+delayed at certain specific times and places. For example, a handler
+cannot occur inside another handler. While one handler is running,
+all other handlers are blocked. This is probably the most noticable
+place where handlers are blocked. Others are generally small windows,
+so you shouldn't notice the delay in executing the handlers.
+
+Several traps are initially defined:
+
+ trap exit {SIGINT SIGTERM}
+
+If you use the -D flag to start the debugger, the following trap is
+defined:
+
+ trap {exp_debug 1} SIGINT
+
+You can, of course, override these. In particular, if you have your
+own "trap exit SIGINT", this will override the debugger trap. Because
+SIGINT is tied to exit (see above) by default anyway, you should
+remove your own "trap exit SIGINT" unless you specifically do not want
+to be able to get to the debugger by ^C.
+
+If you want to define your own trap on SIGINT but still trap to the
+debugger when it is running, use:
+
+ if ![exp_debug] {trap mystuff SIGINT}
+
+Alternatively, you can trap to the debugger using some other signal.
+
+The ONEXIT trap is no longer available. Instead, say "exit -onexit ..."
+
+Traps are now deleted by using the empty ({}) handler. The current
+handler is returned if no action is supplied. With no arguments, trap
+returns the signal number of the trap command currently being executed.
+
+-- The wait command now returns a four element list if a valid child
+was waited on.
+Element 1: pid
+Element 2: spawn id
+Element 3: 0 (or -1 if there was an OS error)
+Element 4: status (or errno if element 3 == -1)
+
+-- expect and interact notes:
+
+The timeout and eof patterns were initially named "-timeout" and
+"-eof" but have been renamed "timeout" and "eof" to match those of
+expect. The ability to define default timeout/eof actions has been
+removed. (You can do this more easily by grouping spawn ids.)
+
+expect and interact now support a "null" keyword to match an ASCII 0.
+send supports -null and -break keywords.
+
+Since a large number of special keywords have been added to interact,
+a new keyword "-ex" for "exact" was added descriptive of its default
+treatment of patterns. This protects the next token from being
+misinterpreted as a keyword. The expect command provides "-gl" for
+"glob" for analogous reasons.
+
+Any string starting with "-" should be protected by the "-ex" or "-gl"
+flag, even those that are not keywords currently. (All strings
+starting with "-" are reserved for future options.)
+
+String start/end indices are no longer written to expect_out and
+interact_out unless the -indices flag is given.
+
+expect_out(spawn_id) is set to the spawn id associated with the spawn
+id that produced the last output in an expect command. For example,
+you can use this to delete files that have closed, by removing this
+element from an indirect spawn ids spec. The same effect is
+reproducable with interact (and interact_out(spawn_id)) but for
+efficiency reasons, it requires the -iwrite flag before each pattern.
+
+Expect's -i and interact's -i, -u, -input, and -output flags can now
+describe a list of spawn ids. So you can say things like:
+
+ interact -input "$id1 $id2 $id3" .... -output "$id1 $id2" ...
+
+In this case, id1, 2, 3 would be sent to id1, and 2.
+
+The spawn id may be given as a global variable name (called an
+"indirect spawn id specification"), in which case, the variable
+contains the list of spawn ids. Whenever the variable is changed, the
+new list of spawn ids is automatically used. This is particularly
+useful with any long running expect command such as expect_before,
+expect_after, expect_background, and interact.
+
+The -update flag was removed. Use indirect spawn ids (see previous
+paragraph).
+
+-- interact notes:
+
+Interact now support -input and -output flags that provide very
+flexible means of moving data from/to multiple spawn ids in complex
+ways (but very quickly). It is possible to write most expect loops
+using a simple interact statement. For instance, the three way
+interaction inside kibitz (between two users and a process) is written
+this way:
+
+ interact {
+ -output $shell
+ -input $userin eof { . . . } -output $shell
+ -input $shell -output "$user_spawn_id $userout"
+ }
+
+-- send command notes:
+
+It is possible to send a break by using the "-break" flag.
+
+Any string starting with "-" should be protected by preceding it with
+the "--" flag, even those that are not keywords currently. (All
+strings starting "-" are reserved for future options.)
+
+-- The spawn command now takes an "-open" flag which in turns takes a
+Tcl file as an argument. This lets you treat raw devices, files, and
+pipelines as spawned processes without using a pty.
+
+This was actually in Expect 4, but I forgot to document it. Oops!
+
+-- The old "debug" command (which describes what Expect is doing
+internally) was renamed "exp_internal". "debug" (and "exp_debug") now
+invoke the interactive debugger.
+
+-- The new command "stty" now takes over the job of "system stty". It
+works much better, allowing POSIX-style redirection to affect other
+ttys. It otherwise takes arguments as "system stty" did.
+
+-- The "-tcl" option to "return" has gone away. (This was dangerous
+to anyone that actually happened to return the value "-tcl".)
+Instead, use inter_return.
+
+-- Added exp_timestamp command to produce very fast timestamps.
+
+-- Added exp_pid command to return pid of given spawn id.
+
+-- The close command now takes an argument of "-onexec" with a following
+0 or non-zero value. For example, the follow command stops the
+current spawn id from being closed when another process is exec'd or
+spawn'd.
+
+ close -onexec 0
+
+While "-onexec 1" returns it to the default condition where it will be
+closed upon exec or spawn.
+
+-- log_user now returns previous value. It is acceptable to call now,
+without arguments just to get the value.
+
+-- The following forms are deprecated. They will be allowed
+indefinitely but not advertised or supported if they break.
+
+ -eof, -timeout in interact (reason: didn't match expect.
+ Instead, use eof or timeout.)
+
+ -- in expect or interact (reason: no easier to read.
+ Instead, use -gl in expect or -ex in interact.)
+
+ continue -expect (reason: when mixing in extensions, you have
+ to use exp_continue, so -expect becomes irrelevant.
+ Instead, use exp_continue.)
+
+ getpid (reason: Tcl now supplies same functionality as "pid".
+ Instead, use pid.)
+
+ expect_version and expect_library (reason: the name implies
+ they have something to do with the expect command,
+ which they doesn't.
+ Instead, use exp_version and exp_library.)
+
+ -timestamp for obtaining tm and ctime in expect and interact
+ (reason: separate command now exists for this purpose.
+ Instead, use exp_timestamp.)
+
+ system stty (reason: bad interaction with redirection.
+ Instead, use stty.)
+
+-- New examples have been added:
+
+"dislocate" lets you disconnect and reconnect to processes.
+
+"tkpasswd" illustrates passwd embedded in a GUI.
+
+They may not be overwhelmingly useful, but run them once to see what
+they do. If you ever need to do anything similar, you can look back
+at them.
+
+"tknewsbiff" pops up a window or plays a audio clip when you have
+unread news.
+
+-- Changes to the Expect libraries:
+
+The expect-tcl library (libexpectcl.a) has been integrated with the
+expect library (libexpect.a). So references to libexpectcl.a should
+be removed.
+
+The Expect C library now supports buffering, multiplexing, null
+matching, full buffer matching. Basically, all of the features in
+Expect are now in the library.
+
+Buffering and multiplexing has caused the biggest change to the
+library. Previously, exp_match contained the entire buffer that
+matched. Now exp_match just points to where in the buffer the match
+started. exp_buffer points to the beginning of the buffer.
+Previously, the previous buffer was thrown away at the beginning of
+each expect function call. Now, previously unmatched characters are
+eligible for matching.
+
+To match on different file descriptors, exp_match, exp_match_end,
+exp_buffer_end must be restored to their previous values. Initially,
+they should be zero.
+
+The meaning of timeout == 0 in the Expect library has been changed.
+See the man page for more info.
+
+======================================================================
+======================================================================
+This file describes the changes from Expect 3 to Expect 4.
+
+The improvements that people will find most interesting are:
+
+1) Expect version 4 is designed to work with Tcl 6.7 and Tk 3.2.
+ (Earlier versions of Expect will not work with Tcl 6.7)
+ Expect can now be layered in with any Tcl program.
+ Note that in Tk, Expect's send command is called "exp_send".
+ (It used to be called "send_spawn" but this bit the dust.)
+2) A debugger is provided.
+3) The interact command has been totally rewritten and supports regular
+ expressions, timeout/eof patterns, and a number of other new things.
+4) The default behavior of ^C (SIGINT) is exit whether or not you are in
+ a read.
+5) Expect uses "sane" terminal parameters by default, allowing scripts
+ to work the same whether inside emacs shell mode or not. (See man
+ page on "spawn" for more info.)
+6) All the hard parts of the installation process are automated. This
+ was done primarily by Rob Savoye at Cygnus. Thank you, Rob!
+7) It is now possible to buy a support contract for Expect from Cygnus.
+
+The changes that people will find most annoying are:
+
+1) send now only sends a single string. (It used to send any number of
+ strings with spaces jammed in between.)
+2) getpid was renamed pid.
+3) interact's -flush was renamed -nobuffer (much more descriptive).
+4) interact now runs all actions in raw mode unless the flag -reset
+ is used. -f and -F are ignored. send automatically understands
+ how to do the right thing. The most likely thing to watch out for
+ are actions like "exec kill -STOP 0" which almost certainly need
+ the -reset flag.
+5) argv0 is initialized to script name. argv no longer contains it.
+ argc is initialized [llength $argv]. This follows new Tcl style.
+
+All differences are described in the man page. Some of the less
+significant differences are described in the HISTORY file. The
+debugger is described in a separate document (see the README).
+
+This version also introduces one incompatibility that may require
+changes to scripts. While this may initially annoy you, the final
+result will simplify the process of writing scripts. Namely:
+
+In version 3, the expect command accepted lists of glob-style patterns
+such as:
+
+ expect "a\ b c" action
+
+where "a b" or "c" would cause action to be executed. The problem
+with this is that the pattern list is hard to write and hard to read.
+Patterns with control-characters, backslashes and dollar signs were
+very difficult to deal with.
+
+Regular-expression patterns provide a much simpler solution. Via the
+alternation feature (using a "|") the above pattern can be written as:
+
+ expect -re "a b|c" action
+
+I was concerned about people having a significant investment in code
+that depended on the old syntax but responders to a comp.lang.tcl poll
+about such a change in pattern handling were 100% in favor of it. (I
+even proposed hooks for backward compatibility, but there was no
+interest in it.)
+
+Fortunately, most simple things will work as before including:
+
+ expect foobar
+ expect {foobar}
+ expect "foobar"
+ expect "foo\ bar"
+
+However, some things won't work as before. For example, the following
+will behave differently - now the braces will be considered as part of
+the pattern.
+
+ expect "{foo bar}"
+
+Here are examples of patterns in my own code that I had to change:
+
+ was changed to
+ Version 3 pattern list Version 4 pattern
+
+ {Whois:\ } "Whois: "
+ {No\ match} "No match"
+ {250*ftp>* 200*ftp>*} -re "2(5|0)0.*ftp>.*"
+ {{Press Return to continue*}} "Press Return to continue*"
+ {*\r\n*\\\\\r\n} "\r\n*\\\r\n"
+
+
+
+Future Change Alert
+
+John Ousterhout has pre-announced a future change in Tcl that may
+affect you. In particular, backslash sequences other than those
+explicitly listed in the Tcl documentation will be handled as if the
+backslash was not present.
+
+The likely place this arises is when quoting characters that are
+special to the pattern matcher but not to Tcl.
+
+For example in Tcl 6.7, the following command matches a period.
+
+ expect -re "\."
+
+In Tcl 7.0, it will match any character, because Tcl will throw away
+the backslash. If you want to match a period, you will have to say:
+
+ expect -re "\\."
+or
+ expect -re {\.}
+
+The following command will find occurrences of this. (It may find
+other things, but it will at least find the problem cases.)
+
+ egrep '(\\$)|(\\[^][bfnrtv\0-9{}$ ;"])' *.exp
+
+======================================================================
+======================================================================
+This section describes the changes from Expect 2 to Expect 3.
+
+If you used to use Expect version 2 (any version written before
+September '91) you will find that the current version of Expect (3)
+introduced minor but significant incompatibilities.
+
+The HISTORY file describes these briefly. They are described at
+length in the man page.
+
+I'm sorry if you feel annoyed at the incompatibilities, but Expect has
+been out for a year and a half, Tcl even longer. Both Tcl and Expect
+are using this as a last chance to make significant changes, so that
+we will not disturb even more users in the future.
+
+There is no automated conversion procedure (although see note below)
+for Expect or even raw Tcl. For now, I suggest that you not bother
+fixing things that already work - just keep the old Expect around.
+The binary isn't very big after all. If you do write a translation
+script, let me know. Thanks.
+
+Of course, I felt obligated to convert the examples distributed with
+expect. I did this by hand while writing the new version itself,
+partly as an aid but mostly to test lots of variations. In 90% of the
+scripts, all I had to do was change:
+
+(changes due to Tcl)
+ 'index' to 'lindex'
+ 'range' to 'lrange'
+ 'length' to 'llength'
+ 'print' to 'send_user' or 'puts' depending on how you use it
+ 'function .... c' with '[join [function [split string ""]] ""]'
+(changes due to Expect)
+ 'expect_match' to 'expect_out(buffer)'
+ 'set match_max' to 'match_max' (perhaps with -d flag)
+ '*' to '-re .+'
+
+If anyone wants to write a script to do this, note the pitfalls:
+
+1) functions and variables do not share the same namespace, so it is a
+inappropriate to just globally rename things.
+
+A number of optimizations can be made:
+
+1) If you are doing multiple split/joins, you should probably cache the
+split string.
+
+2) Virtually all uses of scan are unnecessary now, due to exec's automatic
+stripping of terminating newlines, and expect's support of regexps.
+
+3) String manipulation can be reduced or avoided entirely if you use
+expect -re.
+
+4) exec is no longer necessary to retrieve environment variables, since
+they can now be retrieved from $env.
+
+5) If you have been really anal about testing for timeout and eof, you
+can dramatically reduce the size of your scripts by using expect_before
+and expect_after. This is more efficient, as well, since those actions
+are only parsed once.
+
diff --git a/expect/README b/expect/README
new file mode 100644
index 00000000000..101f1c07cb0
--- /dev/null
+++ b/expect/README
@@ -0,0 +1,366 @@
+NOTE: ALPHA AND BETA RELEASES OF TCL/TK ARE NOT SUPPORTED!
+
+--------------------
+Introduction
+--------------------
+
+This is the README file for Expect, a program that performs programmed
+dialogue with other interactive programs. It is briefly described by
+its man page, expect(1). This directory contains the source and man
+page for Expect.
+
+This is Expect 5 for Tcl 7.5, 7.6, and 8.0. Tk 4.1, 4.2, 8.0 and the
+Tcl Debugger are also supported. Significant changes and other news
+can be found in the NEWS file.
+
+The Expect home page is: http://expect.nist.gov
+The Expect FAQ is: http://expect.nist.gov/FAQ.html
+
+--------------------
+Getting Started - The Preferable Way
+--------------------
+
+A book on Expect is available from O'Reilly with the title "Exploring
+Expect: A Tcl-Based Toolkit for Automating Interactive Applications",
+ISBN 1-56592-090-2.
+
+The book is filled with detailed examples and explanations, and is a
+comprehensive tutorial to Expect. The book also includes a tutorial
+on Tcl written specifically for Expect users (so you don't have to
+read the Expect papers, the debugger paper, Ousterhout's book, or the
+man pages). Exploring Expect is 602 pages.
+
+--------------------
+Getting Started - The Hacker Way
+--------------------
+
+While the book is the best way to learn about Expect, it is not
+absolutely necessary. There are man pages after all and there are
+numerous articles and papers on Expect. All of my own papers are in
+the public domain and can be received free. If you are a hacker on a
+tight budget, this may appeal to you. Nonetheless, I think you will
+find the book pays for itself very quickly. It is much more readable
+than the man pages, it includes well-written and explained examples,
+and it describes everything in the papers as a coherent whole. The
+concepts in the papers actually only make up a small fraction of the
+book.
+
+The 1990 USENIX paper (see "Readings" below) is probably the best one
+for understanding Expect conceptually. The 1991 Computing Systems and
+the LISA IV papers provide a nice mix of examples. The only downside
+is, the examples in these papers don't actually work anymore - some
+aspects (e.g., syntax) of both Expect and Tcl have changed. The
+papers still make interesting reading - just don't study the examples
+too closely! Fortunately, most of the examples from the papers also
+accompany this distribution - and all of these are up to date.
+
+For all the details, read the man page. It is long but you can get
+started just by skimming the sections on the following commands:
+
+ spawn (starts a process)
+ send (sends to a process)
+ expect (waits for output from a process)
+ interact (lets you interact with a process)
+
+To print out the Expect man page, invoke your local troff using the
+-man macros, such as either of:
+
+ ptroff -man expect.man
+ ditroff -man expect.man
+
+If Expect is installed, you can read the man pages using the "usual"
+man commands, such as "man expect". If not installed, view the man
+page on your screen by saying something like:
+
+ nroff -man expect.man | more
+
+Expect uses Tcl as the underlying language for expressing things such
+as procedures, loops, file I/O, and arithmetic expressions. For many
+simple scripts, it is not necessary to learn about Tcl. Just by
+studying the examples, you will learn enough Tcl to get by. But if
+you would like to learn more about Tcl or use it in your own
+applications, read the Tcl README file which provides pointers to the
+extensive Tcl documentation. Or read Exploring Expect. Chapter 2 of
+Exploring Expect is a Tcl tutorial specifically designed for Expect
+users.
+
+An interactive debugger is bundled with Expect. The debugger has its
+own documentation that comes separately. It is listed in the Readings
+below. Again, it is slightly out of date. An up-to-date description
+of the debugger appears in Chapter 18 of Exploring Expect. This
+chapter also contains additional advice and tips for debugging.
+
+You may get the feeling that the Expect documentation is somewhat
+scattered and disorganized. This was true prior to publication of
+Exploring Expect. The book contains everything you need to know, all
+up-to-date, and with examples of every concept. (The book contains no
+references to any of the Expect papers because none are necessary.)
+
+----------------------
+Examples
+----------------------
+
+This distribution contains many example scripts. (All of the
+substantive examples in the book are included.) They can be found in
+the example directory of this distribution. The README file in that
+directory briefly describes all of the example scripts. Many of the
+more sophisticated examples have man pages of their own.
+
+Other interesting scripts are available separately in the directory
+http://expect.nist.gov/scripts/ (ftpable as
+ftp://ftp.nist.gov/mel/div826/subject/expect/scripts). (See below for
+how to retrieve these.) You are welcome to send me scripts to add to
+this directory. A number of Expect scripts are also available in the
+Tcl archive, available at ftp://ftp.neosoft.com/pub/tcl.
+
+--------------------
+Readings on Expect
+--------------------
+
+The implementation, philosophy, and design are discussed in "expect:
+Curing Those Uncontrollable Fits of Interaction", Proceedings of the
+Summer 1990 USENIX Conference, Anaheim, CA, June 11-15, 1990.
+
+Examples and discussion, specifically aimed at system administrators,
+are in "Using expect to Automate System Administration Tasks",
+Proceedings of the 1990 USENIX Large Systems Administration Conference
+(LISA) IV, Colorado Springs, CO, October 17-19, 1990.
+
+A comprehensive paper of example scripts is "expect: Scripts for
+Controlling Interactive Programs", Computing Systems, Vol. 4, No. 2,
+University of California Press Journals, 1991.
+
+Regression and conformance testing is discussed in "Regression Testing
+and Conformance Testing Interactive Programs", Proceedings of the
+Summer 1992 USENIX Conference, San Antonio, TX, June 8-12, 1992.
+
+An explanation of some of the more interesting source code to an early
+version of Expect is in Chapter 36 ("Expect") of "Obfuscated C and
+Other Mysteries", John Wiley & Sons, ISBN 0-471-57805-3, January 1993.
+
+A paper on connecting multiple interactive programs together using
+Expect is "Kibitz - Connecting Multiple Interactive Programs
+Together", Software - Practice & Experience, Vol. 23, No. 5, May 1993.
+
+The debugger is discussed in "A Debugger for Tcl Applications",
+Proceedings of the 1993 Tcl/Tk Workshop, Berkeley, CA, June 10-11,
+1993.
+
+Using Expect with Tk is described in the paper "X Wrappers for
+Non-Graphic Interactive Programs", Proceedings of Xhibition '94, San
+Jose, CA, June 20-24, 1994.
+
+Simple techniques to allow secure handling of passwords in background
+processes are covered in "Handling Passwords with Security and
+Reliability in Background Processes", Proceedings of the 1994 USENIX
+LISA VIII Conference, San Diego, CA, September 19-23, 1994.
+
+More publications can be found in the Expect home page (see elsewhere).
+
+--------------------
+How to Get the Latest Version of Expect or the Readings
+--------------------
+
+Expect may be ftp'd as mel/div826/subject/expect/expect.tar.gz from
+expect.nist.gov. (Yes, the URL is much shorter:
+http://expect.nist.gov/expect.tar.Z) Request email delivery by mailing
+to "library@cme.nist.gov". The contents of the message should be (no
+subject line) "send pub/expect/expect.tar.Z".
+
+Once you have retrieved the system, read the INSTALL file. The papers
+mentioned above can be retrieved separately (from the same directories
+listed above) as:
+
+ doc/seminal.ps.Z (USENIX '90 - Intro and Implementation)
+ doc/sysadm.ps.Z (LISA '90 - System Administration)
+ doc/scripts.ps.Z (Comp. Systems '91 - Overview of Scripts)
+ doc/regress.ps.Z (USENIX '92 - Testing)
+ doc/kibitz.ps.Z (SP&E '93 - Automating Multiple
+ Interactive Programs Simultaneously)
+ doc/tcl-debug.ps.Z (Tcl/Tk '93 - Tcl/Tk Debugger)
+ doc/expectk.ps.Z (Xhibition '94 - Using Expect with Tk)
+ doc/bgpasswd.ps.Z (LISA '94 - Passwds in Background Procs)
+ doc/chargraph.ps.Z (SP&E '96 - Testing and Automation
+ of Character Graphic Applications)
+
+The book "Exploring Expect" is described in more detail earlier in
+this file.
+
+The book "Obfuscated C and Other Mysteries" is not on-line but is
+available in bookstores or directly from the publisher (Wiley).
+
+Overhead transparencies I've used at conferences are also available in
+the same way as the papers themselves. The transparencies are sketchy
+and not meant for personal education - however if you are familiar
+with Expect and just want to give a short talk on it to your
+colleagues, you may find the transparencies useful. They vary in
+length from 15 to 20 minutes in length. These are:
+
+ doc/seminal-talk.ps.Z (USENIX '90 - Intro and Implementation)
+ doc/sysadm-talk.ps.Z (LISA '90 - System Administration)
+ doc/regress-talk.ps.Z (USENIX '92 - Testing)
+ doc/tcl-debug-talk.ps.Z (Tcl/Tk '93 - Tcl/Tk Debugger)
+ doc/expectk-talk.ps.Z (Xhibition '94 - Expect + Tk = Expectk)
+ doc/bgpasswd-talk.ps.Z (LISA '94 - Passwords in the Background)
+
+All of the documents are compressed PostScript files and should be
+uncompressed and sent to a PostScript printer. The documents are
+intended for printing at 8.5"x11" and may fail on some ISO A4
+printers. According to Hans Mayer <Hans.Mayer@gmd.de>, you can make
+them A4-able by searching for "FMVERSION" and changing the next line
+from:
+
+ 1 1 0 0 612 792 0 1 13 FMDOCUMENT
+to:
+ 1 1 0 0 594 841 0 1 13 FMDOCUMENT
+
+
+--------------------
+Using Expect with and without Tcl and/or Tk.
+--------------------
+
+The usual way of using Expect is as a standalone program with Tcl as
+the control language. Since you may already have Tcl, it is available
+separately. Tcl may be retrieved as tcl.tar.Z in the same way as
+described above for Expect. When new releases of Tcl appear, I will
+try to check them out for Expect as soon as possible. If you would
+like to get the newest Tcl release without waiting, ftp it from
+ftp.smli.com (directory pub/tcl).
+
+Expect may also be built using the Tk library, a Tcl interface to the
+X Window System. Tk is available in the same way as Tcl.
+
+It is possible to embed the Expect/Tcl core and optionally Tk in your
+own C programs. This is described in libexpect(3).
+
+Expect can also be used from a C or C++ program without Tcl. This is
+described in libexpect(3). While I consider this library to be easy
+to use, the standalone Expect program is much, much easier to use than
+working with the C compiler and its usual edit, compile, debug cycle.
+Unlike typical programming, most of the debugging isn't getting the C
+compiler to accept your programs - rather, it is getting the dialogue
+correct. Also, translating scripts from Expect to C is usually not
+necessary. For example, the speed of interactive dialogues is
+virtually never an issue. So please try 'expect' first. It is a more
+appropriate tool than the library for most people.
+
+--------------------
+Systems Supported
+--------------------
+
+I do not know of any UNIX systems on which Expect will not run.
+Systems which do not support select or poll can use Expect, but
+without the ability to run multiple processes simultaneously. I am
+willing to work with you to complete a port.
+
+Before sending me changes, please download or verify that you have the
+latest version of Expect (see above). Then send me a "diff -c" along
+with a suitable English explanation. If your diff involves something
+specific to a machine, give me diffs for configure.in as well or give
+me a hint about when the diffs should be done so I can write the
+configure support myself. Also please include the version of the OS
+and whether it is beta, current, recent, or totally out-of-date and
+unsupported.
+
+--------------------
+Installing Expect
+--------------------
+
+Expect comes with a configure script that provides for an automated
+installation. I believe you will find that Expect is very easy to
+install. (Tcl and Tk, too.)
+
+For more information, read the INSTALL file.
+
+--------------------
+Support from Don Libes or NIST
+--------------------
+
+Although I can't promise anything in the way of support, I'd be
+interested to hear about your experiences using it (good or bad). I'm
+also interested in hearing bug reports and suggestions for improvement
+even though I can't promise to implement them.
+
+If you send me a bug, fix, or question, include the version of Expect
+(as reported by expect -d), version of Tcl, and name and version of
+the OS that you are using. Before sending mail, it may be helpful to
+verify that your problem still exists in the latest version. You can
+check on the current release and whether it addresses your problems by
+retrieving the latest HISTORY file (see "History" above).
+
+
+Awards, love letters, and bug reports may be sent to:
+
+Don Libes
+National Institute of Standards and Technology
+Bldg 220, Rm A-127
+Gaithersburg, MD 20899
+(301) 975-3535
+libes@nist.gov
+
+I hereby place this software in the public domain. NIST and I would
+appreciate credit if this program or parts of it are used.
+
+Design and implementation of this program was funded primarily by
+myself. Funding contributors include the NIST Automated Manufacturing
+Research Facility (funded by the Navy Manufacturing Technology
+Program), the NIST Scientific and Technical Research Services, the
+ARPA Persistent Object Bases project and the Computer-aided
+Acquisition and the Logistic Support (CALS) program of the Office of
+the Secretary of Defense.
+
+Especially signicant contributions were made by John Ousterhout, Henry
+Spencer, and Rob Savoye. See the HISTORY file for others.
+
+--------------------
+Support for Don Libes or NIST
+--------------------
+
+NIST accepts external funding and other resources (hardware, software,
+and personnel). This can be a fine way to work more closely with NIST
+and encourage particular areas of research.
+
+Funding can be earmarked for specific purposes or for less-specific
+purposes. For example, if you simply like the work I do, you can
+contribute directly to my funding which will reduce the amount of time
+I have to spend writing proposals and submitting them to other people
+for funding on my own.
+
+I can also participate in the NIST Fellows program allowing me to
+spend several months to a year working directly with your company and
+potentially even at your location. I am also interested in returning
+to an academic program. I presently have an MS and am hunting for
+Ph.D. topics and advisors. Let me know if you have ideas or are
+interested in being my advisor.
+
+--------------------
+Commercial Support, Classes
+--------------------
+
+Several companies provide commercial support for Expect. If your
+company has a financial investment in Expect or you wish to be assured
+of continuing support for Expect, you can buy a support contract this
+way. These companies currently include:
+
+Cygnus Support
+1937 Landings Drive
+Mountain View, CA 94043
++1 (415) 903-1400
+info@cygnus.com
+http://www.cygnus.com
+
+Computerized Processes Unlimited (CPU)
+4200 S. I-10 Service Rd., Suite 205
+Metairie, LA 70006
++1 (504) 889-2784
+info@cpu.com
+http://www.cpu.com
+http://www.cpu.com/cpu/expect.htm (Expect class page)
+
+CPU provides Expect support and also Expect classes. Contact them for
+more information.
+
+Neither NIST nor I have any financial relationship with these
+companies.
+
+
diff --git a/expect/aclocal.m4 b/expect/aclocal.m4
new file mode 100644
index 00000000000..89db2bd7663
--- /dev/null
+++ b/expect/aclocal.m4
@@ -0,0 +1,621 @@
+dnl written by Rob Savoye <rob@cygnus.com> for Cygnus Support
+dnl major rewriting for Tcl 7.5 by Don Libes <libes@nist.gov>
+
+dnl CY_AC_PATH_TCLCONFIG and CY_AC_LOAD_TCLCONFIG should be invoked
+dnl (in that order) before any other TCL macros. Similarly for TK.
+
+dnl CYGNUS LOCAL: This gets the right posix flag for gcc
+AC_DEFUN(CY_AC_TCL_LYNX_POSIX,
+[AC_REQUIRE([AC_PROG_CC])AC_REQUIRE([AC_PROG_CPP])
+AC_MSG_CHECKING([if running LynxOS])
+AC_CACHE_VAL(ac_cv_os_lynx,
+[AC_EGREP_CPP(yes,
+[/*
+ * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__"
+ */
+#if defined(__Lynx__) || defined(Lynx)
+yes
+#endif
+], ac_cv_os_lynx=yes, ac_cv_os_lynx=no)])
+#
+if test "$ac_cv_os_lynx" = "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(LYNX)
+ AC_MSG_CHECKING([whether -mposix or -X is available])
+ AC_CACHE_VAL(ac_cv_c_posix_flag,
+ [AC_TRY_COMPILE(,[
+ /*
+ * This flag varies depending on how old the compiler is.
+ * -X is for the old "cc" and "gcc" (based on 1.42).
+ * -mposix is for the new gcc (at least 2.5.8).
+ */
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ choke me
+ #endif
+ ], ac_cv_c_posix_flag=" -mposix", ac_cv_c_posix_flag=" -X")])
+ CC="$CC $ac_cv_c_posix_flag"
+ AC_MSG_RESULT($ac_cv_c_posix_flag)
+ else
+ AC_MSG_RESULT(no)
+fi
+])
+
+#
+# Sometimes the native compiler is a bogus stub for gcc or /usr/ucb/cc. This
+# makes configure think it's cross compiling. If --target wasn't used, then
+# we can't configure, so something is wrong. We don't use the cache
+# here cause if somebody fixes their compiler install, we want this to work.
+AC_DEFUN(CY_AC_C_WORKS,
+[# If we cannot compile and link a trivial program, we can't expect anything to work
+AC_MSG_CHECKING(whether the compiler ($CC) actually works)
+AC_TRY_COMPILE(, [/* don't need anything here */],
+ c_compiles=yes, c_compiles=no)
+
+AC_TRY_LINK(, [/* don't need anything here */],
+ c_links=yes, c_links=no)
+
+if test x"${c_compiles}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't compile.)
+fi
+
+if test x"${c_links}" = x"no" ; then
+ AC_MSG_ERROR(the native compiler is broken and won't link.)
+fi
+AC_MSG_RESULT(yes)
+])
+
+AC_DEFUN(CY_AC_PATH_TCLH, [
+#
+# Ok, lets find the tcl source trees so we can use the headers
+# Warning: transition of version 9 to 10 will break this algorithm
+# because 10 sorts before 9. We also look for just tcl. We have to
+# be careful that we don't match stuff like tclX by accident.
+# the alternative search directory is involked by --with-tclinclude
+#
+no_tcl=true
+AC_MSG_CHECKING(for Tcl private headers)
+AC_ARG_WITH(tclinclude, [ --with-tclinclude directory where tcl private headers are], with_tclinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tclh,[
+# first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory doesn't contain private headers])
+ fi
+fi
+
+# next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" != x ; then
+ if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/../generic; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+changequote(,)
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../tcl \
+ `ls -dr ${srcdir}/../../tcl[7-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../../tcl \
+ `ls -dr ${srcdir}/../../../tcl[7-9].[0-9] 2>/dev/null ` ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+changequote([,])
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+changequote(,)
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tcl[7-9].[0-9] 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[7-9].[0-9] 2>/dev/null` \
+ /usr/local/src/tcl \
+ /usr/local/lib/tcl \
+ ${prefix}/include ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+changequote([,])
+# see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ AC_HEADER_CHECK(tclInt.h, ac_cv_c_tclh=installed, ac_cv_c_tclh="")
+fi
+])
+if test x"${ac_cv_c_tclh}" = x ; then
+ TCLHDIR="# no Tcl private headers found"
+ TCLHDIRDASHI="# no Tcl private headers found"
+ AC_MSG_ERROR([Can't find Tcl private headers])
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TCLHDIR=""
+ TCLHDIRDASHI=""
+ TCL_LIBRARY=""
+ else
+ AC_MSG_RESULT([found in ${ac_cv_c_tclh}])
+ # this hack is cause the TCLHDIR won't print if there is a "-I" in it.
+ TCLHDIR="${ac_cv_c_tclh}"
+ TCLHDIRDASHI="-I${ac_cv_c_tclh}"
+ TCL_LIBRARY=`echo $TCLHDIR | sed -e 's/generic//'`library
+ fi
+fi
+
+AC_SUBST(TCLHDIR)
+AC_SUBST(TCLHDIRDASHI)
+AC_SUBST(TCL_LIBRARY)
+])
+
+
+AC_DEFUN(CY_AC_PATH_TCLCONFIG, [
+#
+# Ok, lets find the tcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tclconfig
+#
+
+if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tclconfig, [ --with-tclconfig directory containing tcl configuration (tclConfig.sh)],
+ with_tclconfig=${withval})
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+changequote(,)
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[7-9].[0-9] 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[7-9].[0-9] 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[7-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+changequote([,])
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+changequote(,)
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+changequote([,])
+ ])
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG="# no Tcl configs found"
+ AC_MSG_WARN(Can't find Tcl configuration definitions)
+ else
+ no_tcl=
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ AC_MSG_RESULT(found $TCLCONFIG)
+ fi
+fi
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TCLCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TCLCONFIG, [
+ . $TCLCONFIG
+
+dnl AC_SUBST(TCL_VERSION)
+dnl AC_SUBST(TCL_MAJOR_VERSION)
+dnl AC_SUBST(TCL_MINOR_VERSION)
+dnl AC_SUBST(TCL_CC)
+ AC_SUBST(TCL_DEFS)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_LIB_FILE)
+
+dnl don't export, not used outside of configure
+dnl AC_SUBST(TCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_EXEC_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_SHLIB_CFLAGS)
+ AC_SUBST(TCL_SHLIB_LD)
+dnl don't export, not used outside of configure
+dnl AC_SUBST(TCL_SHLIB_LD_LIBS)
+dnl AC_SUBST(TCL_SHLIB_SUFFIX)
+
+# Tcl defines TCL_SHLIB_SUFFIX but TCL_SHARED_LIB_SUFFIX then looks for it
+# as just SHLIB_SUFFIX. How bizarre.
+ SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX
+ AC_SUBST(SHLIB_SUFFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_DL_LIBS)
+ AC_SUBST(TCL_LD_FLAGS)
+dnl don't export, not used outside of configure
+dnl AC_SUBST(TCL_LD_SEARCH_FLAGS)
+dnl AC_SUBST(TCL_COMPAT_OBJS)
+AC_SUBST(TCL_RANLIB)
+
+dnl CYGNUS LOCAL:
+dnl Anyone that tries to build expect without Tcl, deserves what happens
+dnl to them.
+dnl
+dnl # if Tcl's build directory has been removed, TCL_LIB_SPEC should
+dnl # be used instead of TCL_BUILD_LIB_SPEC
+dnl SAVELIBS=$LIBS
+dnl LIBS="$TCL_BUILD_LIB_SPEC $TCL_LIBS"
+dnl AC_CHECK_FUNC(Tcl_CreateCommand,[
+dnl AC_MSG_CHECKING([if Tcl library build specification is valid])
+dnl AC_MSG_RESULT(yes)
+dnl ],[
+dnl TCL_BUILD_LIB_SPEC=$TCL_LIB_SPEC
+dnl # Can't pull the following CHECKING call out since it will be
+dnl # broken up by the CHECK_FUNC just above.
+dnl AC_MSG_CHECKING([if Tcl library build specification is valid])
+dnl AC_MSG_RESULT(no)
+dnl])
+dnl LIBS=$SAVELIBS
+
+ AC_SUBST(TCL_BUILD_LIB_SPEC)
+ AC_SUBST(TCL_LIB_SPEC)
+dnl AC_SUBST(TCL_LIB_VERSIONS_OK)
+
+dnl not used, don't export to save symbols
+ AC_SUBST(TCL_SHARED_LIB_SUFFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_UNSHARED_LIB_SUFFIX)
+])
+
+# Warning: Tk definitions are very similar to Tcl definitions but
+# are not precisely the same. There are a couple of differences,
+# so don't do changes to Tcl thinking you can cut and paste it do
+# the Tk differences and later simply substitute "Tk" for "Tcl".
+# Known differences:
+# - Acceptable Tcl major version #s is 7-9 while Tk is 4-9
+# - Searching for Tcl includes looking for tclInt.h, Tk looks for tk.h
+# - Computing major/minor versions is different because Tk depends on
+# headers to Tcl, Tk, and X.
+# - Symbols in tkConfig.sh are different than tclConfig.sh
+# - Acceptable for Tk to be missing but not Tcl.
+
+AC_DEFUN(CY_AC_PATH_TKH, [
+#
+# Ok, lets find the tk source trees so we can use the headers
+# If the directory (presumably symlink) named "tk" exists, use that one
+# in preference to any others. Same logic is used when choosing library
+# and again with Tcl. The search order is the best place to look first, then in
+# decreasing significance. The loop breaks if the trigger file is found.
+# Note the gross little conversion here of srcdir by cd'ing to the found
+# directory. This converts the path from a relative to an absolute, so
+# recursive cache variables for the path will work right. We check all
+# the possible paths in one loop rather than many seperate loops to speed
+# things up.
+# the alternative search directory is involked by --with-tkinclude
+#
+#no_tk=true
+AC_MSG_CHECKING(for Tk private headers)
+AC_ARG_WITH(tkinclude, [ --with-tkinclude directory where tk private headers are], with_tkinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tkh,[
+# first check to see if --with-tkinclude was specified
+if test x"${with_tkinclude}" != x ; then
+ if test -f ${with_tkinclude}/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
+ elif test -f ${with_tkinclude}/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory doesn't contain private headers])
+ fi
+fi
+
+# next check if it came with Tk configuration file
+if test x"${ac_cv_c_tkconfig}" != x ; then
+ if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/../generic; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+changequote(,)
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[4-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../tk \
+ `ls -dr ${srcdir}/../../tk[4-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../../tk \
+ `ls -dr ${srcdir}/../../../tk[4-9].[0-9] 2>/dev/null ` ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+changequote([,])
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+changequote(,)
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tk[4-9].[0-9] 2>/dev/null` \
+ `ls -dr /usr/local/lib/tk[4-9].[0-9] 2>/dev/null` \
+ /usr/local/src/tk \
+ /usr/local/lib/tk \
+ ${prefix}/include ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+changequote([,])
+# see if one is installed
+if test x"${ac_cv_c_tkh}" = x ; then
+ AC_HEADER_CHECK(tk.h, ac_cv_c_tkh=installed, ac_cv_c_tkh="")
+fi
+])
+if test x"${ac_cv_c_tkh}" != x ; then
+# no_tk=""
+ if test x"${ac_cv_c_tkh}" = x"installed" ; then
+ AC_MSG_RESULT([is installed])
+ TKHDIRDASHI=""
+ else
+ AC_MSG_RESULT([found in ${ac_cv_c_tkh}])
+ # this hack is cause the TKHDIRDASHI won't print if there is a "-I" in it.
+ TKHDIRDASHI="-I${ac_cv_c_tkh}"
+ fi
+else
+ TKHDIRDASHI="# no Tk directory found"
+ AC_MSG_WARN([Can't find Tk private headers])
+ no_tk=true
+fi
+
+AC_SUBST(TKHDIRDASHI)
+])
+
+
+AC_DEFUN(CY_AC_PATH_TKCONFIG, [
+#
+# Ok, lets find the tk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tkconfig
+#
+
+if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tkconfig, [ --with-tkconfig directory containing tk configuration (tkConfig.sh)],
+ with_tkconfig=${withval})
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+changequote(,)
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[4-9].[0-9] 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[4-9].[0-9] 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[4-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+changequote([,])
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+changequote(,)
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[4-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+changequote([,])
+ ])
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TKCONFIG="# no Tk configs found"
+ AC_MSG_WARN(Can't find Tk configuration definitions)
+ else
+ no_tk=
+ TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh
+ AC_MSG_RESULT(found $TKCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TKCONFIG (because this can also be cached).
+AC_DEFUN(CY_AC_LOAD_TKCONFIG, [
+ if test -f "$TKCONFIG" ; then
+ . $TKCONFIG
+ fi
+
+ AC_SUBST(TK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TK_MAJOR_VERSION)
+dnl AC_SUBST(TK_MINOR_VERSION)
+ AC_SUBST(TK_DEFS)
+
+dnl not used, don't export to save symbols
+ dnl AC_SUBST(TK_LIB_FILE)
+
+dnl not used outside of configure
+dnl AC_SUBST(TK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_EXEC_PREFIX)
+
+ AC_SUBST(TK_XINCLUDES)
+ AC_SUBST(TK_XLIBSW)
+ AC_SUBST(TK_BUILD_LIB_SPEC)
+ AC_SUBST(TK_LIB_SPEC)
+])
+
+# check for Itcl headers.
+
+AC_DEFUN(CY_AC_PATH_ITCLH, [
+AC_MSG_CHECKING(for Itcl private headers. srcdir=${srcdir})
+if test x"${ac_cv_c_itclh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ; do
+ if test -f $i/src/itcl.h ; then
+ ac_cv_c_itclh=`(cd $i/src; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itclh}" = x ; then
+ ITCLHDIR="# no Itcl private headers found"
+ ITCLLIB="# no Itcl private headers found"
+ AC_MSG_WARN([Can't find Itcl private headers])
+ no_itcl=true
+else
+ ITCLHDIR="-I${ac_cv_c_itclh}"
+# should always be here
+ ITCLLIB="../itcl/src/libitcl.a"
+fi
+
+AC_SUBST(ITCLHDIR)
+AC_SUBST(ITCLLIB)
+])
+
+# Check to see if we're running under Cygwin32, without using
+# AC_CANONICAL_*. If so, set output variable CYGWIN32 to "yes".
+# Otherwise set it to "no".
+
+dnl AM_CYGWIN32()
+dnl You might think we can do this by checking for a cygwin32-specific
+dnl cpp define.
+AC_DEFUN(CY_AC_CYGWIN32,
+[AC_CACHE_CHECK(for Cygwin32 environment, ac_cv_cygwin32,
+[AC_TRY_COMPILE(,[int main () { return __CYGWIN32__; }],
+ac_cv_cygwin32=yes, ac_cv_cygwin32=no)
+rm -f conftest*])
+CYGWIN32=
+test "$ac_cv_cygwin32" = yes && CYGWIN32=yes])
+
+# Check to see if we're running under Win32, without using
+# AC_CANONICAL_*. If so, set output variable EXEEXT to ".exe".
+# Otherwise set it to "".
+
+dnl AM_EXEEXT()
+dnl This knows we add .exe if we're building in the Cygwin32
+dnl environment. But if we're not, then it compiles a test program
+dnl to see if there is a suffix for executables.
+AC_DEFUN(CY_AC_EXEEXT,
+dnl AC_REQUIRE([AC_PROG_CC])AC_REQUIRE([AM_CYGWIN32])
+AC_MSG_CHECKING([for executable suffix])
+[AC_CACHE_VAL(ac_cv_exeext,
+[if test "$CYGWIN32" = yes; then
+ac_cv_exeext=.exe
+else
+cat > ac_c_test.c << 'EOF'
+int main() {
+/* Nothing needed here */
+}
+EOF
+${CC-cc} -o ac_c_test $CFLAGS $CPPFLAGS $LDFLAGS ac_c_test.c $LIBS 1>&5
+ac_cv_exeext=`ls ac_c_test.* | grep -v ac_c_test.c | sed -e s/ac_c_test//`
+rm -f ac_c_test*])
+test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+AC_MSG_RESULT(${ac_cv_exeext})
+AC_SUBST(EXEEXT)])
+
+# Check for inttypes.h. On some older systems there is a
+# conflict with the definitions of int8_t, int16_t, int32_t
+# that are in sys/types.h. So we have to compile the test
+# program with both, to make sure we want inttypes to be
+# included.
+AC_DEFUN(CY_AC_INTTYPES_H,
+[AC_MSG_CHECKING(for inttypes.h)
+AC_CACHE_VAL(ac_cv_inttypes_h,
+ [AC_TRY_COMPILE([
+ #include <sys/types.h>
+ #include <inttypes.h>],
+ [
+ int16_t x = 0;
+ ], ac_cv_inttypes_h="yes", ac_cv_inttypes_h="no")])
+AC_MSG_RESULT($ac_cv_inttypes_h)
+if test x"${ac_cv_inttypes_h}" = x"yes"; then
+ AC_DEFINE(HAVE_INTTYPES_H)
+fi
+])
+
diff --git a/expect/configure b/expect/configure
new file mode 100755
index 00000000000..369b5c23728
--- /dev/null
+++ b/expect/configure
@@ -0,0 +1,6684 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-tclconfig directory containing tcl configuration (tclConfig.sh)"
+ac_help="$ac_help
+ --with-tkconfig directory containing tk configuration (tkConfig.sh)"
+ac_help="$ac_help
+ --with-tclinclude directory where tcl private headers are"
+ac_help="$ac_help
+ --enable-shared build libexpect as a shared library"
+ac_help="$ac_help
+ --with-x whether or not to use X (default yes)"
+ac_help="$ac_help
+ --with-tkinclude directory where tk private headers are"
+ac_help="$ac_help
+ --disable-load disallow dynamic loading"
+ac_help="$ac_help
+ --enable-gcc allow use of gcc if available"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+sitefile=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --site-file=FILE use FILE as the site file
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -site-file | --site-file | --site-fil | --site-fi | --site-f)
+ ac_prev=sitefile ;;
+ -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+ sitefile="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=expect.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$sitefile"; then
+ if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+ fi
+else
+ CONFIG_SITE="$sitefile"
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir/.. $srcdir/$srcdir/..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir/.. $srcdir/$srcdir/.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# note when updating version numbers here, also update pkgIndex.in (see
+# comments in Makefile)
+EXP_MAJOR_VERSION=5
+EXP_MINOR_VERSION=26
+EXP_MICRO_VERSION=0
+EXP_VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION
+EXP_VERSION_NODOTS=$EXP_MAJOR_VERSION$EXP_MINOR_VERSION
+EXP_VERSION_FULL=$EXP_VERSION.$EXP_MICRO_VERSION
+
+# Tcl's handling of shared_lib_suffix requires this symbol exist
+VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION
+
+# Too many people send me configure output without identifying the version.
+# This forced identification should reduce my pain significantly.
+echo "configuring Expect $EXP_MAJOR_VERSION.$EXP_MINOR_VERSION.$EXP_MICRO_VERSION"
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:610: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:631: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:649: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+
+
+# /bin/sh on some systems is too deficient (in particular, Ultrix 4.3
+# sh lacks unset and we *need* that), but all these systems come with
+# alternatives, so take user's choice or whatever we're using here and
+# allow it to be seen by Make.
+echo $ac_n "checking shell to use within Make""... $ac_c" 1>&6
+echo "configure:679: checking shell to use within Make" >&5
+EXP_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+echo "$ac_t""$CONFIG_SHELL" 1>&6
+
+# If `configure' is invoked (in)directly via `make', ensure that it
+# encounters no `make' conflicts.
+#
+unset MFLAGS MAKEFLAGS
+MFLAGS=""
+MAKEFLAGS=""
+
+
+#
+# Ok, lets find the tcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tclconfig
+#
+
+if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ # Check whether --with-tclconfig or --without-tclconfig was given.
+if test "${with_tclconfig+set}" = set; then
+ withval="$with_tclconfig"
+ with_tclconfig=${withval}
+fi
+
+ echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6
+echo "configure:707: checking for Tcl configuration" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+
+ # First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ { echo "configure: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" 1>&2; exit 1; }
+ fi
+ fi
+
+ # then check for a private Tcl installation
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[7-9].[0-9] 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[7-9].[0-9] 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[7-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+
+fi
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG="# no Tcl configs found"
+ echo "configure: warning: Can't find Tcl configuration definitions" 1>&2
+ else
+ no_tcl=
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ echo "$ac_t""found $TCLCONFIG" 1>&6
+ fi
+fi
+
+
+ . $TCLCONFIG
+
+
+
+
+
+
+
+
+# Tcl defines TCL_SHLIB_SUFFIX but TCL_SHARED_LIB_SUFFIX then looks for it
+# as just SHLIB_SUFFIX. How bizarre.
+ SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX
+
+
+
+
+
+
+
+
+
+
+
+
+CC=$TCL_CC
+EXP_AND_TCL_LIBS=$TCL_LIBS
+
+#
+# Ok, lets find the tk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tkconfig
+#
+
+if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ # Check whether --with-tkconfig or --without-tkconfig was given.
+if test "${with_tkconfig+set}" = set; then
+ withval="$with_tkconfig"
+ with_tkconfig=${withval}
+fi
+
+ echo $ac_n "checking for Tk configuration""... $ac_c" 1>&6
+echo "configure:818: checking for Tk configuration" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_tkconfig'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+ else
+ { echo "configure: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" 1>&2; exit 1; }
+ fi
+ fi
+
+ # then check for a private Tk library
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[4-9].[0-9] 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[4-9].[0-9] 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[4-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[4-9].[0-9] 2>/dev/null` ; do
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+
+fi
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TKCONFIG="# no Tk configs found"
+ echo "configure: warning: Can't find Tk configuration definitions" 1>&2
+ else
+ no_tk=
+ TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh
+ echo "$ac_t""found $TKCONFIG" 1>&6
+ fi
+fi
+
+
+
+ if test -f "$TKCONFIG" ; then
+ . $TKCONFIG
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+EXP_AND_TK_LIBS=$TK_LIBS
+
+# CYGNUS LOCAL dj/cygwin
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:912: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+# If we built a cygwin-specific tcl, use it here.
+case "${host}" in
+*-*-cygwin*)
+ if test -d $srcdir/../tcl/cygwin/.
+ then
+ TCL_BUILD_LIB_SPEC="../tcl/cygwin/libtcl8.0.a"
+ # Use the same static lib for installed_expect
+ TCL_LIB_SPEC="../tcl/cygwin/libtcl8.0.a"
+ fi
+ ;;
+esac
+
+# An explanation is in order for the strange things going on with the
+# various LIBS. There are three separate definitions for LIBS. The
+# reason is that some systems require shared libraries include
+# references to their dependent libraries, i.e., any additional
+# libraries that must be linked to. And some systems get upset if the
+# references are repeated on the link line. So therefore, we create
+# one for Expect and Tk (EXP_AND_TK_LIBS), one for Expect and Tcl
+# (EXP_AND_TCL_LIBS), and finally, one for building Expect's own
+# shared library. Tcl's tclConfig.sh insists that any shared libs
+# that it "helps" build must pass the libraries as LIBS (see comment
+# near end of this configure file). I would do but since we're close
+# to hitting config's max symbols, we take one short cut and pack the
+# LIBS into EXP_SHLIB_LD_LIBS (which is basically what Tcl wants to do
+# for us). The point, however, is that there's no separate LIBS or
+# EXP_LIBS symbol passed out of configure. One additional point for
+# confusion is that LIBS is what configure uses to do all library
+# tests, so we have to swap definitions of LIBS peridically. When we
+# are swapping out the one for Expect's shared library, we save it in
+# EXP_LIBS. Sigh.
+
+OLD_CFLAGS=$CFLAGS
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:968: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:998: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1049: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1081: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1092 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1123: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1128: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1137: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1156: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+CFLAGS=$OLD_CFLAGS
+
+# If we cannot compile and link a trivial program, we can't expect anything to work
+echo $ac_n "checking whether the compiler ($CC) actually works""... $ac_c" 1>&6
+echo "configure:1191: checking whether the compiler ($CC) actually works" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1193 "configure"
+#include "confdefs.h"
+
+int main() {
+/* don't need anything here */
+; return 0; }
+EOF
+if { (eval echo configure:1200: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ c_compiles=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ c_compiles=no
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 1212 "configure"
+#include "confdefs.h"
+
+int main() {
+/* don't need anything here */
+; return 0; }
+EOF
+if { (eval echo configure:1219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ c_links=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ c_links=no
+fi
+rm -f conftest*
+
+if test x"${c_compiles}" = x"no" ; then
+ { echo "configure: error: the native compiler is broken and won't compile." 1>&2; exit 1; }
+fi
+
+if test x"${c_links}" = x"no" ; then
+ { echo "configure: error: the native compiler is broken and won't link." 1>&2; exit 1; }
+fi
+echo "$ac_t""yes" 1>&6
+
+
+# this'll use a BSD compatible install or our included install-sh
+# 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
+# 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"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1253: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1310: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+UNSHARED_RANLIB=$RANLIB
+
+# these are the other subdirectories we need to configure
+subdirs="testsuite"
+
+
+# This is for LynxOS, which needs a flag to force true POSIX when
+# building. The flag varies depending how old the compiler is.
+# -X is for the old "cc" and "gcc" (based on 1.42)
+# -mposix is for the new gcc (at least 2.5.8)
+# This modifies the value of $CC to have the POSIX flag added
+# so it'll configure correctly
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1350: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1365 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1371: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1382 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1388: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1399 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+
+echo $ac_n "checking if running LynxOS""... $ac_c" 1>&6
+echo "configure:1431: checking if running LynxOS" >&5
+if eval "test \"`echo '$''{'ac_cv_os_lynx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1436 "configure"
+#include "confdefs.h"
+/*
+ * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__"
+ */
+#if defined(__Lynx__) || defined(Lynx)
+yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_lynx=yes
+else
+ rm -rf conftest*
+ ac_cv_os_lynx=no
+fi
+rm -f conftest*
+
+fi
+
+#
+if test "$ac_cv_os_lynx" = "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define LYNX 1
+EOF
+
+ echo $ac_n "checking whether -mposix or -X is available""... $ac_c" 1>&6
+echo "configure:1466: checking whether -mposix or -X is available" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_posix_flag'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1471 "configure"
+#include "confdefs.h"
+
+int main() {
+
+ /*
+ * This flag varies depending on how old the compiler is.
+ * -X is for the old "cc" and "gcc" (based on 1.42).
+ * -mposix is for the new gcc (at least 2.5.8).
+ */
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ choke me
+ #endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1487: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_posix_flag=" -mposix"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_posix_flag=" -X"
+fi
+rm -f conftest*
+fi
+
+ CC="$CC $ac_cv_c_posix_flag"
+ echo "$ac_t""$ac_cv_c_posix_flag" 1>&6
+ else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1507: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1512 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1520: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1537 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1555 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1576 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:1611: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1616 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:1644: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1649 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:1666: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1685: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1690 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1699: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:1720: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1725 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(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; }
+EOF
+if { (eval echo configure:1741: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+
+EXP_CFLAGS=""
+# Use -g on all systems but Linux where it upsets the dynamic X libraries.
+
+echo $ac_n "checking if running Mach""... $ac_c" 1>&6
+echo "configure:1766: checking if running Mach" >&5
+mach=0
+case "${host}" in
+ # Both Next and pure Mach behave identically with respect
+ # to a few things, so just lump them together as "mach"
+ *-*-mach*) mach=1 ;;
+ *-*-next*) mach=1 ; next=1 ;;
+esac
+
+if test $mach -eq 1 ; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking if running MachTen""... $ac_c" 1>&6
+echo "configure:1782: checking if running MachTen" >&5
+# yet another Mach clone
+if test -r /MachTen -a "$cross_compiling" != "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ mach=1
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking if on Pyramid""... $ac_c" 1>&6
+echo "configure:1792: checking if on Pyramid" >&5
+if test -r /bin/pyr -a "$cross_compiling" != "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ pyr=1
+else
+ echo "$ac_t""no" 1>&6
+ pyr=0
+fi
+
+echo $ac_n "checking if on Apollo""... $ac_c" 1>&6
+echo "configure:1802: checking if on Apollo" >&5
+if test -r /usr/apollo/bin -a "$cross_compiling" != "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ apollo=1
+else
+ echo "$ac_t""no" 1>&6
+ apollo=0
+fi
+
+echo $ac_n "checking if on Interactive""... $ac_c" 1>&6
+echo "configure:1812: checking if on Interactive" >&5
+if test "x`(uname -s) 2>/dev/null`" = xIUNIX; then
+ echo "$ac_t""yes" 1>&6
+ iunix=1
+else
+ echo "$ac_t""no" 1>&6
+ iunix=0
+fi
+
+echo $ac_n "checking if stty reads stdout""... $ac_c" 1>&6
+echo "configure:1822: checking if stty reads stdout" >&5
+
+# On some systems stty can't be run in the background (svr4) or get it
+# wrong because they fail to complain (next, mach), so don't attempt
+# the test on some systems.
+
+stty_reads_stdout=""
+case "${host}" in
+ *-*-solaris*) stty_reads_stdout=0 ;;
+ *-*-irix*) stty_reads_stdout=0 ;;
+ *-*-sco3.2v[45]*) stty_reads_stdout=1 ;;
+ i[3456]86-*-sysv4.2MP) stty_reads_stdout=0 ;;
+ i[3456]86-*-linux*) stty_reads_stdout=0 ;;
+ # Not sure about old convex but 5.2 definitely reads from stdout
+ c[12]-*-*) stty_reads_stdout=1 ;;
+ *-*-aix[34]*) stty_reads_stdout=0 ;;
+ *-*-hpux9*) stty_reads_stdout=0 ;;
+ *-*-hpux10*) stty_reads_stdout=0 ;;
+ *-*-hpux11*) stty_reads_stdout=0 ;;
+ *-*-osf[234]*) stty_reads_stdout=0 ;;
+ *-*-ultrix4.4) stty_reads_stdout=0 ;;
+ *-*-dgux*) stty_reads_stdout=0 ;;
+ *-*-cygwin*) stty_reads_stdout=0 ;;
+esac
+
+if test $mach -eq 1 ; then
+ stty_reads_stdout=1
+fi
+if test $apollo -eq 1 ; then
+ stty_reads_stdout=1
+fi
+if test $pyr -eq 1 ; then
+ stty_reads_stdout=1
+fi
+
+# if we still don't know, test
+if test x"${stty_reads_stdout}" = x"" ; then
+ /bin/stty > /dev/null 2> /dev/null
+ if test $? -ne 0 ; then
+ stty_reads_stdout=1
+ else
+ stty_reads_stdout=0
+ fi
+fi
+
+if test ${stty_reads_stdout} -eq 1 ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define STTY_READS_STDOUT 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Solaris 2.4 and later requires __EXTENSIONS__ in order to see all sorts
+# of traditional but nonstandard stuff in header files.
+echo $ac_n "checking if running Solaris""... $ac_c" 1>&6
+echo "configure:1880: checking if running Solaris" >&5
+solaris=0
+case "${host}" in
+ *-*-solaris*) solaris=1;;
+esac
+
+if test $solaris -eq 1 ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define SOLARIS 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+# On a few systems, libm.a is the same as libc.a
+# Don't bother to test against Tcl and Tk libs, they always include -lm
+echo $ac_n "checking for sin""... $ac_c" 1>&6
+echo "configure:1900: checking for sin" >&5
+if eval "test \"`echo '$''{'ac_cv_func_sin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1905 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char sin(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char sin();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_sin) || defined (__stub___sin)
+choke me
+#else
+sin();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1928: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_sin=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_sin=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'sin`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+LIBS="${LIBS} -lm"
+fi
+
+
+# On Interactive UNIX, -Xp must be added to LIBS in order to find strftime.
+# This test should really be done by Tcl. So just check Tcl's definition.
+# If defective, add to all three LIBS. (It's not actually necessary for
+# EXP_LIBS since -Xp will just be ignored the way that EXP_LIBS is used in
+# the Makefile, but we include it for consistency.)
+if test $iunix -eq 1 ; then
+ EXP_LIBS=$LIBS
+ LIBS=$EXP_AND_TCL_LIBS
+ echo $ac_n "checking for strftime""... $ac_c" 1>&6
+echo "configure:1958: checking for strftime" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1963 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strftime(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strftime();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strftime) || defined (__stub___strftime)
+choke me
+#else
+strftime();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1986: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+
+ EXP_LIBS="${LIBS} -Xp"
+ EXP_AND_TCL_LIBS="${LIBS} -Xp"
+ EXP_AND_TK_LIBS="${LIBS} -Xp"
+
+fi
+
+ LIBS=EXP_LIBS
+fi
+
+#
+# Ok, lets find the tcl source trees so we can use the headers
+#
+
+#
+# Ok, lets find the tcl source trees so we can use the headers
+# Warning: transition of version 9 to 10 will break this algorithm
+# because 10 sorts before 9. We also look for just tcl. We have to
+# be careful that we don't match stuff like tclX by accident.
+# the alternative search directory is involked by --with-tclinclude
+#
+no_tcl=true
+echo $ac_n "checking for Tcl private headers""... $ac_c" 1>&6
+echo "configure:2026: checking for Tcl private headers" >&5
+# Check whether --with-tclinclude or --without-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then
+ withval="$with_tclinclude"
+ with_tclinclude=${withval}
+fi
+
+if eval "test \"`echo '$''{'ac_cv_c_tclh'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+# first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
+ else
+ { echo "configure: error: ${with_tclinclude} directory doesn't contain private headers" 1>&2; exit 1; }
+ fi
+fi
+
+# next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" != x ; then
+ if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/../generic; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../tcl \
+ `ls -dr ${srcdir}/../../tcl[7-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../../tcl \
+ `ls -dr ${srcdir}/../../../tcl[7-9].[0-9] 2>/dev/null ` ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tcl[7-9].[0-9] 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[7-9].[0-9] 2>/dev/null` \
+ /usr/local/src/tcl \
+ /usr/local/lib/tcl \
+ ${prefix}/include ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+# see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ ac_safe=`echo "tclInt.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for tclInt.h""... $ac_c" 1>&6
+echo "configure:2096: checking for tclInt.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2101 "configure"
+#include "confdefs.h"
+#include <tclInt.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2106: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_cv_c_tclh=installed
+else
+ echo "$ac_t""no" 1>&6
+ac_cv_c_tclh=""
+fi
+
+fi
+
+fi
+
+if test x"${ac_cv_c_tclh}" = x ; then
+ TCLHDIR="# no Tcl private headers found"
+ TCLHDIRDASHI="# no Tcl private headers found"
+ { echo "configure: error: Can't find Tcl private headers" 1>&2; exit 1; }
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
+ echo "$ac_t""is installed" 1>&6
+ TCLHDIR=""
+ TCLHDIRDASHI=""
+ TCL_LIBRARY=""
+ else
+ echo "$ac_t""found in ${ac_cv_c_tclh}" 1>&6
+ # this hack is cause the TCLHDIR won't print if there is a "-I" in it.
+ TCLHDIR="${ac_cv_c_tclh}"
+ TCLHDIRDASHI="-I${ac_cv_c_tclh}"
+ TCL_LIBRARY=`echo $TCLHDIR | sed -e 's/generic//'`library
+ fi
+fi
+
+
+
+
+
+if test x"$no_tcl" = x"true" ; then
+ echo " ERROR: Can't find Tcl headers or library."
+ echo " See README for information on how to obtain Tcl."
+ echo " If Tcl is installed, see INSTALL on how to tell"
+ echo " configure where Tcl is installed."
+ exit 1
+fi
+
+echo $ac_n "checking for Itcl private headers. srcdir=${srcdir}""... $ac_c" 1>&6
+echo "configure:2166: checking for Itcl private headers. srcdir=${srcdir}" >&5
+if test x"${ac_cv_c_itclh}" = x ; then
+ for i in ${srcdir}/../itcl ${srcdir}/../../itcl ${srcdir}/../../../itcl ; do
+ if test -f $i/src/itcl.h ; then
+ ac_cv_c_itclh=`(cd $i/src; pwd)`
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itclh}" = x ; then
+ ITCLHDIR="# no Itcl private headers found"
+ ITCLLIB="# no Itcl private headers found"
+ echo "configure: warning: Can't find Itcl private headers" 1>&2
+ no_itcl=true
+else
+ ITCLHDIR="-I${ac_cv_c_itclh}"
+# should always be here
+ ITCLLIB="../itcl/src/libitcl.a"
+fi
+
+
+
+
+
+# have to whether we're generating shared libs before configuring debugger
+echo $ac_n "checking if generating shared or nonshared library""... $ac_c" 1>&6
+echo "configure:2192: checking if generating shared or nonshared library" >&5
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ enable_shared=$enableval
+else
+ enable_shared=no
+fi
+
+if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then
+ echo "$ac_t""both shared and unshared" 1>&6
+else
+ echo "$ac_t""unshared" 1>&6
+fi
+
+# Now that we've found the Tcl sources, configure the debugger
+# this is a little tricky because it has its own configure script
+# which produces a Makefile and cf file. We only want the cf file,
+# so switch to a temporary directory and run the debugger's configure.
+# Then save the cf file and delete the rest.
+#
+# Incidentally, the debugger can't depend on Expect's cf file, because
+# the debugger is designed to be independent of Expect.
+#
+
+test -n "$verbose" && echo "configuring Tcl debugger"
+tmpdir=./Dbg$$
+mkdir ${tmpdir}
+
+if test "${enable_shared}" = "yes"; then
+ dbg_config_flags='--enable-shared'
+else
+ dbg_config_flags='--disable-shared'
+fi
+# (cd;pwd) in next several commands converts relative dirs to absolute.
+# This is required because the debugger src is at a different level in
+# the filesystem than Expect src (where we are presently), thereby
+# making the relative pathnames incorrect.
+if test "x$with_tclconfig" != "x" ; then
+ dbg_config_flags="$dbg_config_flags --with-tclconfig=`(cd ${with_tclconfig}; pwd)`"
+fi
+if test "x$with_tcllibdir" != "x" ; then
+ dbg_config_flags="$dbg_config_flags --with-tcllibdir=`(cd ${with_tcllibdir}; pwd)`"
+fi
+if test "x$with_tcllib" != "x" ; then
+ dbg_config_flags="$dbg_config_flags --with-tcllib=`(cd ${with_tcllib}; pwd)`"
+fi
+if test "x$with_tclinclude" != "x" ; then
+ dbg_config_flags="$dbg_config_flags --with-tclinclude=`(cd ${with_tclinclude}; pwd)`"
+fi
+case "$cache_file" in
+ /*)
+ dbg_config_flags="$dbg_config_flags --cache-file=$cache_file"
+ ;;
+ *)
+ dbg_config_flags="$dbg_config_flags --cache-file=../$cache_file"
+ ;;
+esac
+
+cp ${srcdir}/Dbgconfigure ${srcdir}/Dbg.h ${srcdir}/Dbg_cf.h.in ${srcdir}/install-sh ${tmpdir}
+cp $srcdir/DbgMkfl.in ${tmpdir}/Makefile.in
+ (cd $tmpdir; ${CONFIG_SHELL-/bin/sh} Dbgconfigure --with-tclinclude=`echo ${TCLHDIR} | sed -e 's/-I//'` $dbg_config_flags)
+cp ${tmpdir}/Dbg_cf.h .
+rm -rf $tmpdir
+test -n "$verbose" && echo "configured Tcl debugger"
+
+# some people would complain if this explanation wasn't provided...
+
+echo "Begin tests for function/library dependencies. Tests may be repeated"
+echo "up to three times. First test is for building Expect's shared library."
+echo "Second set is for building with Tcl. Third is for building with Tk."
+
+######################################################################
+# required by Sequent ptx2
+unset ac_cv_func_gethostname
+echo $ac_n "checking for gethostname""... $ac_c" 1>&6
+echo "configure:2268: checking for gethostname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2273 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gethostname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gethostname) || defined (__stub___gethostname)
+choke me
+#else
+gethostname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2296: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ gethostname=1
+else
+ echo "$ac_t""no" 1>&6
+gethostname=0
+fi
+
+if test $gethostname -eq 0 ; then
+ unset ac_cv_lib_inet_gethostname
+ echo $ac_n "checking for gethostname in -linet""... $ac_c" 1>&6
+echo "configure:2319: checking for gethostname in -linet" >&5
+ac_lib_var=`echo inet'_'gethostname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2327 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostname();
+
+int main() {
+gethostname()
+; return 0; }
+EOF
+if { (eval echo configure:2338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save results and retry for Tcl
+EXP_LIBS=$LIBS
+LIBS=$EXP_AND_TCL_LIBS
+unset ac_cv_func_gethostname
+echo $ac_n "checking for gethostname""... $ac_c" 1>&6
+echo "configure:2364: checking for gethostname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2369 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gethostname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gethostname) || defined (__stub___gethostname)
+choke me
+#else
+gethostname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ gethostname=1
+else
+ echo "$ac_t""no" 1>&6
+gethostname=0
+fi
+
+if test $gethostname -eq 0 ; then
+ unset ac_cv_lib_inet_gethostname
+ echo $ac_n "checking for gethostname in -linet""... $ac_c" 1>&6
+echo "configure:2415: checking for gethostname in -linet" >&5
+ac_lib_var=`echo inet'_'gethostname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2423 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostname();
+
+int main() {
+gethostname()
+; return 0; }
+EOF
+if { (eval echo configure:2434: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save Tcl results and retry for Tk
+EXP_AND_TCL_LIBS=$LIBS
+LIBS=$EXP_AND_TK_LIBS
+unset ac_cv_func_gethostname
+echo $ac_n "checking for gethostname""... $ac_c" 1>&6
+echo "configure:2460: checking for gethostname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2465 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gethostname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gethostname) || defined (__stub___gethostname)
+choke me
+#else
+gethostname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2488: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ gethostname=1
+else
+ echo "$ac_t""no" 1>&6
+gethostname=0
+fi
+
+if test $gethostname -eq 0 ; then
+ unset ac_cv_lib_inet_gethostname
+ echo $ac_n "checking for gethostname in -linet""... $ac_c" 1>&6
+echo "configure:2511: checking for gethostname in -linet" >&5
+ac_lib_var=`echo inet'_'gethostname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2519 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostname();
+
+int main() {
+gethostname()
+; return 0; }
+EOF
+if { (eval echo configure:2530: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save Tk results and reset for Expect
+EXP_AND_TK_LIBS=$LIBS
+LIBS=$EXP_LIBS
+
+######################################################################
+# required by Fischman's ISC 4.0
+unset ac_cv_func_socket
+echo $ac_n "checking for socket""... $ac_c" 1>&6
+echo "configure:2559: checking for socket" >&5
+if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2564 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char socket(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_socket) || defined (__stub___socket)
+choke me
+#else
+socket();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_socket=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_socket=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ socket=1
+else
+ echo "$ac_t""no" 1>&6
+socket=0
+fi
+
+if test $socket -eq 0 ; then
+ unset ac_cv_lib_inet_socket
+ echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6
+echo "configure:2610: checking for socket in -linet" >&5
+ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2618 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:2629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save results and retry for Tcl
+EXP_LIBS=$LIBS
+LIBS=$EXP_AND_TCL_LIBS
+unset ac_cv_func_socket
+echo $ac_n "checking for socket""... $ac_c" 1>&6
+echo "configure:2655: checking for socket" >&5
+if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2660 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char socket(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_socket) || defined (__stub___socket)
+choke me
+#else
+socket();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2683: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_socket=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_socket=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ socket=1
+else
+ echo "$ac_t""no" 1>&6
+socket=0
+fi
+
+if test $socket -eq 0 ; then
+ unset ac_cv_lib_inet_socket
+ echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6
+echo "configure:2706: checking for socket in -linet" >&5
+ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2714 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:2725: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save Tcl results and retry for Tk
+EXP_AND_TCL_LIBS=$LIBS
+LIBS=$EXP_AND_TK_LIBS
+unset ac_cv_func_socket
+echo $ac_n "checking for socket""... $ac_c" 1>&6
+echo "configure:2751: checking for socket" >&5
+if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2756 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char socket(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_socket) || defined (__stub___socket)
+choke me
+#else
+socket();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2779: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_socket=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_socket=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ socket=1
+else
+ echo "$ac_t""no" 1>&6
+socket=0
+fi
+
+if test $socket -eq 0 ; then
+ unset ac_cv_lib_inet_socket
+ echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6
+echo "configure:2802: checking for socket in -linet" >&5
+ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2810 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:2821: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save Tk results and reset for Expect
+EXP_AND_TK_LIBS=$LIBS
+LIBS=$EXP_LIBS
+
+######################################################################
+unset ac_cv_func_select
+echo $ac_n "checking for select""... $ac_c" 1>&6
+echo "configure:2849: checking for select" >&5
+if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2854 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char select(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char select();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_select) || defined (__stub___select)
+choke me
+#else
+select();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_select=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_select=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ select=1
+else
+ echo "$ac_t""no" 1>&6
+select=0
+fi
+
+if test $select -eq 0 ; then
+ unset ac_cv_lib_inet_select
+ echo $ac_n "checking for select in -linet""... $ac_c" 1>&6
+echo "configure:2900: checking for select in -linet" >&5
+ac_lib_var=`echo inet'_'select | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2908 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char select();
+
+int main() {
+select()
+; return 0; }
+EOF
+if { (eval echo configure:2919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save results and retry for Tcl
+EXP_LIBS=$LIBS
+LIBS=$EXP_AND_TCL_LIBS
+unset ac_cv_func_select
+echo $ac_n "checking for select""... $ac_c" 1>&6
+echo "configure:2945: checking for select" >&5
+if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2950 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char select(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char select();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_select) || defined (__stub___select)
+choke me
+#else
+select();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_select=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_select=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ select=1
+else
+ echo "$ac_t""no" 1>&6
+select=0
+fi
+
+if test $select -eq 0 ; then
+ unset ac_cv_lib_inet_select
+ echo $ac_n "checking for select in -linet""... $ac_c" 1>&6
+echo "configure:2996: checking for select in -linet" >&5
+ac_lib_var=`echo inet'_'select | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3004 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char select();
+
+int main() {
+select()
+; return 0; }
+EOF
+if { (eval echo configure:3015: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save Tcl results and retry for Tk
+EXP_AND_TCL_LIBS=$LIBS
+LIBS=$EXP_AND_TK_LIBS
+unset ac_cv_func_select
+echo $ac_n "checking for select""... $ac_c" 1>&6
+echo "configure:3041: checking for select" >&5
+if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3046 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char select(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char select();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_select) || defined (__stub___select)
+choke me
+#else
+select();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3069: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_select=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_select=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ select=1
+else
+ echo "$ac_t""no" 1>&6
+select=0
+fi
+
+if test $select -eq 0 ; then
+ unset ac_cv_lib_inet_select
+ echo $ac_n "checking for select in -linet""... $ac_c" 1>&6
+echo "configure:3092: checking for select in -linet" >&5
+ac_lib_var=`echo inet'_'select | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3100 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char select();
+
+int main() {
+select()
+; return 0; }
+EOF
+if { (eval echo configure:3111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save Tk results and reset for Expect
+EXP_AND_TK_LIBS=$LIBS
+LIBS=$EXP_LIBS
+
+######################################################################
+unset ac_cv_func_getpseudotty
+echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6
+echo "configure:3139: checking for getpseudotty" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getpseudotty'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3144 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getpseudotty(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getpseudotty();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_getpseudotty) || defined (__stub___getpseudotty)
+choke me
+#else
+getpseudotty();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3167: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_getpseudotty=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_getpseudotty=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'getpseudotty`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ getpseudotty=1
+else
+ echo "$ac_t""no" 1>&6
+getpseudotty=0
+fi
+
+if test $getpseudotty -eq 0 ; then
+ unset ac_cv_lib_seq_getpseudotty
+ echo $ac_n "checking for getpseudotty in -lseq""... $ac_c" 1>&6
+echo "configure:3190: checking for getpseudotty in -lseq" >&5
+ac_lib_var=`echo seq'_'getpseudotty | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lseq $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3198 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getpseudotty();
+
+int main() {
+getpseudotty()
+; return 0; }
+EOF
+if { (eval echo configure:3209: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo seq | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lseq $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save results and retry for Tcl
+EXP_LIBS=$LIBS
+LIBS=$EXP_AND_TCL_LIBS
+unset ac_cv_func_getpseudotty
+echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6
+echo "configure:3242: checking for getpseudotty" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getpseudotty'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3247 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getpseudotty(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getpseudotty();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_getpseudotty) || defined (__stub___getpseudotty)
+choke me
+#else
+getpseudotty();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_getpseudotty=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_getpseudotty=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'getpseudotty`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ getpseudotty=1
+else
+ echo "$ac_t""no" 1>&6
+getpseudotty=0
+fi
+
+if test $getpseudotty -eq 0 ; then
+ unset ac_cv_lib_seq_getpseudotty
+ echo $ac_n "checking for getpseudotty in -lseq""... $ac_c" 1>&6
+echo "configure:3293: checking for getpseudotty in -lseq" >&5
+ac_lib_var=`echo seq'_'getpseudotty | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lseq $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3301 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getpseudotty();
+
+int main() {
+getpseudotty()
+; return 0; }
+EOF
+if { (eval echo configure:3312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo seq | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lseq $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save Tcl results and retry for Tk
+EXP_AND_TCL_LIBS=$LIBS
+LIBS=$EXP_AND_TK_LIBS
+unset ac_cv_func_getpseudotty
+echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6
+echo "configure:3345: checking for getpseudotty" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getpseudotty'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3350 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getpseudotty(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getpseudotty();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_getpseudotty) || defined (__stub___getpseudotty)
+choke me
+#else
+getpseudotty();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_getpseudotty=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_getpseudotty=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'getpseudotty`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ getpseudotty=1
+else
+ echo "$ac_t""no" 1>&6
+getpseudotty=0
+fi
+
+if test $getpseudotty -eq 0 ; then
+ unset ac_cv_lib_seq_getpseudotty
+ echo $ac_n "checking for getpseudotty in -lseq""... $ac_c" 1>&6
+echo "configure:3396: checking for getpseudotty in -lseq" >&5
+ac_lib_var=`echo seq'_'getpseudotty | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lseq $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3404 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getpseudotty();
+
+int main() {
+getpseudotty()
+; return 0; }
+EOF
+if { (eval echo configure:3415: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo seq | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lseq $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+# save Tk results and reset for Expect
+EXP_AND_TK_LIBS=$LIBS
+LIBS=$EXP_LIBS
+
+######################################################################
+# Check for FreeBSD/NetBSD openpty()
+# CYGNUS LOCAL: Don't do this on Linux. Alpha Linux Red Hat 4.2 has
+# openpty, but it doesn't work correctly.
+case "${host}" in
+*-*-linux*) ;;
+*)
+ unset ac_cv_func_openpty
+ echo $ac_n "checking for openpty""... $ac_c" 1>&6
+echo "configure:3456: checking for openpty" >&5
+if eval "test \"`echo '$''{'ac_cv_func_openpty'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3461 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char openpty(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char openpty();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_openpty) || defined (__stub___openpty)
+choke me
+#else
+openpty();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3484: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_openpty=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_openpty=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'openpty`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ openpty=1
+else
+ echo "$ac_t""no" 1>&6
+openpty=0
+fi
+
+ if test $openpty -eq 0 ; then
+ unset ac_cv_lib_util_openpty
+ echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6
+echo "configure:3507: checking for openpty in -lutil" >&5
+ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lutil $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3515 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char openpty();
+
+int main() {
+openpty()
+; return 0; }
+EOF
+if { (eval echo configure:3526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ # we only need to define OPENPTY once, but since we are overriding
+ # the default behavior, we must also handle augment LIBS too.
+ # This needn't be done in the 2nd and 3rd tests.
+ cat >> confdefs.h <<\EOF
+#define HAVE_OPENPTY 1
+EOF
+
+ LIBS="$LIBS -lutil"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ # save results and retry for Tcl
+ EXP_LIBS=$LIBS
+ LIBS=$EXP_AND_TCL_LIBS
+ unset ac_cv_func_openpty
+ echo $ac_n "checking for openpty""... $ac_c" 1>&6
+echo "configure:3561: checking for openpty" >&5
+if eval "test \"`echo '$''{'ac_cv_func_openpty'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3566 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char openpty(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char openpty();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_openpty) || defined (__stub___openpty)
+choke me
+#else
+openpty();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_openpty=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_openpty=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'openpty`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ openpty=1
+else
+ echo "$ac_t""no" 1>&6
+openpty=0
+fi
+
+ if test $openpty -eq 0 ; then
+ unset ac_cv_lib_util_openpty
+ echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6
+echo "configure:3612: checking for openpty in -lutil" >&5
+ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lutil $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3620 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char openpty();
+
+int main() {
+openpty()
+; return 0; }
+EOF
+if { (eval echo configure:3631: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_OPENPTY 1
+EOF
+
+ LIBS="$LIBS -lutil"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ # save Tcl results and retry for Tk
+ EXP_AND_TCL_LIBS=$LIBS
+ LIBS=$EXP_AND_TK_LIBS
+ unset ac_cv_func_openpty
+ echo $ac_n "checking for openpty""... $ac_c" 1>&6
+echo "configure:3663: checking for openpty" >&5
+if eval "test \"`echo '$''{'ac_cv_func_openpty'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3668 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char openpty(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char openpty();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_openpty) || defined (__stub___openpty)
+choke me
+#else
+openpty();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_openpty=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_openpty=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'openpty`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ openpty=1
+else
+ echo "$ac_t""no" 1>&6
+openpty=0
+fi
+
+ if test $openpty -eq 0 ; then
+ unset ac_cv_lib_util_openpty
+ echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6
+echo "configure:3714: checking for openpty in -lutil" >&5
+ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lutil $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3722 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char openpty();
+
+int main() {
+openpty()
+; return 0; }
+EOF
+if { (eval echo configure:3733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_OPENPTY 1
+EOF
+
+ LIBS="$LIBS -lutil"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ # save Tk results and reset for Expect
+ EXP_AND_TK_LIBS=$LIBS
+ LIBS=$EXP_LIBS
+
+ # CYGNUS LOCAL: Link against luser32 on Cygwin.
+ case "${host}" in
+ *-*-cygwin*) EXP_AND_TCL_LIBS="$EXP_AND_TCL_LIBS -luser32" ;;
+ esac
+;;
+esac
+
+######################################################################
+# End of library/func checking
+######################################################################
+
+######################################################################
+#
+# Look for various header files
+#
+ac_safe=`echo "sys/sysmacros.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/sysmacros.h""... $ac_c" 1>&6
+echo "configure:3781: checking for sys/sysmacros.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3786 "configure"
+#include "confdefs.h"
+#include <sys/sysmacros.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3791: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYSMACROS_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "stdlib.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6
+echo "configure:3817: checking for stdlib.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3822 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_STDLIB_H 1
+EOF
+
+fi
+
+
+#
+# Look for inttypes.h. Sometimes there are data type conflicts
+# with sys/types.h, so we have to use our own special test.
+#
+echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6
+echo "configure:3858: checking for inttypes.h" >&5
+if eval "test \"`echo '$''{'ac_cv_inttypes_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3863 "configure"
+#include "confdefs.h"
+
+ #include <sys/types.h>
+ #include <inttypes.h>
+int main() {
+
+ int16_t x = 0;
+
+; return 0; }
+EOF
+if { (eval echo configure:3874: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_inttypes_h="yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_inttypes_h="no"
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_inttypes_h" 1>&6
+if test x"${ac_cv_inttypes_h}" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_INTTYPES_H 1
+EOF
+
+fi
+
+
+# Oddly, some systems have stdarg but don't support prototypes
+# Tcl avoids the whole issue by not using stdarg on UNIX at all!
+
+ac_safe=`echo "varargs.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for varargs.h""... $ac_c" 1>&6
+echo "configure:3900: checking for varargs.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3905 "configure"
+#include "confdefs.h"
+#include <varargs.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_VARARGS_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "unistd.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for unistd.h""... $ac_c" 1>&6
+echo "configure:3936: checking for unistd.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3941 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3946: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_UNISTD_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/stropts.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/stropts.h""... $ac_c" 1>&6
+echo "configure:3972: checking for sys/stropts.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3977 "configure"
+#include "confdefs.h"
+#include <sys/stropts.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3982: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STROPTS_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/sysconfig.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/sysconfig.h""... $ac_c" 1>&6
+echo "configure:4008: checking for sys/sysconfig.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4013 "configure"
+#include "confdefs.h"
+#include <sys/sysconfig.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4018: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYSCONF_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/fcntl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/fcntl.h""... $ac_c" 1>&6
+echo "configure:4044: checking for sys/fcntl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4049 "configure"
+#include "confdefs.h"
+#include <sys/fcntl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4054: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_FCNTL_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/select.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/select.h""... $ac_c" 1>&6
+echo "configure:4080: checking for sys/select.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4085 "configure"
+#include "confdefs.h"
+#include <sys/select.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4090: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_SELECT_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/time.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/time.h""... $ac_c" 1>&6
+echo "configure:4116: checking for sys/time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4121 "configure"
+#include "confdefs.h"
+#include <sys/time.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4126: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_TIME_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/ptem.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/ptem.h""... $ac_c" 1>&6
+echo "configure:4152: checking for sys/ptem.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4157 "configure"
+#include "confdefs.h"
+#include <sys/ptem.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4162: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_PTEM_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/strredir.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/strredir.h""... $ac_c" 1>&6
+echo "configure:4188: checking for sys/strredir.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4193 "configure"
+#include "confdefs.h"
+#include <sys/strredir.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4198: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRREDIR_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/strpty.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/strpty.h""... $ac_c" 1>&6
+echo "configure:4224: checking for sys/strpty.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4229 "configure"
+#include "confdefs.h"
+#include <sys/strpty.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4234: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRPTY_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking for sys/bsdtypes.h""... $ac_c" 1>&6
+echo "configure:4261: checking for sys/bsdtypes.h" >&5
+if test "ISC_${ISC}" = "ISC_1" ; then
+ echo "$ac_t""yes" 1>&6
+ # if on ISC 1, we need <sys/bsdtypes.h> to get FD_SET macros
+ for ac_hdr in sys/bsdtypes.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4269: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4274 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4279: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+#
+# Look for functions that may be missing
+#
+echo $ac_n "checking for memmove""... $ac_c" 1>&6
+echo "configure:4313: checking for memmove" >&5
+if eval "test \"`echo '$''{'ac_cv_func_memmove'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4318 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char memmove(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char memmove();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_memmove) || defined (__stub___memmove)
+choke me
+#else
+memmove();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4341: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_memmove=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_memmove=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'memmove`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_MEMMOVE 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for sysconf""... $ac_c" 1>&6
+echo "configure:4364: checking for sysconf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_sysconf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4369 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char sysconf(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char sysconf();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_sysconf) || defined (__stub___sysconf)
+choke me
+#else
+sysconf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_sysconf=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_sysconf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'sysconf`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYSCONF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for strftime""... $ac_c" 1>&6
+echo "configure:4415: checking for strftime" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4420 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strftime(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strftime();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strftime) || defined (__stub___strftime)
+choke me
+#else
+strftime();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4443: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRFTIME 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for strchr""... $ac_c" 1>&6
+echo "configure:4466: checking for strchr" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strchr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4471 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strchr(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strchr();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strchr) || defined (__stub___strchr)
+choke me
+#else
+strchr();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strchr=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strchr=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strchr`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRCHR 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for timezone""... $ac_c" 1>&6
+echo "configure:4517: checking for timezone" >&5
+if eval "test \"`echo '$''{'ac_cv_func_timezone'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4522 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char timezone(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char timezone();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_timezone) || defined (__stub___timezone)
+choke me
+#else
+timezone();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4545: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_timezone=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_timezone=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'timezone`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_TIMEZONE 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+# dnl check for memcpy by hand
+# because Unixware 2.0 handles it specially and refuses to compile
+# autoconf's automatic test that is a call with no arguments
+echo $ac_n "checking for memcpy""... $ac_c" 1>&6
+echo "configure:4572: checking for memcpy" >&5
+cat > conftest.$ac_ext <<EOF
+#line 4574 "configure"
+#include "confdefs.h"
+
+int main() {
+
+char *s1, *s2;
+memcpy(s1,s2,0);
+
+; return 0; }
+EOF
+if { (eval echo configure:4584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_MEMCPY 1
+EOF
+
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -f conftest*
+
+# Some systems only define WNOHANG if _POSIX_SOURCE is defined
+# The following merely tests that sys/wait.h can be included
+# and if so that WNOHANG is not defined. The only place I've
+# seen this is ISC.
+echo $ac_n "checking if WNOHANG requires _POSIX_SOURCE""... $ac_c" 1>&6
+echo "configure:4606: checking if WNOHANG requires _POSIX_SOURCE" >&5
+if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) echo "$ac_t""no" 1>&6 ;;
+ *) { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4615 "configure"
+#include "confdefs.h"
+
+#include <sys/wait.h>
+main() {
+#ifndef WNOHANG
+ return 0;
+#else
+ return 1;
+#endif
+}
+EOF
+if { (eval echo configure:4627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WNOHANG_REQUIRES_POSIX_SOURCE 1
+EOF
+
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -fr conftest*
+fi
+
+
+echo $ac_n "checking if any value exists for WNOHANG""... $ac_c" 1>&6
+echo "configure:4647: checking if any value exists for WNOHANG" >&5
+rm -rf wnohang
+if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WNOHANG_BACKUP_VALUE 1
+EOF
+ ;;
+ *) { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4661 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <sys/wait.h>
+main() {
+#ifdef WNOHANG
+ FILE *fp = fopen("wnohang","w");
+ fprintf(fp,"%d",WNOHANG);
+ fclose(fp);
+ return 0;
+#else
+ return 1;
+#endif
+}
+EOF
+if { (eval echo configure:4677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define WNOHANG_BACKUP_VALUE `cat wnohang`
+EOF
+
+ rm -f wnohang
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WNOHANG_BACKUP_VALUE 1
+EOF
+
+
+fi
+rm -fr conftest*
+fi
+
+
+#
+# check how signals work
+#
+
+# Check for the data type of the mask used in select().
+# This picks up HP braindamage which defines fd_set and then
+# proceeds to ignore it and use int.
+# Pattern matching on int could be loosened.
+# Can't use ac_header_egrep since that doesn't see prototypes with K&R cpp.
+echo $ac_n "checking mask type of select""... $ac_c" 1>&6
+echo "configure:4711: checking mask type of select" >&5
+if egrep "select\(size_t, int" /usr/include/sys/time.h >/dev/null 2>&1; then
+ echo "$ac_t""int" 1>&6
+ cat >> confdefs.h <<\EOF
+#define SELECT_MASK_TYPE int
+EOF
+
+else
+ echo "$ac_t""none" 1>&6
+fi
+
+
+# FIXME: check if alarm exists
+echo $ac_n "checking if signals need to be re-armed""... $ac_c" 1>&6
+echo "configure:4725: checking if signals need to be re-armed" >&5
+if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) echo "$ac_t""no" 1>&6 ;;
+ *) echo "configure: warning: Expect can't be cross compiled" 1>&2 ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4734 "configure"
+#include "confdefs.h"
+
+#include <signal.h>
+#define RETSIGTYPE $retsigtype
+
+int signal_rearms = 0;
+
+RETSIGTYPE
+child_sigint_handler(n)
+int n;
+{
+}
+
+RETSIGTYPE
+parent_sigint_handler(n)
+int n;
+{
+signal_rearms++;
+}
+
+main()
+{
+ signal(SIGINT,parent_sigint_handler);
+
+ if (0 == fork()) {
+ signal(SIGINT,child_sigint_handler);
+ kill(getpid(),SIGINT);
+ kill(getpid(),SIGINT);
+ kill(getppid(),SIGINT);
+ } else {
+ int status;
+
+ wait(&status);
+ unlink("core");
+ exit(signal_rearms);
+ }
+}
+EOF
+if { (eval echo configure:4773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define REARM_SIG 1
+EOF
+
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -fr conftest*
+fi
+
+
+# HPUX7 has trouble with the big cat so split it
+# Owen Rees <rtor@ansa.co.uk> 29Mar93
+SEDDEFS="${SEDDEFS}CONFEOF
+cat >> conftest.sed <<CONFEOF
+"
+#
+
+# There are multiple versions of getpty, alas.
+# I don't remember who has the first one, but Convex just added one
+# so check for it. Unfortunately, there is no header so the only
+# reasonable way to make sure is to look it we are on a Convex.
+echo $ac_n "checking if on Convex""... $ac_c" 1>&6
+echo "configure:4804: checking if on Convex" >&5
+convex=0
+case "${host}" in
+ c[12]-*-*) convex=1;;
+esac
+
+if test $convex -eq 1 ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define CONVEX 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+EXP_LDFLAGS=
+
+echo $ac_n "checking if on NeXT""... $ac_c" 1>&6
+echo "configure:4823: checking if on NeXT" >&5
+if test -r /NextApps -a "$cross_compiling" != "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ # "-m" flag suppresses complaints about multiple strtod
+ EXP_LDFLAGS="$EXP_LDFLAGS -m"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking if on HP""... $ac_c" 1>&6
+echo "configure:4834: checking if on HP" >&5
+if test "x`(uname) 2>/dev/null`" = xHP-UX; then
+ echo "$ac_t""yes" 1>&6
+ hp=1
+else
+ echo "$ac_t""no" 1>&6
+ hp=0
+fi
+
+echo $ac_n "checking sane default stty arguments""... $ac_c" 1>&6
+echo "configure:4844: checking sane default stty arguments" >&5
+DEFAULT_STTY_ARGS="sane"
+
+if test $mach -eq 1 ; then
+ DEFAULT_STTY_ARGS="cooked"
+fi
+
+if test $hp -eq 1 ; then
+ DEFAULT_STTY_ARGS="sane kill "
+fi
+
+echo "$ac_t""$DEFAULT_STTY_ARG" 1>&6
+
+# Look for various features to determine what kind of pty
+# we have. For some weird reason, ac_compile_check would not
+# work, but ac_test_program does.
+#
+echo $ac_n "checking for HP style pty allocation""... $ac_c" 1>&6
+echo "configure:4862: checking for HP style pty allocation" >&5
+# following test fails on DECstations and other things that don't grok -c
+# but that's ok, since they don't have PTYMs anyway
+if test -r /dev/ptym/ptyp0 2>/dev/null -a "$cross_compiling" != "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_PTYM 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for HP style pty trapping""... $ac_c" 1>&6
+echo "configure:4876: checking for HP style pty trapping" >&5
+cat > conftest.$ac_ext <<EOF
+#line 4878 "configure"
+#include "confdefs.h"
+#include <sys/ptyio.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "struct.*request_info" >/dev/null 2>&1; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_PTYTRAP 1
+EOF
+
+
+else
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -f conftest*
+
+
+echo $ac_n "checking for AIX new-style pty allocation""... $ac_c" 1>&6
+echo "configure:4900: checking for AIX new-style pty allocation" >&5
+if test -r /dev/ptc -a -r /dev/pts -a "$cross_compiling" != "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_PTC_PTS 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for SGI old-style pty allocation""... $ac_c" 1>&6
+echo "configure:4912: checking for SGI old-style pty allocation" >&5
+if test -r /dev/ptc -a ! -r /dev/pts -a "$cross_compiling" != "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_PTC 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# On SCO OpenServer, two types of ptys are available: SVR4 streams and c-list.
+# The library routines to open the SVR4 ptys are broken on certain systems and
+# the SCO command to increase the number of ptys only configure c-list ones
+# anyway. So we chose these, which have a special numbering scheme.
+#
+echo $ac_n "checking for SCO style pty allocation""... $ac_c" 1>&6
+echo "configure:4929: checking for SCO style pty allocation" >&5
+sco_ptys=""
+case "${host}" in
+ *-sco3.2v[45]*) sco_clist_ptys=1 svr4_ptys_broken=1;;
+esac
+
+if test x"${sco_clist_ptys}" != x"" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SCO_CLIST_PTYS 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for SVR4 style pty allocation""... $ac_c" 1>&6
+echo "configure:4946: checking for SVR4 style pty allocation" >&5
+if test -r /dev/ptmx -a "x$svr4_ptys_broken" = x -a "$cross_compiling" != "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_PTMX 1
+EOF
+
+ # aargg. Some systems need libpt.a to use /dev/ptmx
+ echo $ac_n "checking for ptsname""... $ac_c" 1>&6
+echo "configure:4955: checking for ptsname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_ptsname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4960 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char ptsname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char ptsname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_ptsname) || defined (__stub___ptsname)
+choke me
+#else
+ptsname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_ptsname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_ptsname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'ptsname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+LIBS="${LIBS} -lpt"
+fi
+
+ # I've never seen Tcl or Tk include -lpt so don't bother with explicit test
+ echo $ac_n "checking for ptsname""... $ac_c" 1>&6
+echo "configure:5005: checking for ptsname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_ptsname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5010 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char ptsname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char ptsname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_ptsname) || defined (__stub___ptsname)
+choke me
+#else
+ptsname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_ptsname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_ptsname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'ptsname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+EXP_AND_TCL_LIBS="${EXP_AND_TCL_LIBS} -lpt"
+fi
+
+ echo $ac_n "checking for ptsname""... $ac_c" 1>&6
+echo "configure:5054: checking for ptsname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_ptsname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5059 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char ptsname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char ptsname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_ptsname) || defined (__stub___ptsname)
+choke me
+#else
+ptsname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_ptsname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_ptsname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'ptsname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+EXP_AND_TK_LIBS="${EXP_AND_TK_LIBS} -lpt"
+fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# In OSF/1 case, SVR4 are somewhat different.
+# Gregory Depp <depp@osf.org> 17Aug93
+echo $ac_n "checking for OSF/1 style pty allocation""... $ac_c" 1>&6
+echo "configure:5109: checking for OSF/1 style pty allocation" >&5
+if test -r /dev/ptmx_bsd -a "$cross_compiling" != "yes" ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PTMX_BSD 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Set the pty handling for Cygwin
+case "${host}" in
+ *-*-cygwin*) cat >> confdefs.h <<\EOF
+#define HAVE_PTMX 1
+EOF
+ ;;
+ *) ;;
+esac
+
+tcgetattr=0
+tcsetattr=0
+echo $ac_n "checking for tcgetattr""... $ac_c" 1>&6
+echo "configure:5132: checking for tcgetattr" >&5
+if eval "test \"`echo '$''{'ac_cv_func_tcgetattr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5137 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char tcgetattr(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tcgetattr();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_tcgetattr) || defined (__stub___tcgetattr)
+choke me
+#else
+tcgetattr();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_tcgetattr=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_tcgetattr=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'tcgetattr`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcgetattr=1
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for tcsetattr""... $ac_c" 1>&6
+echo "configure:5180: checking for tcsetattr" >&5
+if eval "test \"`echo '$''{'ac_cv_func_tcsetattr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5185 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char tcsetattr(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tcsetattr();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_tcsetattr) || defined (__stub___tcsetattr)
+choke me
+#else
+tcsetattr();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_tcsetattr=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_tcsetattr=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'tcsetattr`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcsetattr=1
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test $tcgetattr -eq 1 -a $tcsetattr -eq 1 ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TCSETATTR 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define POSIX 1
+EOF
+
+fi
+
+# first check for the pure bsd
+echo $ac_n "checking for struct sgttyb""... $ac_c" 1>&6
+echo "configure:5240: checking for struct sgttyb" >&5
+if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) echo "$ac_t""no" 1>&6 ;;
+ *) { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5249 "configure"
+#include "confdefs.h"
+
+#include <sgtty.h>
+main()
+{
+ struct sgttyb tmp;
+ exit(0);
+}
+EOF
+if { (eval echo configure:5259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SGTTYB 1
+EOF
+
+ PTY_TYPE=sgttyb
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -fr conftest*
+fi
+
+
+# mach systems have include files for unimplemented features
+# so avoid doing following test on those systems
+if test $mach -eq 0 ; then
+
+ # next check for the older style ttys
+ # note that if we detect termio.h (only), we still set PTY_TYPE=termios
+ # since that just controls which of pty_XXXX.c file is use and
+ # pty_termios.c is set up to handle pty_termio.
+ echo $ac_n "checking for struct termio""... $ac_c" 1>&6
+echo "configure:5288: checking for struct termio" >&5
+ if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) echo "$ac_t""no" 1>&6 ;;
+ *) { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5297 "configure"
+#include "confdefs.h"
+#include <termio.h>
+ main()
+ {
+ struct termio tmp;
+ exit(0);
+ }
+EOF
+if { (eval echo configure:5306: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TERMIO 1
+EOF
+
+ PTY_TYPE=termios
+ echo "$ac_t""yes" 1>&6
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -fr conftest*
+fi
+
+
+ # now check for the new style ttys (not yet posix)
+ echo $ac_n "checking for struct termios""... $ac_c" 1>&6
+echo "configure:5328: checking for struct termios" >&5
+ if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) cat >> confdefs.h <<\EOF
+#define HAVE_TERMIOS 1
+EOF
+
+ PTY_TYPE=termios
+ echo "$ac_t""yes" 1>&6 ;;
+ *) { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5342 "configure"
+#include "confdefs.h"
+
+# ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+# endif
+# include <termios.h>
+ main()
+ {
+ struct termios tmp;
+ exit(0);
+ }
+EOF
+if { (eval echo configure:5355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TERMIOS 1
+EOF
+
+ PTY_TYPE=termios
+ echo "$ac_t""yes" 1>&6
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo $ac_n "checking if TCGETS or TCGETA in termios.h""... $ac_c" 1>&6
+echo "configure:5377: checking if TCGETS or TCGETA in termios.h" >&5
+if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) cat >> confdefs.h <<\EOF
+#define HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H 1
+EOF
+
+ echo "$ac_t""yes" 1>&6 ;;
+ *) { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5390 "configure"
+#include "confdefs.h"
+
+/* including termios.h on Solaris 5.6 fails unless inttypes.h included */
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <termios.h>
+main() {
+#if defined(TCGETS) || defined(TCGETA)
+ return 0;
+#else
+ return 1;
+#endif
+}
+EOF
+if { (eval echo configure:5406: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -fr conftest*
+fi
+
+
+echo $ac_n "checking if TIOCGWINSZ in termios.h""... $ac_c" 1>&6
+echo "configure:5426: checking if TIOCGWINSZ in termios.h" >&5
+if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) cat >> confdefs.h <<\EOF
+#define HAVE_TIOCGWINSZ_IN_TERMIOS_H 1
+EOF
+
+ echo "$ac_t""yes" 1>&6 ;;
+ *) { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5439 "configure"
+#include "confdefs.h"
+
+/* including termios.h on Solaris 5.6 fails unless inttypes.h included */
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <termios.h>
+main() {
+#ifdef TIOCGWINSZ
+ return 0;
+#else
+ return 1;
+#endif
+}
+EOF
+if { (eval echo configure:5455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TIOCGWINSZ_IN_TERMIOS_H 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -fr conftest*
+fi
+
+
+# finally check for Cray style ttys
+echo $ac_n "checking for Cray-style ptys""... $ac_c" 1>&6
+echo "configure:5476: checking for Cray-style ptys" >&5
+SETUID=":"
+if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) echo "$ac_t""no" 1>&6 ;;
+ *) { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5486 "configure"
+#include "confdefs.h"
+
+main(){
+#ifdef CRAY
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+EOF
+if { (eval echo configure:5498: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ PTY_TYPE=unicos
+ SETUID="chmod u+s"
+ echo "$ac_t""yes" 1>&6
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -fr conftest*
+fi
+
+
+#
+# Check for select and/or poll. If both exist, we prefer select.
+# if neither exists, define SIMPLE_EVENT.
+#
+select=0
+poll=0
+unset ac_cv_func_select
+echo $ac_n "checking for select""... $ac_c" 1>&6
+echo "configure:5523: checking for select" >&5
+if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5528 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char select(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char select();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_select) || defined (__stub___select)
+choke me
+#else
+select();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_select=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_select=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ select=1
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for poll""... $ac_c" 1>&6
+echo "configure:5571: checking for poll" >&5
+if eval "test \"`echo '$''{'ac_cv_func_poll'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5576 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char poll(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char poll();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_poll) || defined (__stub___poll)
+choke me
+#else
+poll();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5599: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_poll=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_poll=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'poll`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ poll=1
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking event handling""... $ac_c" 1>&6
+echo "configure:5619: checking event handling" >&5
+if test $select -eq 1 ; then
+ EVENT_TYPE=select
+ EVENT_ABLE=event
+ echo "$ac_t""via select" 1>&6
+elif test $poll -eq 1 ; then
+ EVENT_TYPE=poll
+ EVENT_ABLE=event
+ echo "$ac_t""via poll" 1>&6
+else
+ EVENT_TYPE=simple
+ EVENT_ABLE=noevent
+ echo "$ac_t""none" 1>&6
+ cat >> confdefs.h <<\EOF
+#define SIMPLE_EVENT 1
+EOF
+
+fi
+
+for ac_func in _getpty
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:5641: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5646 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5669: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpty
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:5696: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5701 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+#
+# check for timezones
+#
+echo $ac_n "checking for SV-style timezone""... $ac_c" 1>&6
+echo "configure:5753: checking for SV-style timezone" >&5
+if test "$cross_compiling" = yes; then
+ case "${host}" in
+ *-*-cygwin*) echo "$ac_t""no" 1>&6 ;;
+ *) { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } ;;
+ esac
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5762 "configure"
+#include "confdefs.h"
+
+extern char *tzname[2];
+extern int daylight;
+main()
+{
+ int *x = &daylight;
+ char **y = tzname;
+
+ exit(0);
+}
+EOF
+if { (eval echo configure:5775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SV_TIMEZONE 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -fr conftest*
+fi
+
+
+# only look for Tk stuff if we have X11 and user doesn't say not to
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+ withval="$with_x"
+ :
+else
+ with_x=yes
+fi
+
+if test "$with_x" = "no"; then
+ no_tk=true
+else
+
+#
+# Ok, lets find the tk source trees so we can use the headers
+# If the directory (presumably symlink) named "tk" exists, use that one
+# in preference to any others. Same logic is used when choosing library
+# and again with Tcl. The search order is the best place to look first, then in
+# decreasing significance. The loop breaks if the trigger file is found.
+# Note the gross little conversion here of srcdir by cd'ing to the found
+# directory. This converts the path from a relative to an absolute, so
+# recursive cache variables for the path will work right. We check all
+# the possible paths in one loop rather than many seperate loops to speed
+# things up.
+# the alternative search directory is involked by --with-tkinclude
+#
+#no_tk=true
+echo $ac_n "checking for Tk private headers""... $ac_c" 1>&6
+echo "configure:5821: checking for Tk private headers" >&5
+# Check whether --with-tkinclude or --without-tkinclude was given.
+if test "${with_tkinclude+set}" = set; then
+ withval="$with_tkinclude"
+ with_tkinclude=${withval}
+fi
+
+if eval "test \"`echo '$''{'ac_cv_c_tkh'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+# first check to see if --with-tkinclude was specified
+if test x"${with_tkinclude}" != x ; then
+ if test -f ${with_tkinclude}/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
+ elif test -f ${with_tkinclude}/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)`
+ else
+ { echo "configure: error: ${with_tkinclude} directory doesn't contain private headers" 1>&2; exit 1; }
+ fi
+fi
+
+# next check if it came with Tk configuration file
+if test x"${ac_cv_c_tkconfig}" != x ; then
+ if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/../generic; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[4-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../tk \
+ `ls -dr ${srcdir}/../../tk[4-9].[0-9] 2>/dev/null` \
+ ${srcdir}/../../../tk \
+ `ls -dr ${srcdir}/../../../tk[4-9].[0-9] 2>/dev/null ` ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+
+if test x"${ac_cv_c_tkh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tk[4-9].[0-9] 2>/dev/null` \
+ `ls -dr /usr/local/lib/tk[4-9].[0-9] 2>/dev/null` \
+ /usr/local/src/tk \
+ /usr/local/lib/tk \
+ ${prefix}/include ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+# see if one is installed
+if test x"${ac_cv_c_tkh}" = x ; then
+ ac_safe=`echo "tk.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for tk.h""... $ac_c" 1>&6
+echo "configure:5891: checking for tk.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5896 "configure"
+#include "confdefs.h"
+#include <tk.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5901: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_cv_c_tkh=installed
+else
+ echo "$ac_t""no" 1>&6
+ac_cv_c_tkh=""
+fi
+
+fi
+
+fi
+
+if test x"${ac_cv_c_tkh}" != x ; then
+# no_tk=""
+ if test x"${ac_cv_c_tkh}" = x"installed" ; then
+ echo "$ac_t""is installed" 1>&6
+ TKHDIRDASHI=""
+ else
+ echo "$ac_t""found in ${ac_cv_c_tkh}" 1>&6
+ # this hack is cause the TKHDIRDASHI won't print if there is a "-I" in it.
+ TKHDIRDASHI="-I${ac_cv_c_tkh}"
+ fi
+else
+ TKHDIRDASHI="# no Tk directory found"
+ echo "configure: warning: Can't find Tk private headers" 1>&2
+ no_tk=true
+fi
+
+
+
+fi
+if test x"$no_tk" != x"true" ; then
+# libexpectk no longer exists
+# X_PROGS="expectk \$(LIBEXPECTK)"
+ X_PROGS=expectk
+# should really generate following symbol, but I'm hitting configure's limit on substs.
+ X_PROGS_INSTALLED=expectk_installed
+else
+ X_PROGS="# no X support on this system"
+ echo "configure: warning: No X based programs will be built" 1>&2
+ echo " WARNING: Can't find Tk headers or library. You can still"
+ echo " build expect, but not expectk. See Expect's README for"
+ echo " information on how to obtain Tk. If Tk is installed, see"
+ echo " Expect's INSTALL on how to tell configure where Tk is"
+ echo " installed."
+fi
+
+# consume these flags so that user can invoke Expect's configure with
+# the same command as Tcl's configure
+# Check whether --enable-load or --disable-load was given.
+if test "${enable_load+set}" = set; then
+ enableval="$enable_load"
+ disable_dl=$enableval
+else
+ disable_dl=no
+fi
+
+
+# Check whether --enable-gcc or --disable-gcc was given.
+if test "${enable_gcc+set}" = set; then
+ enableval="$enable_gcc"
+ enable_gcc=$enableval
+else
+ enable_gcc=no
+fi
+
+
+
+# Following comment stolen from Tcl's configure.in:
+# Note: in the following variable, it's important to use the absolute
+# path name of the Tcl directory rather than "..": this is because
+# AIX remembers this path and will attempt to use it at run-time to look
+# up the Tcl library.
+
+if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+ EXP_LIB_VERSION=$EXP_VERSION
+else
+ EXP_LIB_VERSION=$EXP_VERSION_NODOTS
+fi
+if test $iunix -eq 1 ; then
+ EXP_LIB_VERSION=$EXP_VERSION_NODOTS
+fi
+
+# also remove dots on systems that don't support filenames > 14
+# (are there systems which support shared libs and restrict filename lengths!?)
+echo $ac_n "checking for long file names""... $ac_c" 1>&6
+echo "configure:6001: checking for long file names" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_long_file_names'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_long_file_names=yes
+# Test for long file names in all the places we know might matter:
+# . the current directory, where building will happen
+# $prefix/lib where we will be installing things
+# $exec_prefix/lib likewise
+# eval it to expand exec_prefix.
+# $TMPDIR if set, where it might want to write temporary files
+# if $TMPDIR is not set:
+# /tmp where it might want to write temporary files
+# /var/tmp likewise
+# /usr/tmp likewise
+if test -n "$TMPDIR" && test -d "$TMPDIR" && test -w "$TMPDIR"; then
+ ac_tmpdirs="$TMPDIR"
+else
+ ac_tmpdirs='/tmp /var/tmp /usr/tmp'
+fi
+for ac_dir in . $ac_tmpdirs `eval echo $prefix/lib $exec_prefix/lib` ; do
+ test -d $ac_dir || continue
+ test -w $ac_dir || continue # It is less confusing to not echo anything here.
+ (echo 1 > $ac_dir/conftest9012345) 2>/dev/null
+ (echo 2 > $ac_dir/conftest9012346) 2>/dev/null
+ val=`cat $ac_dir/conftest9012345 2>/dev/null`
+ if test ! -f $ac_dir/conftest9012345 || test "$val" != 1; then
+ ac_cv_sys_long_file_names=no
+ rm -f $ac_dir/conftest9012345 $ac_dir/conftest9012346 2>/dev/null
+ break
+ fi
+ rm -f $ac_dir/conftest9012345 $ac_dir/conftest9012346 2>/dev/null
+done
+fi
+
+echo "$ac_t""$ac_cv_sys_long_file_names" 1>&6
+if test $ac_cv_sys_long_file_names = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LONG_FILE_NAMES 1
+EOF
+
+fi
+
+if test $ac_cv_sys_long_file_names = no; then
+ EXP_LIB_VERSION=$EXP_VERSION_NODOTS
+fi
+
+EXP_BUILD_LIB_SPEC="-L`pwd` -lexpect${EXP_LIB_VERSION}"
+EXP_LIB_SPEC="-L\${exec_prefix}/lib -lexpect${EXP_LIB_VERSION}"
+EXP_UNSHARED_LIB_FILE=libexpect${EXP_LIB_VERSION}.a
+EXP_BUILD_LIB_SPEC=${EXP_UNSHARED_LIB_FILE}
+
+echo $ac_n "checking for type of library to build""... $ac_c" 1>&6
+echo "configure:6054: checking for type of library to build" >&5
+if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then
+ EXP_SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS
+# EXP_SHARED_LIB_FILE=libexpect$EXP_LIB_VERSION$TCL_SHLIB_SUFFIX
+ eval "EXP_SHARED_LIB_FILE=libexpect${TCL_SHARED_LIB_SUFFIX}"
+ EXP_LIB_FILE=$EXP_SHARED_LIB_FILE
+ EXP_LIB_FILES="$EXP_SHARED_LIB_FILE $EXP_UNSHARED_LIB_FILE"
+ echo "$ac_t""both shared and unshared" 1>&6
+else
+ EXP_SHLIB_CFLAGS=
+ EXP_SHARED_LIB_FILE="reconfigure_Tcl_for_shared_library"
+ EXP_LIB_FILE=$EXP_UNSHARED_LIB_FILE
+ EXP_LIB_FILES="$EXP_UNSHARED_LIB_FILE"
+ echo "$ac_t""unshared" 1>&6
+fi
+
+# CYGNUS LOCAL
+# We always link expect statically (against $EXP_UNSHARED_LIB_FILE)
+# so we can run it out of the build directory without hurting
+# ourselves and others.
+
+# now broken out into EXP_AND_TCL_LIBS and EXP_AND_TK_LIBS. Had to do this
+# in order to avoid repeating lib specs to which some systems object.
+EXP_AND_TCL_LIBS="$EXP_AND_TCL_LIBS $TCL_LD_SEARCH_FLAGS"
+EXP_AND_TK_LIBS="$EXP_AND_TK_LIBS $TCL_LD_SEARCH_FLAGS"
+
+# Sigh - Tcl defines SHLIB_LD_LIBS to be either empty or ${LIBS} and
+# LIBS is intended to be expanded by Make. But since we're too close
+# to hitting config's max symbols, pack everything together here and
+# do test ourselves. Ugh.
+#
+if test "x$TCL_SHLIB_LD_LIBS" = "x" ; then
+ EXP_SHLIB_LD_LIBS=""
+else
+ # seems a little strange to build in Tcl's build-lib, but
+ # that's what Tk does.
+ EXP_SHLIB_LD_LIBS="$TCL_BUILD_LIB_SPEC $TCL_DL_LIBS $LIBS -lc"
+fi
+
+echo $ac_n "checking for Cygwin32 environment""... $ac_c" 1>&6
+echo "configure:6094: checking for Cygwin32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6099 "configure"
+#include "confdefs.h"
+
+int main() {
+int main () { return __CYGWIN32__; }
+; return 0; }
+EOF
+if { (eval echo configure:6106: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin32" 1>&6
+CYGWIN32=
+test "$ac_cv_cygwin32" = yes && CYGWIN32=yes
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:6123: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN32" = yes; then
+ac_cv_exeext=.exe
+else
+cat > ac_c_test.c << 'EOF'
+int main() {
+/* Nothing needed here */
+}
+EOF
+${CC-cc} -o ac_c_test $CFLAGS $CPPFLAGS $LDFLAGS ac_c_test.c $LIBS 1>&5
+ac_cv_exeext=`ls ac_c_test.* | grep -v ac_c_test.c | sed -e s/ac_c_test//`
+rm -f ac_c_test*
+fi
+
+test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+
+
+#--------------------------------------------------------------------
+# This section is based on analogous thing in Tk installation. - DEL
+# Various manipulations on the search path used at runtime to
+# find shared libraries:
+# 2. On systems such as AIX and Ultrix that use "-L" as the
+# search path option, colons cannot be used to separate
+# directories from each other. Change colons to " -L".
+# 3. Create two sets of search flags, one for use in cc lines
+# and the other for when the linker is invoked directly. In
+# the second case, '-Wl,' must be stripped off and commas must
+# be replaced by spaces.
+#--------------------------------------------------------------------
+
+LIB_RUNTIME_DIR='${LIB_RUNTIME_DIR}'
+
+# If Tcl and Expect are installed in different places, adjust the library
+# search path to reflect this.
+
+if test "$TCL_EXEC_PREFIX" != "$exec_prefix"; then
+ LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}"
+fi
+
+if test "${TCL_LD_SEARCH_FLAGS}" = '-L${LIB_RUNTIME_DIR}'; then
+ LIB_RUNTIME_DIR=`echo ${LIB_RUNTIME_DIR} |sed -e 's/:/ -L/g'`
+fi
+
+# The statement below is very tricky! It actually *evaluates* the
+# string in TCL_LD_SEARCH_FLAGS, which causes a substitution of the
+# variable LIB_RUNTIME_DIR.
+
+eval "EXP_CC_SEARCH_FLAGS=\"$TCL_LD_SEARCH_FLAGS\""
+if test "$GCC" = yes; then
+ true
+else
+ EXP_LD_SEARCH_FLAGS=`echo ${EXP_CC_SEARCH_FLAGS} |sed -e "s|-Wl,||g" -e "s|,| |g"`
+fi
+
+#
+# Set up makefile substitutions
+#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+trap '' 1 2 15
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile pkgIndex expect_cf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@TCL_DEFS@%$TCL_DEFS%g
+s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g
+s%@SHLIB_SUFFIX@%$SHLIB_SUFFIX%g
+s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g
+s%@TCL_RANLIB@%$TCL_RANLIB%g
+s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g
+s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g
+s%@TCL_SHARED_LIB_SUFFIX@%$TCL_SHARED_LIB_SUFFIX%g
+s%@TK_VERSION@%$TK_VERSION%g
+s%@TK_DEFS@%$TK_DEFS%g
+s%@TK_XINCLUDES@%$TK_XINCLUDES%g
+s%@TK_XLIBSW@%$TK_XLIBSW%g
+s%@TK_BUILD_LIB_SPEC@%$TK_BUILD_LIB_SPEC%g
+s%@TK_LIB_SPEC@%$TK_LIB_SPEC%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@RANLIB@%$RANLIB%g
+s%@subdirs@%$subdirs%g
+s%@CPP@%$CPP%g
+s%@TCLHDIR@%$TCLHDIR%g
+s%@TCLHDIRDASHI@%$TCLHDIRDASHI%g
+s%@TCL_LIBRARY@%$TCL_LIBRARY%g
+s%@ITCLHDIR@%$ITCLHDIR%g
+s%@ITCLLIB@%$ITCLLIB%g
+s%@TKHDIRDASHI@%$TKHDIRDASHI%g
+s%@EXEEXT@%$EXEEXT%g
+s%@EXP_MAJOR_VERSION@%$EXP_MAJOR_VERSION%g
+s%@EXP_MINOR_VERSION@%$EXP_MINOR_VERSION%g
+s%@EXP_MICRO_VERSION@%$EXP_MICRO_VERSION%g
+s%@EXP_VERSION_FULL@%$EXP_VERSION_FULL%g
+s%@EXP_VERSION@%$EXP_VERSION%g
+s%@EXP_CONFIG_SHELL@%$EXP_CONFIG_SHELL%g
+s%@EXP_SHARED_LIB_FILE@%$EXP_SHARED_LIB_FILE%g
+s%@EXP_UNSHARED_LIB_FILE@%$EXP_UNSHARED_LIB_FILE%g
+s%@EXP_SHLIB_CFLAGS@%$EXP_SHLIB_CFLAGS%g
+s%@EXP_LIB_FILE@%$EXP_LIB_FILE%g
+s%@EXP_LIB_FILES@%$EXP_LIB_FILES%g
+s%@EXP_BUILD_LIB_SPEC@%$EXP_BUILD_LIB_SPEC%g
+s%@EXP_LIB_SPEC@%$EXP_LIB_SPEC%g
+s%@EXP_CFLAGS@%$EXP_CFLAGS%g
+s%@EXP_LDFLAGS@%$EXP_LDFLAGS%g
+s%@EXP_LD_SEARCH_FLAGS@%$EXP_LD_SEARCH_FLAGS%g
+s%@EXP_AND_TCL_LIBS@%$EXP_AND_TCL_LIBS%g
+s%@EXP_AND_TK_LIBS@%$EXP_AND_TK_LIBS%g
+s%@EXP_SHLIB_LD_LIBS@%$EXP_SHLIB_LD_LIBS%g
+s%@X_PROGS@%$X_PROGS%g
+s%@PTY_TYPE@%$PTY_TYPE%g
+s%@EVENT_TYPE@%$EVENT_TYPE%g
+s%@EVENT_ABLE@%$EVENT_ABLE%g
+s%@SETUID@%$SETUID%g
+s%@UNSHARED_RANLIB@%$UNSHARED_RANLIB%g
+s%@DEFAULT_STTY_ARGS@%$DEFAULT_STTY_ARGS%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile pkgIndex"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="expect_cf.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+if test "$no_recursion" != yes; then
+
+ # Remove --cache-file and --srcdir arguments so they do not pile up.
+ ac_sub_configure_args=
+ ac_prev=
+ for ac_arg in $ac_configure_args; do
+ if test -n "$ac_prev"; then
+ ac_prev=
+ continue
+ fi
+ case "$ac_arg" in
+ -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=*)
+ ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ ;;
+ *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+ esac
+ done
+
+ for ac_config_dir in testsuite; do
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+ if test ! -d $srcdir/$ac_config_dir; then
+ continue
+ fi
+
+ echo configuring in $ac_config_dir
+
+ case "$srcdir" in
+ .) ;;
+ *)
+ if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :;
+ else
+ { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; }
+ fi
+ ;;
+ esac
+
+ ac_popdir=`pwd`
+ cd $ac_config_dir
+
+ # A "../" for each directory in /$ac_config_dir.
+ ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
+
+ case "$srcdir" in
+ .) # No --srcdir option. We are building in place.
+ ac_sub_srcdir=$srcdir ;;
+ /*) # Absolute path.
+ ac_sub_srcdir=$srcdir/$ac_config_dir ;;
+ *) # Relative path.
+ ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;;
+ esac
+
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_sub_srcdir/configure; then
+ ac_sub_configure=$ac_sub_srcdir/configure
+ elif test -f $ac_sub_srcdir/configure.in; then
+ ac_sub_configure=$ac_configure
+ else
+ echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2
+ ac_sub_configure=
+ fi
+
+ # The recursion is here.
+ if test -n "$ac_sub_configure"; then
+
+ # Make the cache file name correct relative to the subdirectory.
+ case "$cache_file" in
+ /*) ac_sub_cache_file=$cache_file ;;
+ *) # Relative path.
+ ac_sub_cache_file="$ac_dots$cache_file" ;;
+ esac
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
+ # The eval makes quoting arguments work.
+ if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
+ then :
+ else
+ { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
+ fi
+ fi
+
+ cd $ac_popdir
+ done
+fi
+
diff --git a/expect/configure.in b/expect/configure.in
new file mode 100644
index 00000000000..abe8f776f6a
--- /dev/null
+++ b/expect/configure.in
@@ -0,0 +1,1256 @@
+# Process this file with autoconf to produce a configure script.
+
+# while Expect is in alpha/beta, disable caching so as not to confuse
+# people trying to fix configure bugs
+dnl CYGNUS LOCAL: allow caching
+define([AC_CACHE_LOAD], )
+define([AC_CACHE_SAVE], )
+dnl END CYGNUS LOCAL
+
+AC_INIT(expect.h)
+
+dnl CYGNUS LOCAL: find aux files in ..
+AC_CONFIG_AUX_DIR($srcdir/..)
+dnl END CYGNUS LOCAL
+dnl AC_CANONICAL_SYSTEM
+
+# note when updating version numbers here, also update pkgIndex.in (see
+# comments in Makefile)
+EXP_MAJOR_VERSION=5
+EXP_MINOR_VERSION=26
+EXP_MICRO_VERSION=0
+EXP_VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION
+EXP_VERSION_NODOTS=$EXP_MAJOR_VERSION$EXP_MINOR_VERSION
+EXP_VERSION_FULL=$EXP_VERSION.$EXP_MICRO_VERSION
+
+# Tcl's handling of shared_lib_suffix requires this symbol exist
+VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION
+
+# Too many people send me configure output without identifying the version.
+# This forced identification should reduce my pain significantly.
+echo "configuring Expect $EXP_MAJOR_VERSION.$EXP_MINOR_VERSION.$EXP_MICRO_VERSION"
+
+dnl AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..)
+AC_CANONICAL_SYSTEM
+
+AC_CONFIG_HEADER(expect_cf.h)
+
+# /bin/sh on some systems is too deficient (in particular, Ultrix 4.3
+# sh lacks unset and we *need* that), but all these systems come with
+# alternatives, so take user's choice or whatever we're using here and
+# allow it to be seen by Make.
+AC_MSG_CHECKING([shell to use within Make])
+EXP_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+AC_MSG_RESULT($CONFIG_SHELL)
+
+# If `configure' is invoked (in)directly via `make', ensure that it
+# encounters no `make' conflicts.
+#
+unset MFLAGS MAKEFLAGS
+MFLAGS=""
+MAKEFLAGS=""
+
+CY_AC_PATH_TCLCONFIG
+CY_AC_LOAD_TCLCONFIG
+CC=$TCL_CC
+EXP_AND_TCL_LIBS=$TCL_LIBS
+CY_AC_PATH_TKCONFIG
+CY_AC_LOAD_TKCONFIG
+EXP_AND_TK_LIBS=$TK_LIBS
+
+# CYGNUS LOCAL dj/cygwin
+AC_CANONICAL_HOST
+# If we built a cygwin-specific tcl, use it here.
+case "${host}" in
+*-*-cygwin*)
+ if test -d $srcdir/../tcl/cygwin/.
+ then
+ TCL_BUILD_LIB_SPEC="../tcl/cygwin/libtcl8.0.a"
+ # Use the same static lib for installed_expect
+ TCL_LIB_SPEC="../tcl/cygwin/libtcl8.0.a"
+ fi
+ ;;
+esac
+
+# An explanation is in order for the strange things going on with the
+# various LIBS. There are three separate definitions for LIBS. The
+# reason is that some systems require shared libraries include
+# references to their dependent libraries, i.e., any additional
+# libraries that must be linked to. And some systems get upset if the
+# references are repeated on the link line. So therefore, we create
+# one for Expect and Tk (EXP_AND_TK_LIBS), one for Expect and Tcl
+# (EXP_AND_TCL_LIBS), and finally, one for building Expect's own
+# shared library. Tcl's tclConfig.sh insists that any shared libs
+# that it "helps" build must pass the libraries as LIBS (see comment
+# near end of this configure file). I would do but since we're close
+# to hitting config's max symbols, we take one short cut and pack the
+# LIBS into EXP_SHLIB_LD_LIBS (which is basically what Tcl wants to do
+# for us). The point, however, is that there's no separate LIBS or
+# EXP_LIBS symbol passed out of configure. One additional point for
+# confusion is that LIBS is what configure uses to do all library
+# tests, so we have to swap definitions of LIBS peridically. When we
+# are swapping out the one for Expect's shared library, we save it in
+# EXP_LIBS. Sigh.
+
+dnl AC_PROG_CC insists on sticking crap -g and -O in CFLAGS
+dnl but I want to control it. Can't just throw it out at the
+dnl end alas, because the user might have defined CFLAGS.
+dnl CYGNUS LOCAL: just use AC_PROG_CC; we don't care.
+dnl OLD_CFLAGS=$CFLAGS
+OLD_CFLAGS=$CFLAGS
+AC_PROG_CC
+CFLAGS=$OLD_CFLAGS
+dnl CFLAGS=$OLD_CFLAGS
+dnl END CYGNUS LOCAL
+
+CY_AC_C_WORKS
+
+# this'll use a BSD compatible install or our included install-sh
+AC_PROG_INSTALL
+
+# Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared
+AC_PROG_RANLIB
+UNSHARED_RANLIB=$RANLIB
+
+# these are the other subdirectories we need to configure
+AC_CONFIG_SUBDIRS(testsuite)
+
+# This is for LynxOS, which needs a flag to force true POSIX when
+# building. The flag varies depending how old the compiler is.
+# -X is for the old "cc" and "gcc" (based on 1.42)
+# -mposix is for the new gcc (at least 2.5.8)
+# This modifies the value of $CC to have the POSIX flag added
+# so it'll configure correctly
+CY_AC_TCL_LYNX_POSIX
+
+AC_TYPE_PID_T
+AC_RETSIGTYPE
+dnl AC_TIME_WITH_SYS_TIME
+AC_HEADER_TIME
+AC_HEADER_SYS_WAIT
+
+dnl CYGNUS LOCAL: always respect CFLAGS.
+EXP_CFLAGS=""
+dnl case "${host}" in
+# Use -g on all systems but Linux where it upsets the dynamic X libraries.
+dnl i[[3456]]86-*-linux*) EXP_CFLAGS="" ;;
+dnl esac
+dnl END CYGNUS LOCAL
+
+AC_MSG_CHECKING([if running Mach])
+mach=0
+case "${host}" in
+ # Both Next and pure Mach behave identically with respect
+ # to a few things, so just lump them together as "mach"
+ *-*-mach*) mach=1 ;;
+ *-*-next*) mach=1 ; next=1 ;;
+esac
+
+if test $mach -eq 1 ; then
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING([if running MachTen])
+# yet another Mach clone
+if test -r /MachTen -a "$cross_compiling" != "yes" ; then
+ AC_MSG_RESULT(yes)
+ mach=1
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING([if on Pyramid])
+if test -r /bin/pyr -a "$cross_compiling" != "yes" ; then
+ AC_MSG_RESULT(yes)
+ pyr=1
+else
+ AC_MSG_RESULT(no)
+ pyr=0
+fi
+
+AC_MSG_CHECKING([if on Apollo])
+if test -r /usr/apollo/bin -a "$cross_compiling" != "yes" ; then
+ AC_MSG_RESULT(yes)
+ apollo=1
+else
+ AC_MSG_RESULT(no)
+ apollo=0
+fi
+
+AC_MSG_CHECKING([if on Interactive])
+if test "x`(uname -s) 2>/dev/null`" = xIUNIX; then
+ AC_MSG_RESULT(yes)
+ iunix=1
+else
+ AC_MSG_RESULT(no)
+ iunix=0
+fi
+
+AC_MSG_CHECKING([if stty reads stdout])
+
+# On some systems stty can't be run in the background (svr4) or get it
+# wrong because they fail to complain (next, mach), so don't attempt
+# the test on some systems.
+
+stty_reads_stdout=""
+case "${host}" in
+ *-*-solaris*) stty_reads_stdout=0 ;;
+ *-*-irix*) stty_reads_stdout=0 ;;
+ *-*-sco3.2v[[45]]*) stty_reads_stdout=1 ;;
+ i[[3456]]86-*-sysv4.2MP) stty_reads_stdout=0 ;;
+ i[[3456]]86-*-linux*) stty_reads_stdout=0 ;;
+ # Not sure about old convex but 5.2 definitely reads from stdout
+ c[[12]]-*-*) stty_reads_stdout=1 ;;
+ *-*-aix[[34]]*) stty_reads_stdout=0 ;;
+ *-*-hpux9*) stty_reads_stdout=0 ;;
+ *-*-hpux10*) stty_reads_stdout=0 ;;
+ *-*-hpux11*) stty_reads_stdout=0 ;;
+ *-*-osf[[234]]*) stty_reads_stdout=0 ;;
+ *-*-ultrix4.4) stty_reads_stdout=0 ;;
+ *-*-dgux*) stty_reads_stdout=0 ;;
+ *-*-cygwin*) stty_reads_stdout=0 ;;
+esac
+
+if test $mach -eq 1 ; then
+ stty_reads_stdout=1
+fi
+if test $apollo -eq 1 ; then
+ stty_reads_stdout=1
+fi
+if test $pyr -eq 1 ; then
+ stty_reads_stdout=1
+fi
+
+# if we still don't know, test
+if test x"${stty_reads_stdout}" = x"" ; then
+ /bin/stty > /dev/null 2> /dev/null
+ if test $? -ne 0 ; then
+ stty_reads_stdout=1
+ else
+ stty_reads_stdout=0
+ fi
+fi
+
+if test ${stty_reads_stdout} -eq 1 ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(STTY_READS_STDOUT)
+else
+ AC_MSG_RESULT(no)
+fi
+
+# Solaris 2.4 and later requires __EXTENSIONS__ in order to see all sorts
+# of traditional but nonstandard stuff in header files.
+AC_MSG_CHECKING([if running Solaris])
+solaris=0
+case "${host}" in
+ *-*-solaris*) solaris=1;;
+esac
+
+if test $solaris -eq 1 ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(SOLARIS)
+else
+ AC_MSG_RESULT(no)
+fi
+
+
+# On a few systems, libm.a is the same as libc.a
+# Don't bother to test against Tcl and Tk libs, they always include -lm
+AC_CHECK_FUNC(sin, , LIBS="${LIBS} -lm" )
+
+# On Interactive UNIX, -Xp must be added to LIBS in order to find strftime.
+# This test should really be done by Tcl. So just check Tcl's definition.
+# If defective, add to all three LIBS. (It's not actually necessary for
+# EXP_LIBS since -Xp will just be ignored the way that EXP_LIBS is used in
+# the Makefile, but we include it for consistency.)
+if test $iunix -eq 1 ; then
+ EXP_LIBS=$LIBS
+ LIBS=$EXP_AND_TCL_LIBS
+ AC_CHECK_FUNC(strftime, , [
+ EXP_LIBS="${LIBS} -Xp"
+ EXP_AND_TCL_LIBS="${LIBS} -Xp"
+ EXP_AND_TK_LIBS="${LIBS} -Xp"
+ ])
+ LIBS=EXP_LIBS
+fi
+
+#
+# Ok, lets find the tcl source trees so we can use the headers
+#
+CY_AC_PATH_TCLH
+if test x"$no_tcl" = x"true" ; then
+ echo " ERROR: Can't find Tcl headers or library."
+ echo " See README for information on how to obtain Tcl."
+ echo " If Tcl is installed, see INSTALL on how to tell"
+ echo " configure where Tcl is installed."
+ exit 1
+fi
+CY_AC_PATH_ITCLH
+
+# have to whether we're generating shared libs before configuring debugger
+AC_MSG_CHECKING([if generating shared or nonshared library])
+AC_ARG_ENABLE(shared,
+ [ --enable-shared build libexpect as a shared library],
+ [enable_shared=$enableval], [enable_shared=no])
+if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then
+ AC_MSG_RESULT(both shared and unshared)
+else
+ AC_MSG_RESULT(unshared)
+fi
+
+# Now that we've found the Tcl sources, configure the debugger
+# this is a little tricky because it has its own configure script
+# which produces a Makefile and cf file. We only want the cf file,
+# so switch to a temporary directory and run the debugger's configure.
+# Then save the cf file and delete the rest.
+#
+# Incidentally, the debugger can't depend on Expect's cf file, because
+# the debugger is designed to be independent of Expect.
+#
+
+test -n "$verbose" && echo "configuring Tcl debugger"
+tmpdir=./Dbg$$
+mkdir ${tmpdir}
+
+if test "${enable_shared}" = "yes"; then
+ dbg_config_flags='--enable-shared'
+else
+ dbg_config_flags='--disable-shared'
+fi
+# (cd;pwd) in next several commands converts relative dirs to absolute.
+# This is required because the debugger src is at a different level in
+# the filesystem than Expect src (where we are presently), thereby
+# making the relative pathnames incorrect.
+if test "x$with_tclconfig" != "x" ; then
+ dbg_config_flags="$dbg_config_flags --with-tclconfig=`(cd ${with_tclconfig}; pwd)`"
+fi
+if test "x$with_tcllibdir" != "x" ; then
+ dbg_config_flags="$dbg_config_flags --with-tcllibdir=`(cd ${with_tcllibdir}; pwd)`"
+fi
+if test "x$with_tcllib" != "x" ; then
+ dbg_config_flags="$dbg_config_flags --with-tcllib=`(cd ${with_tcllib}; pwd)`"
+fi
+if test "x$with_tclinclude" != "x" ; then
+ dbg_config_flags="$dbg_config_flags --with-tclinclude=`(cd ${with_tclinclude}; pwd)`"
+fi
+case "$cache_file" in
+ /*)
+ dbg_config_flags="$dbg_config_flags --cache-file=$cache_file"
+ ;;
+ *)
+ dbg_config_flags="$dbg_config_flags --cache-file=../$cache_file"
+ ;;
+esac
+
+cp ${srcdir}/Dbgconfigure ${srcdir}/Dbg.h ${srcdir}/Dbg_cf.h.in ${srcdir}/install-sh ${tmpdir}
+cp $srcdir/DbgMkfl.in ${tmpdir}/Makefile.in
+ (cd $tmpdir; ${CONFIG_SHELL-/bin/sh} Dbgconfigure --with-tclinclude=`echo ${TCLHDIR} | sed -e 's/-I//'` $dbg_config_flags)
+cp ${tmpdir}/Dbg_cf.h .
+rm -rf $tmpdir
+test -n "$verbose" && echo "configured Tcl debugger"
+
+# some people would complain if this explanation wasn't provided...
+
+echo "Begin tests for function/library dependencies. Tests may be repeated"
+echo "up to three times. First test is for building Expect's shared library."
+echo "Second set is for building with Tcl. Third is for building with Tk."
+
+######################################################################
+# required by Sequent ptx2
+unset ac_cv_func_gethostname
+AC_CHECK_FUNC(gethostname, gethostname=1 , gethostname=0)
+if test $gethostname -eq 0 ; then
+ unset ac_cv_lib_inet_gethostname
+ AC_CHECK_LIB(inet, gethostname, LIBS="$LIBS -linet")
+fi
+# save results and retry for Tcl
+EXP_LIBS=$LIBS
+LIBS=$EXP_AND_TCL_LIBS
+unset ac_cv_func_gethostname
+AC_CHECK_FUNC(gethostname, gethostname=1 , gethostname=0)
+if test $gethostname -eq 0 ; then
+ unset ac_cv_lib_inet_gethostname
+ AC_CHECK_LIB(inet, gethostname, LIBS="$LIBS -linet")
+fi
+# save Tcl results and retry for Tk
+EXP_AND_TCL_LIBS=$LIBS
+LIBS=$EXP_AND_TK_LIBS
+unset ac_cv_func_gethostname
+AC_CHECK_FUNC(gethostname, gethostname=1 , gethostname=0)
+if test $gethostname -eq 0 ; then
+ unset ac_cv_lib_inet_gethostname
+ AC_CHECK_LIB(inet, gethostname, LIBS="$LIBS -linet")
+fi
+# save Tk results and reset for Expect
+EXP_AND_TK_LIBS=$LIBS
+LIBS=$EXP_LIBS
+
+######################################################################
+# required by Fischman's ISC 4.0
+unset ac_cv_func_socket
+AC_CHECK_FUNC(socket, socket=1 , socket=0)
+if test $socket -eq 0 ; then
+ unset ac_cv_lib_inet_socket
+ AC_CHECK_LIB(inet, socket, LIBS="$LIBS -linet")
+fi
+# save results and retry for Tcl
+EXP_LIBS=$LIBS
+LIBS=$EXP_AND_TCL_LIBS
+unset ac_cv_func_socket
+AC_CHECK_FUNC(socket, socket=1 , socket=0)
+if test $socket -eq 0 ; then
+ unset ac_cv_lib_inet_socket
+ AC_CHECK_LIB(inet, socket, LIBS="$LIBS -linet")
+fi
+# save Tcl results and retry for Tk
+EXP_AND_TCL_LIBS=$LIBS
+LIBS=$EXP_AND_TK_LIBS
+unset ac_cv_func_socket
+AC_CHECK_FUNC(socket, socket=1 , socket=0)
+if test $socket -eq 0 ; then
+ unset ac_cv_lib_inet_socket
+ AC_CHECK_LIB(inet, socket, LIBS="$LIBS -linet")
+fi
+# save Tk results and reset for Expect
+EXP_AND_TK_LIBS=$LIBS
+LIBS=$EXP_LIBS
+
+######################################################################
+unset ac_cv_func_select
+AC_CHECK_FUNC(select, select=1 , select=0)
+if test $select -eq 0 ; then
+ unset ac_cv_lib_inet_select
+ AC_CHECK_LIB(inet, select, LIBS="$LIBS -linet")
+fi
+# save results and retry for Tcl
+EXP_LIBS=$LIBS
+LIBS=$EXP_AND_TCL_LIBS
+unset ac_cv_func_select
+AC_CHECK_FUNC(select, select=1 , select=0)
+if test $select -eq 0 ; then
+ unset ac_cv_lib_inet_select
+ AC_CHECK_LIB(inet, select, LIBS="$LIBS -linet")
+fi
+# save Tcl results and retry for Tk
+EXP_AND_TCL_LIBS=$LIBS
+LIBS=$EXP_AND_TK_LIBS
+unset ac_cv_func_select
+AC_CHECK_FUNC(select, select=1 , select=0)
+if test $select -eq 0 ; then
+ unset ac_cv_lib_inet_select
+ AC_CHECK_LIB(inet, select, LIBS="$LIBS -linet")
+fi
+# save Tk results and reset for Expect
+EXP_AND_TK_LIBS=$LIBS
+LIBS=$EXP_LIBS
+
+######################################################################
+unset ac_cv_func_getpseudotty
+AC_CHECK_FUNC(getpseudotty, getpseudotty=1 , getpseudotty=0)
+if test $getpseudotty -eq 0 ; then
+ unset ac_cv_lib_seq_getpseudotty
+ AC_CHECK_LIB(seq, getpseudotty)
+fi
+# save results and retry for Tcl
+EXP_LIBS=$LIBS
+LIBS=$EXP_AND_TCL_LIBS
+unset ac_cv_func_getpseudotty
+AC_CHECK_FUNC(getpseudotty, getpseudotty=1 , getpseudotty=0)
+if test $getpseudotty -eq 0 ; then
+ unset ac_cv_lib_seq_getpseudotty
+ AC_CHECK_LIB(seq, getpseudotty)
+fi
+# save Tcl results and retry for Tk
+EXP_AND_TCL_LIBS=$LIBS
+LIBS=$EXP_AND_TK_LIBS
+unset ac_cv_func_getpseudotty
+AC_CHECK_FUNC(getpseudotty, getpseudotty=1 , getpseudotty=0)
+if test $getpseudotty -eq 0 ; then
+ unset ac_cv_lib_seq_getpseudotty
+ AC_CHECK_LIB(seq, getpseudotty)
+fi
+# save Tk results and reset for Expect
+EXP_AND_TK_LIBS=$LIBS
+LIBS=$EXP_LIBS
+
+######################################################################
+# Check for FreeBSD/NetBSD openpty()
+# CYGNUS LOCAL: Don't do this on Linux. Alpha Linux Red Hat 4.2 has
+# openpty, but it doesn't work correctly.
+case "${host}" in
+*-*-linux*) ;;
+*)
+ unset ac_cv_func_openpty
+ AC_CHECK_FUNC(openpty, openpty=1 , openpty=0)
+ if test $openpty -eq 0 ; then
+ unset ac_cv_lib_util_openpty
+ AC_CHECK_LIB(util, openpty, [
+ # we only need to define OPENPTY once, but since we are overriding
+ # the default behavior, we must also handle augment LIBS too.
+ # This needn't be done in the 2nd and 3rd tests.
+ AC_DEFINE(HAVE_OPENPTY)
+ LIBS="$LIBS -lutil"
+ ])
+ fi
+ # save results and retry for Tcl
+ EXP_LIBS=$LIBS
+ LIBS=$EXP_AND_TCL_LIBS
+ unset ac_cv_func_openpty
+ AC_CHECK_FUNC(openpty, openpty=1 , openpty=0)
+ if test $openpty -eq 0 ; then
+ unset ac_cv_lib_util_openpty
+ AC_CHECK_LIB(util, openpty, [
+ AC_DEFINE(HAVE_OPENPTY)
+ LIBS="$LIBS -lutil"
+ ])
+ fi
+ # save Tcl results and retry for Tk
+ EXP_AND_TCL_LIBS=$LIBS
+ LIBS=$EXP_AND_TK_LIBS
+ unset ac_cv_func_openpty
+ AC_CHECK_FUNC(openpty, openpty=1 , openpty=0)
+ if test $openpty -eq 0 ; then
+ unset ac_cv_lib_util_openpty
+ AC_CHECK_LIB(util, openpty, [
+ AC_DEFINE(HAVE_OPENPTY)
+ LIBS="$LIBS -lutil"
+ ])
+ fi
+ # save Tk results and reset for Expect
+ EXP_AND_TK_LIBS=$LIBS
+ LIBS=$EXP_LIBS
+
+ # CYGNUS LOCAL: Link against luser32 on Cygwin.
+ case "${host}" in
+ *-*-cygwin*) EXP_AND_TCL_LIBS="$EXP_AND_TCL_LIBS -luser32" ;;
+ esac
+;;
+esac
+
+######################################################################
+# End of library/func checking
+######################################################################
+
+######################################################################
+#
+# Look for various header files
+#
+AC_CHECK_HEADER(sys/sysmacros.h, AC_DEFINE(HAVE_SYSMACROS_H))
+AC_CHECK_HEADER(stdlib.h, ,AC_DEFINE(NO_STDLIB_H))
+
+#
+# Look for inttypes.h. Sometimes there are data type conflicts
+# with sys/types.h, so we have to use our own special test.
+#
+dnl AC_CHECK_HEADER(inttypes.h, AC_DEFINE(HAVE_INTTYPES_H))
+CY_AC_INTTYPES_H
+
+# Oddly, some systems have stdarg but don't support prototypes
+# Tcl avoids the whole issue by not using stdarg on UNIX at all!
+dnl AC_CHECK_HEADER(stdarg.h, AC_DEFINE(HAVE_STDARG_H))
+
+AC_CHECK_HEADER(varargs.h, AC_DEFINE(HAVE_VARARGS_H))
+AC_CHECK_HEADER(unistd.h, AC_DEFINE(HAVE_UNISTD_H))
+AC_CHECK_HEADER(sys/stropts.h, AC_DEFINE(HAVE_STROPTS_H))
+AC_CHECK_HEADER(sys/sysconfig.h, AC_DEFINE(HAVE_SYSCONF_H))
+AC_CHECK_HEADER(sys/fcntl.h, AC_DEFINE(HAVE_SYS_FCNTL_H))
+AC_CHECK_HEADER(sys/select.h, AC_DEFINE(HAVE_SYS_SELECT_H))
+AC_CHECK_HEADER(sys/time.h, AC_DEFINE(HAVE_SYS_TIME_H))
+AC_CHECK_HEADER(sys/ptem.h, AC_DEFINE(HAVE_SYS_PTEM_H))
+AC_CHECK_HEADER(sys/strredir.h, AC_DEFINE(HAVE_STRREDIR_H))
+AC_CHECK_HEADER(sys/strpty.h, AC_DEFINE(HAVE_STRPTY_H))
+
+dnl #echo checking for ucbinclude/sys/ioctl.h (ucb-style ioctl.h under SV)
+dnl #if test -f /usr/ucbinclude/sys/ioctl.h ; then
+dnl # AC_DEFINE(HAVE_UCB_IOCTL_H)
+dnl #fi
+
+AC_MSG_CHECKING([for sys/bsdtypes.h])
+if test "ISC_${ISC}" = "ISC_1" ; then
+ AC_MSG_RESULT(yes)
+ # if on ISC 1, we need <sys/bsdtypes.h> to get FD_SET macros
+ AC_HAVE_HEADERS(sys/bsdtypes.h)
+else
+ AC_MSG_RESULT(no)
+fi
+
+#
+# Look for functions that may be missing
+#
+dnl AC_CHECK_FUNC(memcpy, AC_DEFINE(HAVE_MEMCPY))
+AC_CHECK_FUNC(memmove, AC_DEFINE(HAVE_MEMMOVE))
+AC_CHECK_FUNC(sysconf, AC_DEFINE(HAVE_SYSCONF))
+AC_CHECK_FUNC(strftime, AC_DEFINE(HAVE_STRFTIME))
+AC_CHECK_FUNC(strchr, AC_DEFINE(HAVE_STRCHR))
+AC_CHECK_FUNC(timezone, AC_DEFINE(HAVE_TIMEZONE))
+
+# dnl check for memcpy by hand
+# because Unixware 2.0 handles it specially and refuses to compile
+# autoconf's automatic test that is a call with no arguments
+AC_MSG_CHECKING([for memcpy])
+AC_TRY_LINK(,[
+char *s1, *s2;
+memcpy(s1,s2,0);
+],
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_MEMCPY)
+ ,
+ AC_MSG_RESULT(no)
+)
+
+# Some systems only define WNOHANG if _POSIX_SOURCE is defined
+# The following merely tests that sys/wait.h can be included
+# and if so that WNOHANG is not defined. The only place I've
+# seen this is ISC.
+AC_MSG_CHECKING([if WNOHANG requires _POSIX_SOURCE])
+AC_TRY_RUN([
+#include <sys/wait.h>
+main() {
+#ifndef WNOHANG
+ return 0;
+#else
+ return 1;
+#endif
+}],
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WNOHANG_REQUIRES_POSIX_SOURCE)
+,
+ AC_MSG_RESULT(no)
+,
+ [case "${host}" in
+ *-*-cygwin*) AC_MSG_RESULT(no) ;;
+ *) AC_MSG_ERROR([Expect can't be cross compiled]) ;;
+ esac]
+)
+
+AC_MSG_CHECKING([if any value exists for WNOHANG])
+rm -rf wnohang
+AC_TRY_RUN([
+#include <stdio.h>
+#include <sys/wait.h>
+main() {
+#ifdef WNOHANG
+ FILE *fp = fopen("wnohang","w");
+ fprintf(fp,"%d",WNOHANG);
+ fclose(fp);
+ return 0;
+#else
+ return 1;
+#endif
+}],
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_UNQUOTED(WNOHANG_BACKUP_VALUE, `cat wnohang`)
+ rm -f wnohang
+,
+ AC_MSG_RESULT(no)
+ AC_DEFINE(WNOHANG_BACKUP_VALUE, 1)
+,
+ [case "${host}" in
+ *-*-cygwin*) AC_MSG_RESULT(yes)
+ AC_DEFINE(WNOHANG_BACKUP_VALUE, 1) ;;
+ *) AC_MSG_ERROR([Expect can't be cross compiled]) ;;
+ esac]
+)
+
+#
+# check how signals work
+#
+
+# Check for the data type of the mask used in select().
+# This picks up HP braindamage which defines fd_set and then
+# proceeds to ignore it and use int.
+# Pattern matching on int could be loosened.
+# Can't use ac_header_egrep since that doesn't see prototypes with K&R cpp.
+AC_MSG_CHECKING([mask type of select])
+if egrep "select\(size_t, int" /usr/include/sys/time.h >/dev/null 2>&1; then
+ AC_MSG_RESULT(int)
+ AC_DEFINE(SELECT_MASK_TYPE, int)
+else
+ AC_MSG_RESULT(none)
+fi
+
+dnl # Check for the data type of the function used in signal(). This
+dnl # must be before the test for rearming.
+dnl # echo checking return type of signal handlers
+dnl AC_HEADER_EGREP([(void|sighandler_t).*signal], signal.h, retsigtype=void,AC_DEFINE(RETSIGTYPE, int) retsigtype=int)
+
+# FIXME: check if alarm exists
+AC_MSG_CHECKING([if signals need to be re-armed])
+AC_TRY_RUN([
+#include <signal.h>
+#define RETSIGTYPE $retsigtype
+
+int signal_rearms = 0;
+
+RETSIGTYPE
+child_sigint_handler(n)
+int n;
+{
+}
+
+RETSIGTYPE
+parent_sigint_handler(n)
+int n;
+{
+signal_rearms++;
+}
+
+main()
+{
+ signal(SIGINT,parent_sigint_handler);
+
+ if (0 == fork()) {
+ signal(SIGINT,child_sigint_handler);
+ kill(getpid(),SIGINT);
+ kill(getpid(),SIGINT);
+ kill(getppid(),SIGINT);
+ } else {
+ int status;
+
+ wait(&status);
+ unlink("core");
+ exit(signal_rearms);
+ }
+}],
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(REARM_SIG)
+,
+ AC_MSG_RESULT(no)
+,
+ [case "${host}" in
+ *-*-cygwin*) AC_MSG_RESULT(no) ;;
+ *) AC_MSG_WARN([Expect can't be cross compiled]) ;;
+ esac]
+)
+
+# HPUX7 has trouble with the big cat so split it
+# Owen Rees <rtor@ansa.co.uk> 29Mar93
+SEDDEFS="${SEDDEFS}CONFEOF
+cat >> conftest.sed <<CONFEOF
+"
+#
+
+# There are multiple versions of getpty, alas.
+# I don't remember who has the first one, but Convex just added one
+# so check for it. Unfortunately, there is no header so the only
+# reasonable way to make sure is to look it we are on a Convex.
+AC_MSG_CHECKING([if on Convex])
+convex=0
+case "${host}" in
+ c[[12]]-*-*) convex=1;;
+esac
+
+if test $convex -eq 1 ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(CONVEX)
+else
+ AC_MSG_RESULT(no)
+fi
+
+EXP_LDFLAGS=
+
+AC_MSG_CHECKING([if on NeXT])
+if test -r /NextApps -a "$cross_compiling" != "yes" ; then
+ AC_MSG_RESULT(yes)
+ # "-m" flag suppresses complaints about multiple strtod
+ EXP_LDFLAGS="$EXP_LDFLAGS -m"
+else
+ AC_MSG_RESULT(no)
+fi
+
+
+AC_MSG_CHECKING([if on HP])
+if test "x`(uname) 2>/dev/null`" = xHP-UX; then
+ AC_MSG_RESULT(yes)
+ hp=1
+else
+ AC_MSG_RESULT(no)
+ hp=0
+fi
+
+AC_MSG_CHECKING([sane default stty arguments])
+DEFAULT_STTY_ARGS="sane"
+
+if test $mach -eq 1 ; then
+ DEFAULT_STTY_ARGS="cooked"
+fi
+
+if test $hp -eq 1 ; then
+ DEFAULT_STTY_ARGS="sane kill "
+fi
+
+AC_MSG_RESULT($DEFAULT_STTY_ARG)
+
+# Look for various features to determine what kind of pty
+# we have. For some weird reason, ac_compile_check would not
+# work, but ac_test_program does.
+#
+AC_MSG_CHECKING([for HP style pty allocation])
+# following test fails on DECstations and other things that don't grok -c
+# but that's ok, since they don't have PTYMs anyway
+if test -r /dev/ptym/ptyp0 2>/dev/null -a "$cross_compiling" != "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PTYM)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING([for HP style pty trapping])
+AC_HEADER_EGREP([struct.*request_info], sys/ptyio.h,
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PTYTRAP)
+,
+ AC_MSG_RESULT(no)
+)
+
+AC_MSG_CHECKING([for AIX new-style pty allocation])
+if test -r /dev/ptc -a -r /dev/pts -a "$cross_compiling" != "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PTC_PTS)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING([for SGI old-style pty allocation])
+if test -r /dev/ptc -a ! -r /dev/pts -a "$cross_compiling" != "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PTC)
+else
+ AC_MSG_RESULT(no)
+fi
+
+# On SCO OpenServer, two types of ptys are available: SVR4 streams and c-list.
+# The library routines to open the SVR4 ptys are broken on certain systems and
+# the SCO command to increase the number of ptys only configure c-list ones
+# anyway. So we chose these, which have a special numbering scheme.
+#
+AC_MSG_CHECKING([for SCO style pty allocation])
+sco_ptys=""
+case "${host}" in
+ *-sco3.2v[[45]]*) sco_clist_ptys=1 svr4_ptys_broken=1;;
+esac
+
+if test x"${sco_clist_ptys}" != x"" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SCO_CLIST_PTYS)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING([for SVR4 style pty allocation])
+if test -r /dev/ptmx -a "x$svr4_ptys_broken" = x -a "$cross_compiling" != "yes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PTMX)
+ # aargg. Some systems need libpt.a to use /dev/ptmx
+ AC_CHECK_FUNC(ptsname, , LIBS="${LIBS} -lpt")
+ # I've never seen Tcl or Tk include -lpt so don't bother with explicit test
+ AC_CHECK_FUNC(ptsname, , EXP_AND_TCL_LIBS="${EXP_AND_TCL_LIBS} -lpt")
+ AC_CHECK_FUNC(ptsname, , EXP_AND_TK_LIBS="${EXP_AND_TK_LIBS} -lpt")
+else
+ AC_MSG_RESULT(no)
+fi
+
+# In OSF/1 case, SVR4 are somewhat different.
+# Gregory Depp <depp@osf.org> 17Aug93
+AC_MSG_CHECKING([for OSF/1 style pty allocation])
+if test -r /dev/ptmx_bsd -a "$cross_compiling" != "yes" ; then
+ AC_DEFINE(HAVE_PTMX_BSD)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+# Set the pty handling for Cygwin
+case "${host}" in
+ *-*-cygwin*) AC_DEFINE(HAVE_PTMX) ;;
+ *) ;;
+esac
+
+tcgetattr=0
+tcsetattr=0
+AC_CHECK_FUNC(tcgetattr, tcgetattr=1)
+AC_CHECK_FUNC(tcsetattr, tcsetattr=1)
+if test $tcgetattr -eq 1 -a $tcsetattr -eq 1 ; then
+ AC_DEFINE(HAVE_TCSETATTR)
+ AC_DEFINE(POSIX)
+fi
+
+# first check for the pure bsd
+AC_MSG_CHECKING([for struct sgttyb])
+AC_TRY_RUN([
+#include <sgtty.h>
+main()
+{
+ struct sgttyb tmp;
+ exit(0);
+}],
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SGTTYB)
+ PTY_TYPE=sgttyb
+,
+ AC_MSG_RESULT(no)
+,
+ [case "${host}" in
+ *-*-cygwin*) AC_MSG_RESULT(no) ;;
+ *) AC_MSG_ERROR([Expect can't be cross compiled]) ;;
+ esac]
+)
+
+# mach systems have include files for unimplemented features
+# so avoid doing following test on those systems
+if test $mach -eq 0 ; then
+
+ # next check for the older style ttys
+ # note that if we detect termio.h (only), we still set PTY_TYPE=termios
+ # since that just controls which of pty_XXXX.c file is use and
+ # pty_termios.c is set up to handle pty_termio.
+ AC_MSG_CHECKING([for struct termio])
+ AC_TRY_RUN([#include <termio.h>
+ main()
+ {
+ struct termio tmp;
+ exit(0);
+ }],
+ AC_DEFINE(HAVE_TERMIO)
+ PTY_TYPE=termios
+ AC_MSG_RESULT(yes)
+,
+ AC_MSG_RESULT(no)
+,
+ [case "${host}" in
+ *-*-cygwin*) AC_MSG_RESULT(no) ;;
+ *) AC_MSG_ERROR([Expect can't be cross compiled]) ;;
+ esac]
+)
+
+ # now check for the new style ttys (not yet posix)
+ AC_MSG_CHECKING([for struct termios])
+ AC_TRY_RUN([
+# ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+# endif
+# include <termios.h>
+ main()
+ {
+ struct termios tmp;
+ exit(0);
+ }],
+ AC_DEFINE(HAVE_TERMIOS)
+ PTY_TYPE=termios
+ AC_MSG_RESULT(yes)
+ ,
+ AC_MSG_RESULT(no)
+ ,
+ [case "${host}" in
+ *-*-cygwin*) AC_DEFINE(HAVE_TERMIOS)
+ PTY_TYPE=termios
+ AC_MSG_RESULT(yes) ;;
+ *) AC_MSG_ERROR([Expect can't be cross compiled]) ;;
+ esac]
+ )
+fi
+
+AC_MSG_CHECKING([if TCGETS or TCGETA in termios.h])
+AC_TRY_RUN([
+/* including termios.h on Solaris 5.6 fails unless inttypes.h included */
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <termios.h>
+main() {
+#if defined(TCGETS) || defined(TCGETA)
+ return 0;
+#else
+ return 1;
+#endif
+}],
+ AC_DEFINE(HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H)
+ AC_MSG_RESULT(yes)
+,
+ AC_MSG_RESULT(no)
+,
+ [case "${host}" in
+ *-*-cygwin*) AC_DEFINE(HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H)
+ AC_MSG_RESULT(yes) ;;
+ *) AC_MSG_ERROR([Expect can't be cross compiled]) ;;
+ esac]
+)
+
+AC_MSG_CHECKING([if TIOCGWINSZ in termios.h])
+AC_TRY_RUN([
+/* including termios.h on Solaris 5.6 fails unless inttypes.h included */
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <termios.h>
+main() {
+#ifdef TIOCGWINSZ
+ return 0;
+#else
+ return 1;
+#endif
+}],
+ AC_DEFINE(HAVE_TIOCGWINSZ_IN_TERMIOS_H)
+ AC_MSG_RESULT(yes)
+,
+ AC_MSG_RESULT(no)
+,
+ [case "${host}" in
+ *-*-cygwin*) AC_DEFINE(HAVE_TIOCGWINSZ_IN_TERMIOS_H)
+ AC_MSG_RESULT(yes) ;;
+ *) AC_MSG_ERROR([Expect can't be cross compiled]) ;;
+ esac]
+)
+
+# finally check for Cray style ttys
+AC_MSG_CHECKING([for Cray-style ptys])
+SETUID=":"
+AC_TRY_RUN([
+main(){
+#ifdef CRAY
+ return 0;
+#else
+ return 1;
+#endif
+}
+],
+ PTY_TYPE=unicos
+ SETUID="chmod u+s"
+ AC_MSG_RESULT(yes)
+,
+ AC_MSG_RESULT(no)
+,
+ [case "${host}" in
+ *-*-cygwin*) AC_MSG_RESULT(no) ;;
+ *) AC_MSG_ERROR([Expect can't be cross compiled]) ;;
+ esac]
+)
+
+#
+# Check for select and/or poll. If both exist, we prefer select.
+# if neither exists, define SIMPLE_EVENT.
+#
+select=0
+poll=0
+unset ac_cv_func_select
+AC_CHECK_FUNC(select, select=1)
+AC_CHECK_FUNC(poll, poll=1)
+AC_MSG_CHECKING([event handling])
+if test $select -eq 1 ; then
+ EVENT_TYPE=select
+ EVENT_ABLE=event
+ AC_MSG_RESULT(via select)
+elif test $poll -eq 1 ; then
+ EVENT_TYPE=poll
+ EVENT_ABLE=event
+ AC_MSG_RESULT(via poll)
+else
+ EVENT_TYPE=simple
+ EVENT_ABLE=noevent
+ AC_MSG_RESULT(none)
+ AC_DEFINE(SIMPLE_EVENT)
+fi
+
+AC_HAVE_FUNCS(_getpty)
+AC_HAVE_FUNCS(getpty)
+
+#
+# check for timezones
+#
+AC_MSG_CHECKING([for SV-style timezone])
+AC_TRY_RUN([
+extern char *tzname[2];
+extern int daylight;
+main()
+{
+ int *x = &daylight;
+ char **y = tzname;
+
+ exit(0);
+}],
+ AC_DEFINE(HAVE_SV_TIMEZONE)
+ AC_MSG_RESULT(yes),
+ AC_MSG_RESULT(no)
+,
+ [case "${host}" in
+ *-*-cygwin*) AC_MSG_RESULT(no) ;;
+ *) AC_MSG_ERROR([Expect can't be cross compiled]) ;;
+ esac]
+)
+
+# only look for Tk stuff if we have X11 and user doesn't say not to
+AC_ARG_WITH(x, [ --with-x whether or not to use X (default yes)], , with_x=yes)
+if test "$with_x" = "no"; then
+ no_tk=true
+else
+ CY_AC_PATH_TKH
+fi
+if test x"$no_tk" != x"true" ; then
+# libexpectk no longer exists
+# X_PROGS="expectk \$(LIBEXPECTK)"
+ X_PROGS=expectk
+# should really generate following symbol, but I'm hitting configure's limit on substs.
+ X_PROGS_INSTALLED=expectk_installed
+else
+ X_PROGS="# no X support on this system"
+ AC_MSG_WARN([No X based programs will be built])
+ echo " WARNING: Can't find Tk headers or library. You can still"
+ echo " build expect, but not expectk. See Expect's README for"
+ echo " information on how to obtain Tk. If Tk is installed, see"
+ echo " Expect's INSTALL on how to tell configure where Tk is"
+ echo " installed."
+fi
+
+# consume these flags so that user can invoke Expect's configure with
+# the same command as Tcl's configure
+AC_ARG_ENABLE(load,
+ [ --disable-load disallow dynamic loading],
+ [disable_dl=$enableval], [disable_dl=no])
+
+AC_ARG_ENABLE(gcc,
+ [ --enable-gcc allow use of gcc if available],
+ [enable_gcc=$enableval], [enable_gcc=no])
+
+
+# Following comment stolen from Tcl's configure.in:
+# Note: in the following variable, it's important to use the absolute
+# path name of the Tcl directory rather than "..": this is because
+# AIX remembers this path and will attempt to use it at run-time to look
+# up the Tcl library.
+
+if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+ EXP_LIB_VERSION=$EXP_VERSION
+else
+ EXP_LIB_VERSION=$EXP_VERSION_NODOTS
+fi
+if test $iunix -eq 1 ; then
+ EXP_LIB_VERSION=$EXP_VERSION_NODOTS
+fi
+
+# also remove dots on systems that don't support filenames > 14
+# (are there systems which support shared libs and restrict filename lengths!?)
+AC_SYS_LONG_FILE_NAMES
+if test $ac_cv_sys_long_file_names = no; then
+ EXP_LIB_VERSION=$EXP_VERSION_NODOTS
+fi
+
+EXP_BUILD_LIB_SPEC="-L`pwd` -lexpect${EXP_LIB_VERSION}"
+EXP_LIB_SPEC="-L\${exec_prefix}/lib -lexpect${EXP_LIB_VERSION}"
+EXP_UNSHARED_LIB_FILE=libexpect${EXP_LIB_VERSION}.a
+EXP_BUILD_LIB_SPEC=${EXP_UNSHARED_LIB_FILE}
+
+AC_MSG_CHECKING([for type of library to build])
+if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then
+ EXP_SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS
+# EXP_SHARED_LIB_FILE=libexpect$EXP_LIB_VERSION$TCL_SHLIB_SUFFIX
+ eval "EXP_SHARED_LIB_FILE=libexpect${TCL_SHARED_LIB_SUFFIX}"
+ EXP_LIB_FILE=$EXP_SHARED_LIB_FILE
+ EXP_LIB_FILES="$EXP_SHARED_LIB_FILE $EXP_UNSHARED_LIB_FILE"
+ AC_MSG_RESULT(both shared and unshared)
+else
+ EXP_SHLIB_CFLAGS=
+ EXP_SHARED_LIB_FILE="reconfigure_Tcl_for_shared_library"
+ EXP_LIB_FILE=$EXP_UNSHARED_LIB_FILE
+ EXP_LIB_FILES="$EXP_UNSHARED_LIB_FILE"
+ AC_MSG_RESULT(unshared)
+fi
+
+# CYGNUS LOCAL
+# We always link expect statically (against $EXP_UNSHARED_LIB_FILE)
+# so we can run it out of the build directory without hurting
+# ourselves and others.
+dnl EXP_LIB_FILE=$EXP_UNSHARED_LIB_FILE
+
+# now broken out into EXP_AND_TCL_LIBS and EXP_AND_TK_LIBS. Had to do this
+# in order to avoid repeating lib specs to which some systems object.
+EXP_AND_TCL_LIBS="$EXP_AND_TCL_LIBS $TCL_LD_SEARCH_FLAGS"
+EXP_AND_TK_LIBS="$EXP_AND_TK_LIBS $TCL_LD_SEARCH_FLAGS"
+
+# Sigh - Tcl defines SHLIB_LD_LIBS to be either empty or ${LIBS} and
+# LIBS is intended to be expanded by Make. But since we're too close
+# to hitting config's max symbols, pack everything together here and
+# do test ourselves. Ugh.
+#
+if test "x$TCL_SHLIB_LD_LIBS" = "x" ; then
+ EXP_SHLIB_LD_LIBS=""
+else
+ # seems a little strange to build in Tcl's build-lib, but
+ # that's what Tk does.
+ EXP_SHLIB_LD_LIBS="$TCL_BUILD_LIB_SPEC $TCL_DL_LIBS $LIBS -lc"
+fi
+
+dnl CYGNUS LOCAL
+dnl check for win32 dependencies
+CY_AC_CYGWIN32
+CY_AC_EXEEXT
+
+#--------------------------------------------------------------------
+# This section is based on analogous thing in Tk installation. - DEL
+# Various manipulations on the search path used at runtime to
+# find shared libraries:
+# 2. On systems such as AIX and Ultrix that use "-L" as the
+# search path option, colons cannot be used to separate
+# directories from each other. Change colons to " -L".
+# 3. Create two sets of search flags, one for use in cc lines
+# and the other for when the linker is invoked directly. In
+# the second case, '-Wl,' must be stripped off and commas must
+# be replaced by spaces.
+#--------------------------------------------------------------------
+
+LIB_RUNTIME_DIR='${LIB_RUNTIME_DIR}'
+
+# If Tcl and Expect are installed in different places, adjust the library
+# search path to reflect this.
+
+if test "$TCL_EXEC_PREFIX" != "$exec_prefix"; then
+ LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}"
+fi
+
+if test "${TCL_LD_SEARCH_FLAGS}" = '-L${LIB_RUNTIME_DIR}'; then
+ LIB_RUNTIME_DIR=`echo ${LIB_RUNTIME_DIR} |sed -e 's/:/ -L/g'`
+fi
+
+# The statement below is very tricky! It actually *evaluates* the
+# string in TCL_LD_SEARCH_FLAGS, which causes a substitution of the
+# variable LIB_RUNTIME_DIR.
+
+eval "EXP_CC_SEARCH_FLAGS=\"$TCL_LD_SEARCH_FLAGS\""
+if test "$GCC" = yes; then
+ true
+else
+ EXP_LD_SEARCH_FLAGS=`echo ${EXP_CC_SEARCH_FLAGS} |sed -e "s|-Wl,||g" -e "s|,| |g"`
+fi
+
+#
+# Set up makefile substitutions
+#
+AC_SUBST(EXP_MAJOR_VERSION)
+AC_SUBST(EXP_MINOR_VERSION)
+AC_SUBST(EXP_MICRO_VERSION)
+AC_SUBST(EXP_VERSION_FULL)
+AC_SUBST(EXP_VERSION)
+AC_SUBST(CC)
+AC_SUBST(EXP_CONFIG_SHELL)
+AC_SUBST(EXP_SHARED_LIB_FILE)
+AC_SUBST(EXP_UNSHARED_LIB_FILE)
+AC_SUBST(EXP_SHLIB_CFLAGS)
+AC_SUBST(EXP_LIB_FILE)
+AC_SUBST(EXP_LIB_FILES)
+AC_SUBST(EXP_BUILD_LIB_SPEC)
+AC_SUBST(EXP_LIB_SPEC)
+AC_SUBST(EXP_CFLAGS)
+AC_SUBST(EXP_LDFLAGS)
+AC_SUBST(EXP_LD_SEARCH_FLAGS)
+AC_SUBST(EXP_AND_TCL_LIBS)
+AC_SUBST(EXP_AND_TK_LIBS)
+AC_SUBST(EXP_SHLIB_LD_LIBS)
+AC_SUBST(X_PROGS)
+AC_SUBST(PTY_TYPE)
+AC_SUBST(EVENT_TYPE)
+AC_SUBST(EVENT_ABLE)
+AC_SUBST(SETUID)
+AC_SUBST(UNSHARED_RANLIB)
+AC_SUBST(DEFAULT_STTY_ARGS)
+AC_OUTPUT(Makefile pkgIndex)
diff --git a/expect/example/Makefile b/expect/example/Makefile
new file mode 100644
index 00000000000..e921fc2006d
--- /dev/null
+++ b/expect/example/Makefile
@@ -0,0 +1,75 @@
+TCLVERSION = 8.0
+EXPVERSION = 5.25
+TCLROOT = ../../tcl$(TCLVERSION)
+
+# Tcl include files. (If you haven't installed Tcl yet, read the README file).
+# This must point to the directory that contains ALL of Tcl's include
+# files, not just the public ones.
+TCLHDIR = $(TCLROOT)/generic
+
+# TCL library. Very little actually comes out of it, but it is handy.
+TCLLIB = $(TCLROOT)/unix/libtcl$(TCLVERSION).so
+# if installed, you can use:
+# TCLLIB = -ltcl
+
+CC = gcc
+CPLUSPLUS = g++
+CPLUSPLUSLIBDIR = -L/depot/gnu/arch/lib
+CPLUSPLUSLIB = -lg++
+
+CFLAGS = -g -I.. -I$(TCLHDIR)
+LIBEXPECT = -L.. -lexpect$(EXPVERSION)
+
+LIBS = $(LIBEXPECT) $(TCLLIB) -lm
+
+SCRIPTS = su2 noidle script.exp bonfield.exp
+
+all: chesslib chesslib2 chesslib++
+
+# this can be compiled with either cc or gcc
+chesslib: chesslib.o
+ $(CC) -g -o chesslib chesslib.o $(LIBS)
+
+# this can be compiled with either cc or gcc
+chesslib2: chesslib2.o
+ $(CC) -g -o chesslib2 chesslib2.o $(LIBS)
+
+# this is compiled with c++
+chesslib++: chesslib++.o
+ $(CPLUSPLUS) -g -o chesslib++ chesslib++.o $(LIBS) \
+ $(CPLUSPLUSLIBDIR) $(CPLUSPLUSLIB)
+
+chesslib++.o: chesslib++.c
+ $(CPLUSPLUS) -c $(CFLAGS) chesslib++.c
+
+unbuffer-standalone: unbuffer.o
+ $(CC) -g -o unbuffer-standalone unbuffer.o $(LIBS)
+
+printvars: printvars.o
+ $(CC) -o printvars printvars.o $(LIBS)
+
+ftplib: ftplib.o
+ $(CC) -g -o ftplib ftplib.o $(LIBS)
+
+match_max: match_max.o
+ $(CC) -g -o match_max match_max.o $(LIBS)
+
+jaj1: jaj1.o
+ $(CC) -g -o jaj1 jaj1.o $(LIBS)
+
+jaj2: jaj2.o
+ $(CC) -g -o jaj2 jaj2.o $(LIBS)
+
+# wrap up password-generation examples
+passgen:
+ shar passgen.README tkpasswd mkpasswd mkpasswd.man > /tmp/passgen
+
+cleanup:
+ rm -f expect devtty exho dumb test.raw test.results test.tmp
+
+# copy some contributed scripts over to public-accessible directory
+SCRIPTDIR = ~ftp/pub/expect/scripts
+ftp:
+ rcp README.scripts durer:$(SCRIPTDIR)/README
+ rcp $(SCRIPTS) durer:$(SCRIPTDIR)
+ rsh durer ls -l $(SCRIPTDIR)
diff --git a/expect/example/README b/expect/example/README
new file mode 100644
index 00000000000..0f71e595d35
--- /dev/null
+++ b/expect/example/README
@@ -0,0 +1,141 @@
+This file is example/README. It contains brief descriptions of the
+examples in this directory. Also listed are scripts from the Expect
+archive at ftp.cme.nist.gov (See Expect's README for how to retrieve
+these from). You are welcome to send me additional scripts. A number
+of Expect scripts are also available in the Tcl archive, available via
+anonymous ftp at harbor.ecn.purdue.edu
+
+Note that on some systems, some of the scripts (notably kibitz and
+dislocate) require that Expect be installed. (Merely compiling the
+expect binary is not enough.)
+
+--------------------
+Expect scripts (See next section for example Tk scripts)
+--------------------
+Entries marked with "m" have their own man page.
+Entries marked with "a" live in the Expect archive (see above).
+
+ archie - mails back response after talking to archie ftp-catalog.
+ m autoexpect - generate an Expect script from watching a session
+ autopasswd - runs passwd non-interactively for superuser.
+ a bc - Uses bc to do arbitrary precision math.
+ beer.exp - 99 Bottles of Beer On The Wall, Expect-style.
+ beer.exp.out - sample output from beer.exp (but you really have to
+ run it to see the timing aspect).
+ a bonfield.exp - solve Jim Bonfield's puzzle that won the 1991 Obfuscated
+ C Code contest.
+ carpal - warn about typing for too long without a break.
+ chess.exp - has two chess games play each other.
+ m cryptdir - encrypt all files in a directory.
+ m decryptdir - decrypt all files in a directory.
+ m dislocate - allow disconnection/reconnection to background processes.
+ dvorak - dvorak keyboard.
+ a eftp - ftp client with miscellaneous frills (also see rftp below).
+ expectd.proto - telnet daemon.
+ ftp-inband - does file transfer over telnet, rlogin, etc.
+ ftp-rfc - retrieve a DoD RFC from uunet via anonymous ftp.
+ ftp-talk-radio - gets "Internet Talk Radio" files from a host.
+ gethostbyaddr - translates internet address to name (with a higher
+ success rate than nslookup). Easier to use, too.
+ irsh - run interactive commands via rsh
+ m kibitz - lets two people control a program at the same time.
+ Lots of uses. I.e., You can help another person remotely.
+ Can run an editor and log a transcript of a conversation.
+ a libro-II - connect to Libro-II, the NIST library catalog.
+ lpunlock - unhangs a printer which says it is "waiting for lock".
+ a mirror_file - mirror a file from another ftp site, copying file only
+ if changed.
+ a mirror_dir - mirror a directory from another ftp site, copying only
+ files which have changed.
+ m mkpasswd - generates good passwords, optionally runs passwd with them.
+ a mx - return any MX records for the given host.
+ a noidle - run a shell which avoids being 'autologged out'.
+ a pager.alpha - sends a message to a (Alpha brand) pager.
+ a pager.mercury - sends a message to a (Mercury brand) pager.
+ m passmass - sets passwd on many machines simultaneously.
+ passwd.html - form to change a login passwd
+ passwd.cgi - CGI script to respond to passwd.html form
+ a ping-and-page - Ping list of hosts. If any down, page system admin.
+ read1char - read a single character for the shell, Perl, etc.
+ reprompt - like timed-read but reprompt after given amount of time.
+ rlogin-cwd - rlogin giving you same current working directory.
+ (Compare to telnet-cwd and xrlogin.)
+ robohunt - plays the game of hunt (from Berkeley).
+ It's more of a wild player than good, but amusing to watch.
+ Fun to throw against people who don't know about it.
+ rogue.exp - finds a good game of rogue.
+ rftp - recursive ftp (assumes UNIX-style ftpd at other end).
+ a s-key-rlogin - Automate rlogin (or telnet) using s/key
+ a scripttoggle - Like UNIX script command, but allow enabling/disabling
+ of recording.
+ a slip.shar - scripts to keep your SLIP link alive.
+ su.exp - start up an 'su' and run the argument.
+ telnet-cwd - telnet giving you same current working directory.
+ telnet-in-bg - put telnet (or any program) in bg, saving all remaining
+ output to a logfile.
+ a term-rlogin - run Term over rlogin. Good for traversing PPP/SLIP or
+ firewall rlogin connections.
+ a term-start - start up Term (a sophisticated UNIX-to-UNIX serial line
+ handler).
+ a timed-choice - offer user a timed choice of responses.
+ timed-read - a timed read for the shell, Perl, etc. Compare with
+ reprompt example.
+ m timed-run - run a program for only a given amount of time.
+ a try-phone-list - automate logging in to remote system, trying numbers
+ from a list until finding one that works.
+ m unbuffer - disables output buffering that normally occurs when
+ programs are redirected.
+ virterm - example of terminal emulation and expect operations on
+ character graphics using arrays (compare to term_expect
+ (below) which uses Tk widget).
+ vrfy - verifies an email address using SMTP/VRFY to remote site.
+ a waste-collection - Contact NIST service for hazardous waste pickup.
+ weather - retrieves weather forecasts.
+ m xkibitz - similar to kibitz but uses X Window System for handling
+ communication. Also, allows users to be added dynamically.
+ xrlogin - rlogin giving you same DISPLAY. (Compare to rlogin-cwd.)
+
+To run, for example, chess.exp, type:
+
+ expect chess.exp
+
+If expect is installed and your system supports the #! magic you can
+invoke it as:
+
+ chess.exp
+
+Each of these examples necessarily depends upon other binaries in the
+system. For example, chess.exp depends upon the "usual" UNIX chess
+program being present. If any of these programs are different,
+it may cause the associated script to misbehave.
+
+Please use the ".exp" extension on scripts that might otherwise have
+names that could be confused with the real program, such as "rogue.exp".
+Scripts that have unique names do not need the extension, such as "rftp".
+
+--------------------
+Sample Expectk scripts
+--------------------
+Entries marked with "m" have their own man page.
+
+ term_expect - template for doing expect operations on character
+ graphics.
+ m tknewsbiff - pops up a window (or plays sounds, etc) when news
+ arrives in selected newsgroups.
+ tkpasswd - Tk GUI for changing passwords.
+ tkterm - Tk terminal emulator in a Tk text widget.
+ xpstat - provide an X window front end to the xpilot game.
+
+--------------------
+Sample C and C++ programs that use the Expect library
+--------------------
+
+ chesslib.c - same thing as chess.exp, but in C.
+ chesslib2.c - ditto, but uses popen and stream-style I/O.
+ chesslib++.c - ditto, but for C++.
+ m unbuffer.c - same as unbuffer example but standalone
+
+You may change the value of CC or CPLUSPLUS in the Makefile, to
+compile under gcc or other compilers. However, you may have to edit
+the lines defining where the libraries are.
+
diff --git a/expect/example/archie b/expect/example/archie
new file mode 100755
index 00000000000..c3d3ece3e0e
--- /dev/null
+++ b/expect/example/archie
@@ -0,0 +1,36 @@
+#!../expect -f
+
+# archie
+
+# Log in to the archie ftp-catalog at McGill University, and mail back results
+# Brian P. Fitzgerald
+# Department of Mechanical Engineering
+# Rensselaer Polytechnic Institute
+
+set CINTR \003 ;# ^C
+set CSUSP \032 ;# ^Z
+
+set timeout -1
+spawn telnet quiche.cs.mcgill.ca
+
+expect_after eof exit ;# archie logs us out if too many people are logged in
+
+expect {
+ login: {send archie\r}
+ "unknown" {exit 1}
+ "unreachable" {exit 1}
+}
+
+expect "archie>" {send "set pager\r"}
+expect "archie>" {send "set maxhits 20\r"}
+expect "archie>" {send "set term vt100\r"}
+expect "archie>" {send "set sortby time\r"}
+expect "archie>" {
+ send "set mailto [exec whoami]@[exec hostname].[exec domainname]\r"
+}
+
+send_user "type ^C to exit, ^Z to suspend\n"
+interact {
+ -reset $CSUSP {exec kill -STOP [pid]}
+ $CINTR {exit 0}
+}
diff --git a/expect/example/autoexpect b/expect/example/autoexpect
new file mode 100755
index 00000000000..ea4f1522ee6
--- /dev/null
+++ b/expect/example/autoexpect
@@ -0,0 +1,347 @@
+#!../expect --
+# Name: autoexpect - generate an Expect script from watching a session
+#
+# Description:
+#
+# Given a program name, autoexpect will run that program. Otherwise
+# autoexpect will start a shell. Interact as desired. When done, exit
+# the program or shell. Autoexpect will create a script that reproduces
+# your interactions. By default, the script is named script.exp.
+# See the man page for more info.
+#
+# Author: Don Libes, NIST
+# Date: June 30 1995
+# Version: 1.4b
+
+set filename "script.exp"
+set verbose 1
+set conservative 0
+set promptmode 0
+set option_keys ""
+
+proc check_for_following {type} {
+ if ![llength [uplevel set argv]] {
+ puts "autoexpect: [uplevel set flag] requires following $type"
+ exit 1
+ }
+}
+
+while {[llength $argv]>0} {
+ set flag [lindex $argv 0]
+ if 0==[regexp "^-" $flag] break
+ set argv [lrange $argv 1 end]
+ switch -- $flag \
+ "-c" {
+ set conservative 1
+ } "-C" {
+ check_for_following character
+ lappend option_keys [lindex $argv 0] ctoggle
+ set argv [lrange $argv 1 end]
+ } "-p" {
+ set promptmode 1
+ } "-P" {
+ check_for_following character
+ lappend option_keys [lindex $argv 0] ptoggle
+ set argv [lrange $argv 1 end]
+ } "-Q" {
+ check_for_following character
+ lappend option_keys [lindex $argv 0] quote
+ set argv [lrange $argv 1 end]
+ } "-f" {
+ check_for_following filename
+ set filename [lindex $argv 0]
+ set argv [lrange $argv 1 end]
+ } "-quiet" {
+ set verbose 0
+ } default {
+ break
+ }
+}
+
+#############################################################
+# Variables Descriptions
+#############################################################
+# userbuf buffered characters from user
+# procbuf buffered characters from process
+# lastkey last key pressed by user
+# if undefined, last key came from process
+# echoing if the process is echoing
+#############################################################
+
+# Handle a character that came from user input (i.e., the keyboard)
+proc input {c} {
+ global userbuf lastkey
+
+ send -- $c
+ append userbuf $lastkey
+ set lastkey $c
+}
+
+# Handle a null character from the keyboard
+proc input_null {} {
+ global lastkey userbuf procbuf echoing
+
+ send -null
+
+ if {$lastkey == ""} {
+ if $echoing {
+ sendcmd "$userbuf"
+ }
+ if {$procbuf != ""} {
+ expcmd "$procbuf"
+ }
+ } else {
+ sendcmd "$userbuf"
+ if $echoing {
+ expcmd "$procbuf"
+ sendcmd "$lastkey"
+ }
+ }
+ cmd "send -null"
+ set userbuf ""
+ set procbuf ""
+ set lastkey ""
+ set echoing 0
+}
+
+# Handle a character that came from the process
+proc output {s} {
+ global lastkey procbuf userbuf echoing
+
+ send_user -raw -- $s
+
+ if {$lastkey == ""} {
+ if !$echoing {
+ append procbuf $s
+ } else {
+ sendcmd "$userbuf"
+ expcmd "$procbuf"
+ set echoing 0
+ set userbuf ""
+ set procbuf $s
+ }
+ return
+ }
+
+ regexp (.)(.*) $s dummy c tail
+ if {$c == $lastkey} {
+ if $echoing {
+ append userbuf $lastkey
+ set lastkey ""
+ } else {
+ if {$procbuf != ""} {
+ expcmd "$procbuf"
+ set procbuf ""
+ }
+ set echoing 1
+ }
+ append procbuf $s
+
+ if [string length $tail] {
+ sendcmd "$userbuf$lastkey"
+ set userbuf ""
+ set lastkey ""
+ set echoing 0
+ }
+ } else {
+ if !$echoing {
+ expcmd "$procbuf"
+ }
+ sendcmd "$userbuf$lastkey"
+ set procbuf $s
+ set userbuf ""
+ set lastkey ""
+ set echoing 0
+ }
+}
+
+# rewrite raw strings so that can appear as source code but still reproduce
+# themselves.
+proc expand {s} {
+ regsub -all "\\\\" $s "\\\\\\\\" s
+ regsub -all "\r" $s "\\r" s
+ regsub -all "\"" $s "\\\"" s
+ regsub -all "\\\[" $s "\\\[" s
+ regsub -all "\\\]" $s "\\\]" s
+ regsub -all "\\\$" $s "\\\$" s
+
+ return $s
+}
+
+# generate an expect command
+proc expcmd {s} {
+ global promptmode
+
+ if $promptmode {
+ regexp ".*\[\r\n]+(.*)" $s dummy s
+ }
+
+ cmd "expect -exact \"[expand $s]\""
+}
+
+# generate a send command
+proc sendcmd {s} {
+ global send_style conservative
+
+ if {$conservative} {
+ cmd "sleep .1"
+ }
+
+ cmd "send$send_style -- \"[expand $s]\""
+}
+
+# generate any command
+proc cmd {s} {
+ global fd
+ puts $fd "$s"
+}
+
+proc verbose_send_user {s} {
+ global verbose
+
+ if $verbose {
+ send_user -- $s
+ }
+}
+
+proc ctoggle {} {
+ global conservative send_style
+
+ if $conservative {
+ cmd "# conservative mode off - adding no delays"
+ verbose_send_user "conservative mode off\n"
+ set conservative 0
+ set send_style ""
+ } else {
+ cmd "# prompt mode on - adding delays"
+ verbose_send_user "conservative mode on\n"
+ set conservative 1
+ set send_style " -s"
+ }
+}
+
+proc ptoggle {} {
+ global promptmode
+
+ if $promptmode {
+ cmd "# prompt mode off - now looking for complete output"
+ verbose_send_user "prompt mode off\n"
+ set promptmode 0
+ } else {
+ cmd "# prompt mode on - now looking only for prompts"
+ verbose_send_user "prompt mode on\n"
+ set promptmode 1
+ }
+}
+
+# quote the next character from the user
+proc quote {} {
+ expect_user -re .
+ send -- $expect_out(buffer)
+}
+
+
+if [catch {set fd [open $filename w]} msg] {
+ puts $msg
+ exit
+}
+exec chmod +x $filename
+verbose_send_user "autoexpect started, file is $filename\n"
+
+# calculate a reasonable #! line
+set expectpath /usr/local/bin ;# prepare default
+foreach dir [split $env(PATH) :] { ;# now look for real location
+ if [file executable $dir/expect] {
+ set expectpath $dir
+ break
+ }
+}
+
+cmd "#![set expectpath]/expect -f
+#
+# This Expect script was generated by autoexpect on [timestamp -format %c]
+# Expect and autoexpect were both written by Don Libes, NIST."
+cmd {#
+# Note that autoexpect does not guarantee a working script. It
+# necessarily has to guess about certain things. Two reasons a script
+# might fail are:
+#
+# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
+# etc.) and devices discard or ignore keystrokes that arrive "too
+# quickly" after prompts. If you find your new script hanging up at
+# one spot, try adding a short sleep just before the previous send.
+# Setting "force_conservative" to 1 (see below) makes Expect do this
+# automatically - pausing briefly before sending each character. This
+# pacifies every program I know of. The -c flag makes the script do
+# this in the first place. The -C flag allows you to define a
+# character to toggle this mode off and on.
+
+set force_conservative 0 ;# set to 1 to force conservative mode even if
+ ;# script wasn't run conservatively originally
+if {$force_conservative} {
+ set send_slow {1 .1}
+ proc send {ignore arg} {
+ sleep .1
+ exp_send -s -- $arg
+ }
+}
+
+#
+# 2) differing output - Some programs produce different output each time
+# they run. The "date" command is an obvious example. Another is
+# ftp, if it produces throughput statistics at the end of a file
+# transfer. If this causes a problem, delete these patterns or replace
+# them with wildcards. An alternative is to use the -p flag (for
+# "prompt") which makes Expect only look for the last line of output
+# (i.e., the prompt). The -P flag allows you to define a character to
+# toggle this mode off and on.
+#
+# Read the man page for more info.
+#
+# -Don
+
+}
+
+cmd "set timeout -1"
+if $conservative {
+ set send_style " -s"
+ cmd "set send_slow {1 .1}"
+} else {
+ set send_style ""
+}
+
+if [llength $argv]>0 {
+ eval spawn -noecho $argv
+ cmd "spawn $argv"
+} else {
+ spawn -noecho $env(SHELL)
+ cmd "spawn \$env(SHELL)"
+}
+
+cmd "match_max 100000"
+
+set lastkey ""
+set procbuf ""
+set userbuf ""
+set echoing 0
+
+remove_nulls 0
+
+eval interact $option_keys {
+ -re . {
+ input $interact_out(0,string)
+ } null {
+ input_null
+ } \
+ -o \
+ -re .+ {
+ output $interact_out(0,string)
+ } eof {
+ cmd "expect eof"
+ return
+ } null {
+ }
+}
+
+close $fd
+verbose_send_user "autoexpect done, file is $filename\n"
diff --git a/expect/example/autoexpect.man b/expect/example/autoexpect.man
new file mode 100644
index 00000000000..45f24a4007d
--- /dev/null
+++ b/expect/example/autoexpect.man
@@ -0,0 +1,207 @@
+.TH AUTOEXPECT 1 "30 June 1995"
+.SH NAME
+autoexpect \- generate an Expect script from watching a session
+.SH SYNOPSIS
+.B autoexpect
+[
+.I args
+]
+[
+.I program args...
+]
+.br
+.SH INTRODUCTION
+
+autoexpect watches you interacting with another program and creates an
+Expect script that reproduces your interactions. For straightline
+scripts, autoexpect saves substantial time over writing scripts by
+hand. Even if you are an Expect expert, you will find it convenient
+to use autoexpect to automate the more mindless parts of interactions.
+It is much easier to cut/paste hunks of autoexpect scripts together
+than to write them from scratch. And if you are a beginner, you may
+be able to get away with learning nothing more about Expect than how
+to call autoexpect.
+
+The simplest way to use autoexpect is to call it from the command line
+with no arguments. For example:
+
+ % autoexpect
+
+By default, autoexpect spawns a shell for you. Given a program name
+and arguments, autoexpect spawns that program. For example:
+
+ % autoexpect ftp ftp.cme.nist.gov
+
+Once your spawned program is running, interact normally. When you
+have exited the shell (or program that you specified), autoexpect will
+create a new script for you. By default, autoexpect writes the new
+script to "script.exp". You can override this with the \-f flag
+followed by a new script name.
+
+The following example runs "ftp ftp.cme.nist.gov" and stores the
+resulting Expect script in the file "nist".
+.nf
+
+ % autoexpect \-f nist ftp ftp.cme.nist.gov
+
+.fi
+It is important to understand that
+autoexpect does not guarantee a working script because it necessarily
+has to guess about certain things \- and occasionally it guesses wrong.
+However, it is usually very easy to identify and fix these problems.
+The typical problems are:
+.RS
+.TP 4
+\(bu
+Timing. A surprisingly large number of programs (rn, ksh, zsh,
+telnet, etc.) and devices (e.g., modems) ignore keystrokes that arrive
+"too quickly" after prompts. If you find your new script hanging up
+at one spot, try adding a short sleep just before the previous send.
+
+You can force this behavior throughout by overriding the variable
+"force_conservative" near the beginning of the generated script. This
+"conservative" mode makes autoexpect automatically pause briefly (one
+tenth of a second) before sending each character. This pacifies every
+program I know of.
+
+This conservative mode is useful if you just want to quickly reassure
+yourself that the problem is a timing one (or if you really don't care
+about how fast the script runs). This same mode can be forced before
+script generation by using the \-c flag.
+
+Fortunately, these timing spots are rare. For example, telnet ignores
+characters only after entering its escape sequence. Modems only
+ignore characters immediately after connecting to them for the first
+time. A few programs exhibit this behavior all the time but typically
+have a switch to disable it. For example, rn's \-T flag disables this
+behavior.
+
+The following example starts autoexpect in conservative
+mode.
+.nf
+
+ autoexpect \-c
+
+.fi
+The \-C flag defines a key to toggle conservative mode.
+The following example starts autoexpect (in non-conservative
+mode) with ^L as the toggle. (Note that the ^L is
+entered literally - i.e., enter a real control-L).
+.nf
+
+ autoexpect \-C ^L
+
+.fi
+The following example starts autoexpect in conservative
+mode with ^L as the toggle.
+.nf
+
+ autoexpect \-c \-C ^L
+
+.fi
+.TP
+\(bu
+Echoing. Many program echo characters. For example, if you type
+"more" to a shell, what autoexpect actually sees is:
+.nf
+
+ you typed 'm',
+ computer typed 'm',
+ you typed 'o',
+ computer typed 'o',
+ you typed 'r',
+ computer typed 'r',
+ ...
+.fi
+
+Without specific knowledge of the program, it is impossible to know if
+you are waiting to see each character echoed before typing the next.
+If autoexpect sees characters being echoed, it assumes that it can
+send them all as a group rather than interleaving them the way they
+originally appeared. This makes the script more pleasant to read.
+However, it could conceivably be incorrect if you really had to wait
+to see each character echoed.
+
+.TP
+\(bu
+Change. Autoexpect records every character from the interaction in
+the script. This is desirable because it gives you the ability to
+make judgements about what is important and what can be replaced with
+a pattern match.
+
+On the other hand, if you use commands whose output differs from run
+to run, the generated scripts are not going to be correct. For
+example, the "date" command always produces different output. So
+using the date command while running autoexpect is a sure way to
+produce a script that will require editing in order for it to work.
+
+The \-p flag puts autoexpect into "prompt mode". In this mode,
+autoexpect will only look for the the last line of program output \-
+which is usually the prompt. This handles the date problem (see
+above) and most others.
+
+The following example starts autoexpect in prompt mode.
+.nf
+
+ autoexpect \-p
+
+.fi
+The \-P flag defines a key to toggle prompt mode. The following
+example starts autoexpect (in non-prompt mode) with ^P as the toggle.
+Note that the ^P is entered literally - i.e., enter a real control-P.
+.nf
+
+ autoexpect \-P ^P
+
+.fi
+The following example starts autoexpect in prompt mode with ^P as the toggle.
+.nf
+
+ autoexpect \-p \-P ^P
+
+.fi
+.SH OTHER FLAGS
+The
+.B \-quiet
+flag disables informational messages produced by autoexpect.
+
+The
+.B \-Q
+flag names a quote character which can be used to enter characters
+that autoexpect would otherwise consume because they are used as toggles.
+
+The following example shows a number of flags with quote used to
+provide a way of entering the toggles literally.
+.nf
+
+ autoexpect \-P ^P \-C ^L \-Q ^Q
+
+.fi
+.SH STYLE
+
+I don't know if there is a "style" for Expect programs but autoexpect
+should definitely not be held up as any model of style. For example,
+autoexpect uses features of Expect that are intended specifically for
+computer-generated scripting. So don't try to faithfully write
+scripts that appear as if they were generated by autoexpect. This is
+not useful.
+
+On the other hand, autoexpect scripts do show some worthwhile things.
+For example, you can see how any string must be quoted in order to use
+it in a Tcl script simply by running the strings through autoexpect.
+
+.SH SEE ALSO
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
+
+.B expect
+and
+.B autoexpect
+are in the public domain.
+NIST and I would
+appreciate credit if these programs or parts of them are used.
+
diff --git a/expect/example/autopasswd b/expect/example/autopasswd
new file mode 100755
index 00000000000..f1b812dc759
--- /dev/null
+++ b/expect/example/autopasswd
@@ -0,0 +1,11 @@
+#!../expect -f
+# wrapper to make passwd(1) be non-interactive
+# username is passed as 1st arg, passwd as 2nd
+
+set password [lindex $argv 1]
+spawn passwd [lindex $argv 0]
+expect "password:"
+send "$password\r"
+expect "password:"
+send "$password\r"
+expect eof
diff --git a/expect/example/beer.exp b/expect/example/beer.exp
new file mode 100755
index 00000000000..7142d09f52f
--- /dev/null
+++ b/expect/example/beer.exp
@@ -0,0 +1,116 @@
+#!/depot/path/expect -f
+
+# 99 bottles of beer on the wall, Expect-style
+# Author: Don Libes <libes@nist.gov>
+
+# Unlike programs (http://www.ionet.net/~timtroyr/funhouse/beer.html)
+# which merely print out the 99 verses, this one SIMULATES a human
+# typing the beer song. Like a real human, typing mistakes and timing
+# becomes more erratic with each beer - the final verse is barely
+# recognizable and it is really like watching a typist hunt and peck
+# while drunk.
+
+# Finally, no humans actually sing all 99 verses - particularly when
+# drunk. In reality, they occasionally lose their place (or just get
+# bored) and skip verses, so this program does likewise.
+
+# Because the output is timed, just looking at the output isn't enough
+# - you really have to see the program running to appreciate it.
+# Nonetheless, for convenience, output from one run (it's different
+# every time of course) can be found in the file beer.exp.out
+# But it won't show the erratic timing; you have to run it for that.
+
+# For an even fancier version, see http://expect.nist.gov/scripts/superbeer.exp
+
+proc bottles {i} {
+ return "$i bottle[expr $i!=1?"s":""] of beer"
+}
+
+proc line123 {i} {
+ out $i "[bottles $i] on the wall,\n"
+ out $i "[bottles $i],\n"
+ out $i "take one down, pass it around,\n"
+}
+
+proc line4 {i} {
+ out $i "[bottles $i] on the wall.\n\n"
+}
+
+proc out {i s} {
+ foreach c [split $s ""] {
+ # don't touch punctuation; just looks too strange if you do
+ if [regexp "\[,. \n\]" $c] {
+ append d $c
+ continue
+ }
+
+ # keep first couple of verses straight
+ if {$i > 97} {append d $c; continue}
+
+ # +3 prevents it from degenerating too far
+ # /2 makes it degenerate faster though
+
+ set r [rand [expr $i/2+3]]
+ if {$r} {append d $c; continue}
+
+ # do something strange
+ switch [rand 3] {
+ 0 {
+ # substitute another letter
+
+ if [regexp \[aeiou\] $c] {
+ # if vowel, substitute another
+ append d [string index aeiou [rand 5]]
+ } elseif [regexp \[0-9\] $c] {
+ # if number, substitute another
+ append d [string index 123456789 [rand 9]]
+ } else {
+ # if consonant, substitute another
+ append d [string index bcdfghjklmnpqrstvwxyz [rand 21]]
+ }
+ } 1 {
+ # duplicate a letter
+ append d $c$c
+ } 2 {
+ # drop a letter
+ }
+ }
+ }
+
+ set arr1 [expr .4 - ($i/333.)]
+ set arr2 [expr .6 - ($i/333.)]
+ set shape [expr log(($i+2)/2.)+.1]
+ set min 0
+ set max [expr 6-$i/20.]
+
+ set send_human "$arr1 $arr2 $shape $min $max"
+
+ send -h $d
+}
+
+set _ran [pid]
+
+proc rand {m} {
+ global _ran
+
+ set period 259200
+ set _ran [expr ($_ran*7141 + 54773) % $period]
+ expr int($m*($_ran/double($period)))
+}
+
+for {set i 99} {$i>0} {} {
+ line123 $i
+ incr i -1
+ line4 $i
+
+ # get bored and skip ahead
+ if {$i == 92} {
+ set i [expr 52+[rand 5]]
+ }
+ if {$i == 51} {
+ set i [expr 12+[rand 5]]
+ }
+ if {$i == 10} {
+ set i [expr 6+[rand 3]]
+ }
+}
diff --git a/expect/example/beer.exp.out b/expect/example/beer.exp.out
new file mode 100644
index 00000000000..768e58e67e8
--- /dev/null
+++ b/expect/example/beer.exp.out
@@ -0,0 +1,119 @@
+99 bottles of beer on the wall,
+99 bottles of beer,
+take one down, pass it around,
+98 bottles of beer on the wall.
+
+98 bottles of beer on the wall,
+98 bottles of beer,
+take one down, pass it around,
+97 bottles of beer on the wall.
+
+97 bottles of beer on the wadl,
+97 bottles of beer,
+take one down, pass it around,
+96 bottles of beer on the wall.
+
+96 bottlees of beer on the wall,
+96 bowtles of beer,
+take one down, piss it around,
+95 bottles of beer on the salll.
+
+95 bottles of ber on the wall,
+95 qottles of beer,
+take one down, pass it around,
+94 bottles of beeer on the wall.
+
+94 ottles ef beer on the wall,
+94 bottles of beer,
+take one down, pass it around,
+93 bottles of beer n the wall.
+
+93 bottles of beer on the wall,
+93 bottles of beer,
+take one sown, pass it ajound,
+92 bottles of beer on the wall.
+
+56 bottles of beer on the wwall,
+56 bottles of beer,
+ake ne down, pass it around,
+55 bottles oof beer on the wall.
+
+55 bottles of beer on the wall,
+55 bottles if beer,
+take one down, pass it around,
+54 bottles of beer on the wall.
+
+54 bottles of beer on the wall,
+54 bottles of beer,
+take one dow, bass it around,
+53 bottes of beer on the wall.
+
+53 bottlef of beer on the wall,
+53 bottles of beer,
+tke one down, pas t around,
+52 bottles of beer on the wall.
+
+52 bottless o beer on the wall,
+52 botttles of beer,
+take one down, pass it round,
+51 bottles of beer on the all.
+
+114 bottles of ber on the wall,
+14 botles of ber,
+taakee one ddown, pass it around,
+13 bottles of beeer on the wakl.
+
+13 bottles of beer on tth wall,
+1 yottles of beer,
+take one down, xass it around,
+12 botles ooff beer on the walll.
+
+12 bottttqes of beer oon the wall,
+12 bttles oof beer,
+take one down, pass it around,
+11 boottles of beer on the wall.
+
+11 botttles of beer on the all,
+1 otttles of beer,
+tae one duwn, ppess it around,
+10 bottlos of beer on the wall.
+
+8 bottles of beer on thee wwall,
+8 bottles oof eer,
+taxe onne doown, pass iz aaroind,
+77 botttles f beer on nhe wall.
+
+7 bbottes of beer on the wlll,
+7 bomtles of beer,
+ake onee dwn, pass it around,
+6 bottles of beer on the ral.
+
+6 botttles of berr on the wal,
+6 bottles oof beer,
+take onee donn, pas it arouund,
+5 bottles of beer oq the wall.
+
+ bottles f beer on the walll,
+5 botttlees of meer,
+take one down, passs it aroundd,
+4 boothles of beer n thhe wall.
+
+6 botyles of boer n the lll,
+4 bottles i beer,
+take one down, pass i aarounnd,
+3 bbotlos of bbeir iy te wall.
+
+ bottles off ee on the wall,
+3 buttes of bbeer,
+take one dooxn, pass il rround,
+3 bottles oof ber on tthe wall.
+
+2 bottle uf er ooc the tall,
+2 bettles ok beear,
+taka onu doowy, pesss itt arond,
+1 botjllee off beer i thh walll.
+
+11 botqle off baer oc tbe wakl,
+1 botplo of beer,
+take onne da, pass itt arounm,
+0 yotglees oof beeeer on tte walll.
diff --git a/expect/example/beer.out b/expect/example/beer.out
new file mode 100644
index 00000000000..768e58e67e8
--- /dev/null
+++ b/expect/example/beer.out
@@ -0,0 +1,119 @@
+99 bottles of beer on the wall,
+99 bottles of beer,
+take one down, pass it around,
+98 bottles of beer on the wall.
+
+98 bottles of beer on the wall,
+98 bottles of beer,
+take one down, pass it around,
+97 bottles of beer on the wall.
+
+97 bottles of beer on the wadl,
+97 bottles of beer,
+take one down, pass it around,
+96 bottles of beer on the wall.
+
+96 bottlees of beer on the wall,
+96 bowtles of beer,
+take one down, piss it around,
+95 bottles of beer on the salll.
+
+95 bottles of ber on the wall,
+95 qottles of beer,
+take one down, pass it around,
+94 bottles of beeer on the wall.
+
+94 ottles ef beer on the wall,
+94 bottles of beer,
+take one down, pass it around,
+93 bottles of beer n the wall.
+
+93 bottles of beer on the wall,
+93 bottles of beer,
+take one sown, pass it ajound,
+92 bottles of beer on the wall.
+
+56 bottles of beer on the wwall,
+56 bottles of beer,
+ake ne down, pass it around,
+55 bottles oof beer on the wall.
+
+55 bottles of beer on the wall,
+55 bottles if beer,
+take one down, pass it around,
+54 bottles of beer on the wall.
+
+54 bottles of beer on the wall,
+54 bottles of beer,
+take one dow, bass it around,
+53 bottes of beer on the wall.
+
+53 bottlef of beer on the wall,
+53 bottles of beer,
+tke one down, pas t around,
+52 bottles of beer on the wall.
+
+52 bottless o beer on the wall,
+52 botttles of beer,
+take one down, pass it round,
+51 bottles of beer on the all.
+
+114 bottles of ber on the wall,
+14 botles of ber,
+taakee one ddown, pass it around,
+13 bottles of beeer on the wakl.
+
+13 bottles of beer on tth wall,
+1 yottles of beer,
+take one down, xass it around,
+12 botles ooff beer on the walll.
+
+12 bottttqes of beer oon the wall,
+12 bttles oof beer,
+take one down, pass it around,
+11 boottles of beer on the wall.
+
+11 botttles of beer on the all,
+1 otttles of beer,
+tae one duwn, ppess it around,
+10 bottlos of beer on the wall.
+
+8 bottles of beer on thee wwall,
+8 bottles oof eer,
+taxe onne doown, pass iz aaroind,
+77 botttles f beer on nhe wall.
+
+7 bbottes of beer on the wlll,
+7 bomtles of beer,
+ake onee dwn, pass it around,
+6 bottles of beer on the ral.
+
+6 botttles of berr on the wal,
+6 bottles oof beer,
+take onee donn, pas it arouund,
+5 bottles of beer oq the wall.
+
+ bottles f beer on the walll,
+5 botttlees of meer,
+take one down, passs it aroundd,
+4 boothles of beer n thhe wall.
+
+6 botyles of boer n the lll,
+4 bottles i beer,
+take one down, pass i aarounnd,
+3 bbotlos of bbeir iy te wall.
+
+ bottles off ee on the wall,
+3 buttes of bbeer,
+take one dooxn, pass il rround,
+3 bottles oof ber on tthe wall.
+
+2 bottle uf er ooc the tall,
+2 bettles ok beear,
+taka onu doowy, pesss itt arond,
+1 botjllee off beer i thh walll.
+
+11 botqle off baer oc tbe wakl,
+1 botplo of beer,
+take onne da, pass itt arounm,
+0 yotglees oof beeeer on tte walll.
diff --git a/expect/example/carpal b/expect/example/carpal
new file mode 100644
index 00000000000..0ebc225a007
--- /dev/null
+++ b/expect/example/carpal
@@ -0,0 +1,26 @@
+# Script to enforce a 10 minute break every half hour from typing -
+# Written for someone (Uwe Hollerbach) with Carpal Tunnel Syndrome.
+
+# If you type for more than 20 minutes straight, the script rings
+# the bell after every character until you take a 10 minute break.
+
+# Author: Don Libes, NIST
+# Date: Feb 26, '95
+
+spawn $env(SHELL)
+set start [timestamp] ;# when we started our current typing period
+set stop [timestamp] ;# when we stopped typing
+
+set typing 1200 ;# twenty minutes, max typing time allowed
+set notyping 600 ;# ten minutes, min notyping time required
+
+interact -nobuffer -re . {
+ set now [timestamp]
+
+ if {$now-$stop > $notyping} {
+ set start [timestamp]
+ } elseif {$now-$start > $typing} {
+ send_user "\007"
+ }
+ set stop [timestamp]
+}
diff --git a/expect/example/chess.exp b/expect/example/chess.exp
new file mode 100755
index 00000000000..2729ec4caba
--- /dev/null
+++ b/expect/example/chess.exp
@@ -0,0 +1,52 @@
+#!../expect -f
+# expect script to connect two UNIX chess programs together.
+# written by Don Libes - May 9, 1990
+
+# Note, this depends on the "usual" UNIX chess output. Other chess programs
+# will almost certainly not work.
+
+# Moves and counter-moves are printed out in different formats, sigh...
+# But I guess that's what makes this Expect script challenging to write.
+# In particular, the 1st player outputs:
+#
+# p/k2-k4 (echo from 2nd player)
+# 1. ... p/k2-k4 (reprint it with a number in front - god knows why)
+# 2. n/kn1-kb3 (our new move)
+#
+# and the 2nd player outputs the following
+#
+# n/kn1-kb3 (echo from first player)
+# 2. n/kn1-kb3 (reprint it as above, but differently - god knows why)
+# 2. ... p/k4-k5 (our new countermove - written differently, of course)
+
+set timeout -1; # wait forever
+expect_before {
+ -i $any_spawn_id eof {
+ send_user "player resigned!\n"
+ exit
+ }
+}
+
+# start things rolling
+spawn chess
+set id1 $spawn_id
+expect "Chess\r\n"
+send "first\r"
+# read_first_move
+expect -re "1. (.*)\n"
+
+spawn chess
+set id2 $spawn_id
+expect "Chess\r\n"
+send $expect_out(1,string)
+
+for {} 1 {} {
+ expect {
+ -i $id2 -re "\\.\\. (.*)\n" {
+ send -i $id1 $expect_out(1,string)
+ }
+ -i $id1 -re "\\.\\. .*\\. (.*)\n" {
+ send -i $id2 $expect_out(1,string)
+ }
+ }
+}
diff --git a/expect/example/chesslib++.c b/expect/example/chesslib++.c
new file mode 100644
index 00000000000..0439791752b
--- /dev/null
+++ b/expect/example/chesslib++.c
@@ -0,0 +1,84 @@
+/* testlib.c for c++ - test expectlib */
+
+#include <stdio.h>
+#include "expect.h"
+
+extern "C" {
+ extern int write(...);
+ extern int strlen(...);
+}
+
+void
+timedout()
+{
+ fprintf(stderr,"timed out\n");
+ exit(-1);
+}
+
+char move[100];
+
+void
+read_first_move(int fd)
+{
+ if (EXP_TIMEOUT == exp_expectl(fd,exp_glob,"first\r\n1.*\r\n",0,exp_end)) {
+ timedout();
+ }
+ sscanf(exp_match,"%*s 1. %s",move);
+}
+
+/* moves and counter-moves are printed out in different formats, sigh... */
+
+void
+read_counter_move(int fd)
+{
+ switch (exp_expectl(fd,exp_glob,"*...*\r\n",0,exp_end)) {
+ case EXP_TIMEOUT: timedout();
+ case EXP_EOF: exit(-1);
+ }
+
+ sscanf(exp_match,"%*s %*s %*s %*s ... %s",move);
+}
+
+void
+read_move(int fd)
+{
+ switch (exp_expectl(fd,exp_glob,"*...*\r\n*.*\r\n",0,exp_end)) {
+ case EXP_TIMEOUT: timedout();
+ case EXP_EOF: exit(-1);
+ }
+
+ sscanf(exp_match,"%*s %*s ... %*s %*s %s",move);
+}
+
+void
+send_move(int fd)
+{
+ write(fd,move,strlen(move));
+}
+
+main(){
+ int fd1, fd2;
+
+ exp_loguser = 1;
+ exp_timeout = 3600;
+
+ fd1 = exp_spawnl("chess","chess",(char *)0);
+
+ if (-1 == exp_expectl(fd1,exp_glob,"Chess\r\n",0,exp_end)) exit;
+
+ if (-1 == write(fd1,"first\r",6)) exit;
+
+ read_first_move(fd1);
+
+ fd2 = exp_spawnl("chess","chess",(char *)0);
+
+ if (-1 == exp_expectl(fd2,exp_glob,"Chess\r\n",0,exp_end)) exit;
+
+ for (;;) {
+ send_move(fd2);
+ read_counter_move(fd2);
+
+ send_move(fd1);
+ read_move(fd1);
+ }
+}
diff --git a/expect/example/chesslib.c b/expect/example/chesslib.c
new file mode 100644
index 00000000000..35bf524bfa2
--- /dev/null
+++ b/expect/example/chesslib.c
@@ -0,0 +1,80 @@
+/* chesslib.c - test expectlib */
+
+#include <stdio.h>
+#include "expect.h"
+
+timedout()
+{
+ fprintf(stderr,"timed out\n");
+ exit(-1);
+}
+
+char move[100];
+
+read_first_move(fd)
+int fd;
+{
+ if (EXP_TIMEOUT == exp_expectl(fd,
+ exp_glob,"first\r\n1.*\r\n",0,
+ exp_end)) {
+ timedout();
+ }
+ sscanf(exp_match,"%*s 1. %s",move);
+}
+
+/* moves and counter-moves are printed out in different formats, sigh... */
+
+read_counter_move(fd)
+int fd;
+{
+ switch (exp_expectl(fd,exp_glob,"*...*\r\n",0,exp_end)) {
+ case EXP_TIMEOUT: timedout();
+ case EXP_EOF: exit(-1);
+ }
+
+ sscanf(exp_match,"%*s %*s %*s %*s ... %s",move);
+}
+
+read_move(fd)
+int fd;
+{
+ switch (exp_expectl(fd,exp_glob,"*...*\r\n*.*\r\n",0,exp_end)) {
+ case EXP_TIMEOUT: timedout();
+ case EXP_EOF: exit(-1);
+ }
+
+ sscanf(exp_match,"%*s %*s ... %*s %*s %s",move);
+}
+
+send_move(fd)
+int fd;
+{
+ write(fd,move,strlen(move));
+}
+
+main(){
+ int fd1, fd2;
+
+ exp_loguser = 1;
+ exp_timeout = 3600;
+
+ fd1 = exp_spawnl("chess","chess",(char *)0);
+
+ if (-1 == exp_expectl(fd1,exp_glob,"Chess\r\n",0,exp_end)) exit;
+
+ if (-1 == write(fd1,"first\r",6)) exit;
+
+ read_first_move(fd1);
+
+ fd2 = exp_spawnl("chess","chess",(char *)0);
+
+ if (-1 == exp_expectl(fd2,exp_glob,"Chess\r\n",0,exp_end)) exit;
+
+ for (;;) {
+ send_move(fd2);
+ read_counter_move(fd2);
+
+ send_move(fd1);
+ read_move(fd1);
+ }
+}
diff --git a/expect/example/chesslib2.c b/expect/example/chesslib2.c
new file mode 100644
index 00000000000..95f0f7d3340
--- /dev/null
+++ b/expect/example/chesslib2.c
@@ -0,0 +1,84 @@
+/* testlib.c - test expectlib */
+
+#include <stdio.h>
+#include "expect.h"
+
+timedout()
+{
+ fprintf(stderr,"timed out\n");
+ exit(-1);
+}
+
+char move[100];
+
+read_first_move(fp)
+FILE *fp;
+{
+ if (EXP_TIMEOUT == exp_fexpectl(fp,
+ exp_glob,"first\r\n1.*\r\n",0,
+ exp_end)) {
+ timedout();
+ }
+ sscanf(exp_match,"%*s 1. %s",move);
+}
+
+/* moves and counter-moves are printed out in different formats, sigh... */
+
+read_counter_move(fp)
+FILE *fp;
+{
+ switch (exp_fexpectl(fp,exp_glob,"*...*\r\n",0, exp_end)) {
+ case EXP_TIMEOUT: timedout();
+ case EXP_EOF: exit(-1);
+ }
+
+ sscanf(exp_match,"%*s %*s %*s %*s ... %s",move);
+}
+
+read_move(fp)
+FILE *fp;
+{
+ switch (exp_fexpectl(fp,exp_glob,"*...*\r\n*.*\r\n",0,exp_end)) {
+ case EXP_TIMEOUT: timedout();
+ case EXP_EOF: exit(-1);
+ }
+
+ sscanf(exp_match,"%*s %*s ... %*s %*s %s",move);
+}
+
+send_move(fp)
+FILE *fp;
+{
+ fprintf(fp,move);
+}
+
+main(){
+ FILE *fp1, *fp2;
+ int ec;
+
+/* exp_is_debugging = 1;*/
+ exp_loguser = 1;
+ exp_timeout = 3600;
+
+ if (0 == (fp1 = exp_popen("chess"))) {
+ printf("exp_popen failed\n");
+ exit(-1);
+ }
+
+ if (0 > exp_fexpectl(fp1,exp_glob,"Chess\r\n",0,exp_end)) exit(-1);
+ fprintf(fp1,"first\r");
+
+ read_first_move(fp1);
+
+ fp2 = exp_popen("chess");
+
+ exp_fexpectl(fp2,exp_glob,"Chess\r\n",0,exp_end);
+
+ for (;;) {
+ send_move(fp2);
+ read_counter_move(fp2);
+
+ send_move(fp1);
+ read_move(fp1);
+ }
+}
diff --git a/expect/example/cryptdir b/expect/example/cryptdir
new file mode 100755
index 00000000000..2512ece0d6f
--- /dev/null
+++ b/expect/example/cryptdir
@@ -0,0 +1,63 @@
+#!../expect --
+# Name: cryptdir
+# Author: Don Libes, NIST
+#
+# Synopsis:
+# cryptdir [dir]
+# decryptdir [dir]
+#
+# Encrypt or decrypts the current directory or named directory if given.
+
+if {[llength $argv] > 0} {
+ cd $argv
+}
+
+# encrypt or decrypt?
+set decrypt [regexp "decrypt" $argv0]
+
+set timeout -1
+stty -echo
+send "Password:"
+expect -re "(.*)\n"
+send "\n"
+set passwd $expect_out(1,string)
+
+# wouldn't want to encrypt files with mistyped password!
+if !$decrypt {
+ send "Again:"
+ expect -re "(.*)\n"
+ send "\n"
+ if ![string match $passwd $expect_out(1,string)] {
+ send_user "mistyped password?\n"
+ stty echo
+ exit
+ }
+}
+stty echo
+
+log_user 0
+foreach f [glob *] {
+ # strip shell metachars from filename to avoid problems
+ if [regsub -all {[]['`~<>:-]} $f "" newf] {
+ exec mv $f $newf
+ set f $newf
+ }
+
+ set strcmp [string compare .crypt [file extension $f]]
+ if $decrypt {
+ # skip files that don't end with ".crypt"
+ if 0!=$strcmp continue
+ spawn sh -c "exec crypt < $f > [file root $f]"
+ } else {
+ # skip files that already end with ".crypt"
+ if 0==$strcmp continue
+ spawn sh -c "exec crypt < $f > $f.crypt"
+ }
+ expect "key:"
+ send "$passwd\r"
+ expect
+ wait
+ exec rm -f $f
+ send_tty "."
+}
+send_tty "\n"
diff --git a/expect/example/cryptdir.man b/expect/example/cryptdir.man
new file mode 100644
index 00000000000..01fbdb2f2f3
--- /dev/null
+++ b/expect/example/cryptdir.man
@@ -0,0 +1,42 @@
+.TH CRYPTDIR 1 "1 January 1993"
+.SH NAME
+cryptdir \- encrypt/decrypt all files in a directory
+.SH SYNOPSIS
+.B cryptdir
+[
+.I dir
+]
+.br
+.B decryptdir
+[
+.I dir
+]
+.SH INTRODUCTION
+.B cryptdir
+encrypts all files in the current directory (or the given directory
+if one is provided as an argument). When called as decryptdir
+(i.e., same program, different name), all files are decrypted.
+
+.SH NOTES
+When encrypting, you are prompted twice for the password as a
+precautionary measure. It would be a disaster to encrypt files with a
+password that wasn't what you intended.
+
+In contrast, when decrypting, you are only prompted once. If it's the
+wrong password, no harm done.
+
+Encrypted files have the suffix .crypt appended. This prevents files
+from being encrypted twice. The suffix is removed upon decryption.
+Thus, you can easily add files to an encrypted directory and run
+cryptdir on it without worrying about the already encrypted files.
+.SH BUGS
+
+The man page is longer than the program.
+
+.SH SEE ALSO
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
diff --git a/expect/example/decryptdir b/expect/example/decryptdir
new file mode 100755
index 00000000000..9d9b93fd044
--- /dev/null
+++ b/expect/example/decryptdir
@@ -0,0 +1,63 @@
+#!../expect --
+# Name: cryptdir
+# Author: Don Libes, NIST
+#
+# Synopsis:
+# cryptdir [dir]
+# decryptdir [dir]
+#
+# Encrypt or decrypts the current directory or named directory if given.
+
+if {[llength $argv] > 0} {
+ cd $argv
+}
+
+# encrypt or decrypt?
+set decrypt [regexp "decrypt" $argv0]
+
+set timeout -1
+stty -echo
+send "Password:"
+expect -re "(.*)\n"
+send "\n"
+set passwd $expect_out(1,string)
+
+# wouldn't want to encrypt files with mistyped password!
+if !$decrypt {
+ send "Again:"
+ expect -re "(.*)\n"
+ send "\n"
+ if ![string match $passwd $expect_out(1,string)] {
+ send_user "mistyped password?"
+ stty echo
+ exit
+ }
+}
+stty echo
+
+log_user 0
+foreach f [glob *] {
+ # strip shell metachars from filename to avoid problems
+ if [regsub -all {[]['`~<>:-]} $f "" newf] {
+ exec mv $f $newf
+ set f $newf
+ }
+
+ set strcmp [string compare .crypt [file extension $f]]
+ if $decrypt {
+ # skip files that don't end with ".crypt"
+ if 0!=$strcmp continue
+ spawn sh -c "exec crypt < $f > [file root $f]"
+ } else {
+ # skip files that already end with ".crypt"
+ if 0==$strcmp continue
+ spawn sh -c "exec crypt < $f > $f.crypt"
+ }
+ expect "key:"
+ send "$passwd\r"
+ expect
+ wait
+ exec rm -f $f
+ send_tty "."
+}
+send_tty "\n"
diff --git a/expect/example/decryptdir.man b/expect/example/decryptdir.man
new file mode 100644
index 00000000000..683cb7a0b63
--- /dev/null
+++ b/expect/example/decryptdir.man
@@ -0,0 +1,42 @@
+.TH CRYPTDIR 1 "1 January 1993"
+.SH NAME
+cryptdir \- encrypt/decrypt all files in a directory
+.SH SYNOPSIS
+.B cryptdir
+[
+.I dir
+]
+.br
+.B decryptdir
+[
+.I dir
+]
+.SH INTRODUCTION
+.B cryptdir
+encrypts all files in the current directory (or the given directory
+if one is provided as an argument). When called as decryptdir
+(i.e., same program, different name), all files are decrypted.
+
+.SH NOTES
+When encrypting, you are prompted twice for the password as a
+precautionary measure. It would be a disaster to encrypt files a
+password that wasn't what you intended.
+
+In contrast, when decrypting, you are only prompted once. If it's the
+wrong password, no harm done.
+
+Encrypted files have the suffix .crypt appended. This prevents files
+from being encrypted twice. The suffix is removed upon decryption.
+Thus, you can easily add files to an encrypted directory and run
+cryptdir on it without worrying about the already encrypted files.
+.SH BUGS
+
+The man page is longer than the program.
+
+.SH SEE ALSO
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
diff --git a/expect/example/dislocate b/expect/example/dislocate
new file mode 100755
index 00000000000..eb271c9878c
--- /dev/null
+++ b/expect/example/dislocate
@@ -0,0 +1,342 @@
+#!../expect --
+# dislocate - allow disconnection and reconnection to a background program
+# Author: Don Libes, NIST
+
+exp_version -exit 5.1
+
+# The following code attempts to intuit whether cat buffers by default.
+# The -u flag is required on HPUX (8 and 9) and IBM AIX (3.2) systems.
+if [file exists $exp_exec_library/cat-buffers] {
+ set catflags "-u"
+} else {
+ set catflags ""
+}
+# If this fails, you can also force it by commenting in one of the following.
+# Or, you can use the -catu flag to the script.
+#set catflags ""
+#set catflags "-u"
+
+set escape \035 ;# control-right-bracket
+set escape_printable "^\]"
+
+set pidfile "~/.dislocate"
+set prefix "disc"
+set timeout -1
+set debug_flag 0
+
+while {$argc} {
+ set flag [lindex $argv 0]
+ switch -- $flag \
+ "-catu" {
+ set catflags "-u"
+ set argv [lrange $argv 1 end]
+ incr argc -1
+ } "-escape" {
+ set escape [lindex $argv 1]
+ set escape_printable $escape
+ set argv [lrange $argv 2 end]
+ incr argc -2
+ } "-debug" {
+ log_file [lindex $argv 1]
+ set debug_flag 1
+ set argv [lrange $argv 2 end]
+ incr argc -2
+ } default {
+ break
+ }
+}
+
+# These are correct from parent's point of view.
+# In child, we will reset these so that they appear backwards
+# thus allowing following two routines to be used by both parent and child
+set infifosuffix ".i"
+set outfifosuffix ".o"
+
+proc infifoname {pid} {
+ global prefix infifosuffix
+
+ return "/tmp/$prefix$pid$infifosuffix"
+}
+
+proc outfifoname {pid} {
+ global prefix outfifosuffix
+
+ return "/tmp/$prefix$pid$outfifosuffix"
+}
+
+proc pid_remove {pid} {
+ global date proc
+
+ say "removing $pid $proc($pid)"
+
+ unset date($pid)
+ unset proc($pid)
+}
+
+# lines in data file looks like this:
+# pid#date-started#argv
+
+# allow element lookups on empty arrays
+set date(dummy) dummy; unset date(dummy)
+set proc(dummy) dummy; unset proc(dummy)
+
+# load pidfile into memory
+proc pidfile_read {} {
+ global date proc pidfile
+
+ if [catch {open $pidfile} fp] return
+
+ #
+ # read info out of file
+ #
+
+ say "reading pidfile"
+ set line 0
+ while {[gets $fp buf]!=-1} {
+ # while pid and date can't have # in it, proc can
+ if [regexp "(\[^#]*)#(\[^#]*)#(.*)" $buf junk pid xdate xproc] {
+ set date($pid) $xdate
+ set proc($pid) $xproc
+ } else {
+ puts "warning: inconsistency in $pidfile line $line"
+ }
+ incr line
+ }
+ close $fp
+ say "read $line entries"
+
+ #
+ # see if pids and fifos are still around
+ #
+
+ foreach pid [array names date] {
+ if {$pid && [catch {exec /bin/kill -0 $pid}]} {
+ say "$pid no longer exists, removing"
+ pid_remove $pid
+ continue
+ }
+
+ # pid still there, see if fifos are
+ if {![file exists [infifoname $pid]] || ![file exists [outfifoname $pid]]} {
+ say "$pid fifos no longer exists, removing"
+ pid_remove $pid
+ continue
+ }
+ }
+}
+
+proc pidfile_write {} {
+ global pidfile date proc
+
+ say "writing pidfile"
+
+ set fp [open $pidfile w]
+ foreach pid [array names date] {
+ puts $fp "$pid#$date($pid)#$proc($pid)"
+ say "wrote $pid#$date($pid)#$proc($pid)"
+ }
+ close $fp
+}
+
+proc fifo_pair_remove {pid} {
+ global date proc prefix
+
+ pidfile_read
+ pid_remove $pid
+ pidfile_write
+
+ catch {exec rm -f [infifoname $pid] [outfifoname $pid]}
+}
+
+proc fifo_pair_create {pid argdate argv} {
+ global prefix date proc
+
+ pidfile_read
+ set date($pid) $argdate
+ set proc($pid) $argv
+ pidfile_write
+
+ mkfifo [infifoname $pid]
+ mkfifo [outfifoname $pid]
+}
+
+proc mkfifo {f} {
+ if [file exists $f] {
+ say "uh, fifo already exists?"
+ return
+ }
+
+ if 0==[catch {exec mkfifo $f}] return ;# POSIX
+ if 0==[catch {exec mknod $f p}] return
+ # some systems put mknod in wierd places
+ if 0==[catch {exec /usr/etc/mknod $f p}] return ;# Sun
+ if 0==[catch {exec /etc/mknod $f p}] return ;# AIX, Cray
+ puts "Couldn't figure out how to make a fifo - where is mknod?"
+ exit
+}
+
+proc child {argdate argv} {
+ global catflags infifosuffix outfifosuffix
+
+ disconnect
+
+ # these are backwards from the child's point of view so that
+ # we can make everything else look "right"
+ set infifosuffix ".o"
+ set outfifosuffix ".i"
+ set pid 0
+
+ eval spawn $argv
+ set proc_spawn_id $spawn_id
+
+ while {1} {
+ say "opening [infifoname $pid] for read"
+ spawn -open [open "|cat $catflags < [infifoname $pid]" "r"]
+ set in $spawn_id
+
+ say "opening [outfifoname $pid] for write"
+ spawn -open [open [outfifoname $pid] w]
+ set out $spawn_id
+
+ fifo_pair_remove $pid
+
+ say "interacting"
+ interact {
+ -u $proc_spawn_id eof exit
+ -output $out
+ -input $in
+ }
+
+ # parent has closed connection
+ say "parent closed connection"
+ catch {close -i $in}
+ catch {wait -i $in}
+ catch {close -i $out}
+ catch {wait -i $out}
+
+ # switch to using real pid
+ set pid [pid]
+ # put entry back
+ fifo_pair_create $pid $argdate $argv
+ }
+}
+
+proc say {msg} {
+ global debug_flag
+
+ if !$debug_flag return
+
+ if [catch {puts "parent: $msg"}] {
+ send_log "child: $msg\n"
+ }
+}
+
+proc escape {} {
+ # export process handles so that user can get at them
+ global in out
+
+ puts "\nto disconnect, enter: exit (or ^D)"
+ puts "to suspend, press appropriate job control sequence"
+ puts "to return to process, enter: return"
+ interpreter
+ puts "returning ..."
+}
+
+# interactively query user to choose process, return pid
+proc choose {} {
+ global index date
+
+ while 1 {
+ send_user "enter # or pid: "
+ expect_user -re "(.*)\n" {set buf $expect_out(1,string)}
+ if [info exists index($buf)] {
+ set pid $index($buf)
+ } elseif [info exists date($buf)] {
+ set pid $buf
+ } else {
+ puts "no such # or pid"
+ continue
+ }
+ return $pid
+ }
+}
+
+if {$argc} {
+ # initial creation occurs before fork because if we do it after
+ # then either the child or the parent may have to spin retrying
+ # the fifo open. Unfortunately, we cannot know the pid ahead of
+ # time so use "0". This will be set to the real pid when the
+ # parent does its initial disconnect. There is no collision
+ # problem because the fifos are deleted immediately anyway.
+
+ set datearg [exec date]
+ fifo_pair_create 0 $datearg $argv
+
+ set pid [fork]
+ say "after fork, pid = $pid"
+ if $pid==0 {
+ child $datearg $argv
+ }
+ # parent thinks of child as pid==0 for reason given earlier
+ set pid 0
+}
+
+say "examining pid"
+
+if ![info exists pid] {
+ global fifos date proc
+
+ say "pid does not exist"
+
+ pidfile_read
+
+ set count 0
+ foreach pid [array names date] {
+ incr count
+ }
+
+ if $count==0 {
+ puts "no connectable processes"
+ exit
+ } elseif $count==1 {
+ puts "one connectable process: $proc($pid)"
+ puts "pid $pid, started $date($pid)"
+ send_user "connect? \[y] "
+ expect_user -re "(.*)\n" {set buf $expect_out(1,string)}
+ if {$buf!="y" && $buf!=""} exit
+ } else {
+ puts "connectable processes:"
+ set count 1
+ puts " # pid date started process"
+ foreach pid [array names date] {
+ puts [format "%2d %6d %.19s %s" \
+ $count $pid $date($pid) $proc($pid)]
+ set index($count) $pid
+ incr count
+ }
+ set pid [choose]
+ }
+}
+
+say "opening [outfifoname $pid] for write"
+spawn -noecho -open [open [outfifoname $pid] w]
+set out $spawn_id
+
+say "opening [infifoname $pid] for read"
+spawn -noecho -open [open "|cat $catflags < [infifoname $pid]" "r"]
+set in $spawn_id
+
+puts "Escape sequence is $escape_printable"
+
+proc prompt1 {} {
+ global argv0
+
+ return "$argv0[history nextid]> "
+}
+
+interact {
+ -reset $escape escape
+ -output $out
+ -input $in
+}
+
diff --git a/expect/example/dislocate.man b/expect/example/dislocate.man
new file mode 100644
index 00000000000..d995522cc6d
--- /dev/null
+++ b/expect/example/dislocate.man
@@ -0,0 +1,100 @@
+.TH DISLOCATE 1 "7 October 1993"
+.SH NAME
+Dislocate \- disconnect and reconnect processes
+.SH SYNOPSIS
+.B dislocate
+[
+.I program args...
+]
+.SH INTRODUCTION
+.B Dislocate
+allows processes to be disconnected and reconnected to the terminal.
+Possible uses:
+.RS
+.TP 4
+\(bu
+You can disconnect a process from a terminal at work
+and reconnect from home, to continue working.
+.TP 4
+\(bu
+After having your line be dropped due to noise, you can get back to your
+process without having to restart it from scratch.
+.TP 4
+\(bu
+If you have a problem that you would like to show someone, you can set
+up the scenario at your own terminal, disconnect, walk down the hall,
+and reconnect on another terminal.
+.TP 4
+\(bu
+If you are in the middle of a great game (or whatever) that does not allow
+you to save, and someone else kicks you off the terminal, you can disconnect,
+and reconnect later.
+.SH USAGE
+When run with no arguments,
+.B Dislocate
+tells you about your disconnected processes and lets you reconnect to one.
+Otherwise,
+.B Dislocate
+runs the named program along with any arguments.
+
+By default, ^] is an escape that lets you talk to
+.B Dislocate
+itself. At that point, you can disconnect (by pressing ^D) or
+suspend
+.B Dislocate
+(by pressing ^Z).
+
+Any Tcl or Expect command is also acceptable at this point.
+For example,
+to insert the contents of a the file /etc/motd as if you had typed it, say:
+.nf
+
+ send -i $out [exec cat /etc/motd]
+
+.fi
+
+To send the numbers 1 to 100 in response to the prompt "next #", say:
+.nf
+
+ for {set i 0} {$i<100} {incr i} {
+ expect -i $in "next #"
+ send -i $out "$i\r"
+ }
+.fi
+
+Scripts can also be prepared and sourced in so that you don't have to
+type them on the spot.
+
+.B Dislocate
+is actually just a simple
+.B Expect
+script. Feel free to make it do what you want it to do or just
+use
+.B Expect
+directly, without going through
+.BR Dislocate .
+.B Dislocate
+understands a few special arguments. These should appear before any program
+name. Each should be separated by whitespace. If the arguments themselves
+takes arguments, these should also be separated by whitespace.
+.PP
+The
+.B \-escape
+flag sets the escape to whatever follows. The default escape is ^].
+.PP
+.SH CAVEATS
+This program was written by the author as an exercise to show that
+communicating with disconnected processes is easy. There are
+many features that could be added, but that is not the intent of this
+program.
+
+.SH SEE ALSO
+.BR Tcl (3),
+.BR libexpect (3)
+.br
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
diff --git a/expect/example/dvorak b/expect/example/dvorak
new file mode 100755
index 00000000000..3b8fde19d7a
--- /dev/null
+++ b/expect/example/dvorak
@@ -0,0 +1,29 @@
+#!../expect -f
+# simulate a dvorak keyboard
+# Actually just the lowercase letters are mapped to show the basic idea.
+# Really, uppercase and control should probably be mapped too.
+# But this isn't really what expect is all about. It just demonstrates
+# the mapping ability of 'interact'.
+
+proc rot {} {
+ interact {
+ q {send '} w {send ,} e {send .} r {send p}
+ t {send y} y {send f} u {send g} i {send c}
+ o {send r} p {send l} s {send o} d {send e}
+ f {send u} g {send i} h {send d} j {send h}
+ k {send t} l {send n} \; {send s} ' {send -- -}
+ z {send \;} x {send q} c {send j} v {send k}
+ b {send x} n {send b} , {send w} . {send v}
+ / {send z} ~q {return} ~d {} ~e {}
+ -o eof exit
+ }
+}
+
+log_user 0
+spawn $env(SHELL)
+log_user 1
+send_user "~d for dvorak input\n"
+send_user "~q for qwerty input (default)\n"
+send_user "~e for expect interpreter\n"
+send_user "Enter ~ sequences using qwerty keys\n"
+interact ~d rot ~q {} ~e
diff --git a/expect/example/expectd.proto b/expect/example/expectd.proto
new file mode 100755
index 00000000000..a26ca803f4b
--- /dev/null
+++ b/expect/example/expectd.proto
@@ -0,0 +1,80 @@
+#!/depot/tcl/src/expect/e --
+# Description: Simple fragment to begin a telnet daemon
+# For more information, see Chapter 17 of "Exploring Expect"
+# Author: Don Libes, NIST
+
+set IAC "\xff"
+set DONT "\xfe"
+set DO "\xfd"
+set WONT "\xfc"
+set WILL "\xfb"
+set SB "\xfa" ;# subnegotation begin
+set SE "\xf0" ;# subnegotation end
+set TTYPE "\x18"
+set SGA "\x03"
+set ECHO "\x01"
+set SEND "\x01"
+
+send "$IAC$WILL$ECHO"
+send "$IAC$WILL$SGA"
+send "$IAC$DO$TTYPE"
+
+remove_nulls 0
+
+expect_before {
+ -re "^$IAC$DO$ECHO" {
+ # treat as acknowledgement and ignore
+ exp_continue
+ }
+ -re "^$IAC$DO$SGA" {
+ # treat as acknowledgement and ignore
+ exp_continue
+ }
+ -re "^$IAC$DO\(.)" {
+ # refuse anything else
+ send_user "$IAC$WONT$expect_out(1,string)"
+ exp_continue
+ }
+ -re "^$IAC$WILL$TTYPE" {
+ # respond to acknowledgement
+ send_user "$IAC$SB$TTYPE$SEND$IAC$SE"
+ exp_continue
+ }
+ -re "^$IAC$WILL$SGA" {
+ send_user "$IAC$DO$SGA"
+ exp_continue
+ }
+ -re "^$IAC$WILL\(.)" {
+ # refuse anything else
+ send_user "$IAC$DONT$expect_out(1,string)"
+ exp_continue
+ }
+ -re "^$IAC$SB$TTYPE" {
+ expect_user null
+ expect_user -re "(.*)$IAC$SE"
+ set env(TERM) [string tolower $expect_out(1,string)]
+ # no continue!
+ }
+ -re "^$IAC$WONT$TTYPE" {
+ # treat as acknowledgement and ignore
+ set env(TERM) vt100
+ # no continue!
+ }
+}
+
+# do negotations up to terminal type
+# expect
+
+##############################
+# your code goes after this point here
+
+# spawn something ;# typically spawn something
+# expect ... ;# typically do some expects, sends, etc.
+# send ...
+# expect ...
+# send ...
+
+# expect_before ;# remove all protocol nonsense
+
+# let user interact
+# interact -re "\r" {send "\r"; expect_user \n {} null}
diff --git a/expect/example/ftp-inband b/expect/example/ftp-inband
new file mode 100755
index 00000000000..e8d3978822a
--- /dev/null
+++ b/expect/example/ftp-inband
@@ -0,0 +1,295 @@
+#!../expect -f
+# ftp-inband - copy files over a telnet/rlogin/etc link
+# Author: Don Libes, NIST
+# Date: Jan 11, 1993
+
+# Program follows usual conventions and is otherwise self-documenting.
+# Assumes standard UNIX conventions on both sides. It uses "compress"
+# which can be replaced with gzip or removed totally - it's just there
+# for efficiency.
+# Assumes error-free transmission (i.e., MNP modems), telnet links, etc.
+# Assumes remote shell does not reset tty modes after each command.
+
+# Note, there is very little error checking. This script was written
+# primarily as an exercise - just to demonstrate Expect.
+
+set prompt "(%|#|\\\$) $" ;# default prompt
+catch {set prompt $env(EXPECT_PROMPT)}
+
+set timeout -1
+set verbose_flag 0
+
+proc send_verbose {msg} {
+ global verbose_flag
+
+ if $verbose_flag {
+ send_user $msg
+ }
+}
+
+proc get {infile outfile} {
+ global prompt verbose_flag
+
+ if (!$verbose_flag) {
+ log_user 0
+ }
+
+ send_verbose "disabling echo: "
+ send "stty -echo\r"
+ expect -re $prompt
+
+ send_verbose "remote pid is "
+ send "echo $$\r"
+ expect -re "(.*)\r\n.*$prompt" {set rpid $expect_out(1,string)}
+
+ set pid [pid]
+ # pid is local pid, rpid is remote pid
+
+ set infile_plain "/tmp/$rpid"
+ set infile_compressed "$infile_plain.Z"
+ set infile_encoded "$infile_compressed.uu"
+
+ set outfile_plain "/tmp/$pid"
+ set outfile_compressed "$outfile_plain.Z"
+ set outfile_encoded "$outfile_compressed.uu"
+
+ set out [open $outfile_encoded w]
+
+ send_verbose "compressing\n"
+ send "compress -fc $infile > $infile_compressed\r"
+ expect -re $prompt
+
+ # use label corresponding to temporary name on local system
+ send_verbose "uuencoding\n"
+ send "uuencode $infile_compressed $outfile_compressed > $infile_encoded\r"
+ expect -re $prompt
+
+ send_verbose "copying\n"
+ send "cat $infile_encoded\r"
+
+ log_user 0
+
+ expect {
+ -re "^end\r\n" {
+ puts $out "end"
+ close $out
+ } -re "^(\[^\r]*)\r\n" {
+ puts $out $expect_out(1,string)
+ send_verbose "."
+ exp_continue
+ }
+ }
+
+ if ($verbose_flag) {
+ send_user "\n" ;# after last "."
+ log_user 1
+ }
+
+ expect -re $prompt ;# wait for prompt from cat
+
+ send_verbose "deleting temporary files\n"
+ send "rm -f $infile_compressed $infile_encoded\r"
+ expect -re $prompt
+
+ send_verbose "switching attention to local system\nuudecoding\n"
+ exec uudecode $outfile_encoded
+
+ send_verbose "uncompressing\n"
+ exec uncompress -f $outfile_compressed
+
+ send_verbose "renaming\n"
+ if [catch "exec cp $outfile_plain $outfile" msg] {
+ send_user "could not move file in place, reason: $msg\n"
+ send_user "left as $outfile_plain\n"
+ exec rm -f $outfile_encoded
+ } else {
+ exec rm -f $outfile_plain $outfile_encoded
+ }
+
+ # restore echo and serendipitously reprompt
+ send "stty echo\r"
+
+ log_user 1
+}
+
+proc put {infile outfile} {
+ global prompt verbose_flag
+
+ if (!$verbose_flag) {
+ log_user 0
+ }
+
+ send_verbose "disabling echo: "
+ send "stty -echo\r"
+ expect -re $prompt
+
+ send_verbose "remote pid is "
+ send "echo $$\r"
+ expect -re "(.*)\r\n.*$prompt" {set rpid $expect_out(1,string)}
+
+ set pid [pid]
+ # pid is local pid, rpid is remote pid
+
+ set infile_plain "/tmp/$pid"
+ set infile_compressed "$infile_plain.Z"
+ set infile_encoded "$infile_compressed.uu"
+
+ set outfile_plain "/tmp/$rpid"
+ set outfile_compressed "$outfile_plain.Z"
+ set outfile_encoded "$outfile_compressed.uu"
+
+ set out [open $outfile_encoded w]
+
+ send_verbose "compressing\n"
+ exec compress -fc $infile > $infile_compressed
+
+ # use label corresponding to temporary name on local system
+ send_verbose "uuencoding\n"
+ exec uuencode $infile_compressed $outfile_compressed > $infile_encoded
+
+ send_verbose "copying\n"
+ send "cat > $outfile_encoded\r"
+
+ log_user 0
+
+ set fp [open $infile_encoded r]
+ while 1 {
+ if {-1 == [gets $fp buf]} break
+ send_verbose "."
+ send "$buf\r"
+ }
+
+ if ($verbose_flag) {
+ send_user "\n" ;# after last "."
+ log_user 1
+ }
+
+ send "\004" ;# eof
+ close $fp
+
+ send_verbose "deleting temporary files\n"
+ exec rm -f $infile_compressed $infile_encoded
+
+ send_verbose "switching attention to remote system\n"
+
+ expect -re $prompt ;# wait for prompt from cat
+
+ send_verbose "uudecoding\n"
+ send "uudecode $outfile_encoded\r"
+ expect -re $prompt
+
+ send_verbose "uncompressing\n"
+ send "uncompress -f $outfile_compressed\r"
+ expect -re $prompt
+
+ send_verbose "renaming\n"
+ send "cp $outfile_plain $outfile\r"
+ expect -re $prompt
+
+ send_verbose "deleting temporary files\n"
+ send "rm -f $outfile_plain $outfile_encoded\r"
+ expect -re $prompt
+
+ # restore echo and serendipitously reprompt
+ send "stty echo\r"
+
+ log_user 1
+}
+
+proc get_main {} {
+ stty -raw echo
+ send_user "g\nget remote file \[localfile]: "
+ expect_user {
+ -re "(\[^ ]+) +(\[^ ]+)\n" {
+ send_user "copying (remote) $expect_out(1,string) to (local) $expect_out(2,string)\n"
+ get $expect_out(1,string) $expect_out(2,string)
+ } -re "(\[^ ]+)\n" {
+ send_user "copying $expect_out(1,string)\n"
+ get $expect_out(1,string) $expect_out(1,string)
+ } -re "\n" {
+ send_user "eh?\n"
+ }
+ }
+ stty raw -echo
+}
+
+proc put_main {} {
+ stty -raw echo
+ send_user "p\nput localfile \[remotefile]: "
+ expect_user {
+ -re "(\[^ ]+) +(\[^ ]+)\n" {
+ send_user "copying (local) $expect_out(1,string) to (remote) $expect_out(2,string)\n"
+ put $expect_out(1,string) $expect_out(2,string)
+ } -re "(\[^ ]+)\n" {
+ send_user "copying $expect_out(1,string)\n"
+ put $expect_out(1,string) $expect_out(1,string)
+ } -re "\n" {
+ send_user "eh?\n"
+ }
+ }
+ stty raw -echo
+}
+
+proc chdir {} {
+ stty -raw echo
+ send_user "c\n"
+ send_user "current directory is [pwd], new directory: "
+ expect_user -re "(.*)\n" {
+ cd $expect_out(1,string)
+ }
+ stty raw -echo
+}
+
+proc verbose {} {
+ global verbose_flag
+
+ set verbose_flag [expr !$verbose_flag]
+ send_user "verbose [verbose_status]\r\n"
+}
+
+proc verbose_status {} {
+ global verbose_flag
+
+ if $verbose_flag {
+ return "on"
+ } else {
+ return "off"
+ }
+}
+
+proc cmd {} {
+ set CTRLZ \032
+
+ send_user "command (g,p,? for more): "
+ expect_user {
+ g get_main
+ p put_main
+ c chdir
+ v verbose
+ ~ {send "~"}
+ "\\?" {
+ send_user "?\n"
+ send_user "~~g get file from remote system\n"
+ send_user "~~p put file to remote system\n"
+ send_user "~~c change/show directory on local system\n"
+ send_user "~~~ send ~~ to remote system\n"
+ send_user "~~? this list\n"
+ send_user "~~v verbose mode toggle (currently [verbose_status])\n"
+ send_user "~~^Z suspend\n"
+ }
+ $CTRLZ {
+ stty -raw echo
+ exec kill -STOP [pid]
+ stty raw -echo
+ }
+ -re . {send_user "unknown command\n"}
+ }
+ send_user "resuming session...\n"
+}
+
+spawn -noecho $env(SHELL)
+
+send_user "Once logged in, cd to directory to transfer to/from and press: ~~\n"
+send_user "One moment...\n"
+interact ~~ cmd
+
diff --git a/expect/example/ftp-rfc b/expect/example/ftp-rfc
new file mode 100755
index 00000000000..f55adc2bea4
--- /dev/null
+++ b/expect/example/ftp-rfc
@@ -0,0 +1,34 @@
+#!../expect --
+
+# ftp-rfc <rfc-number>
+# ftp-rfc -index
+
+# retrieves an rfc (or the index) from uunet
+
+exp_version -exit 5.0
+
+if $argc!=1 {
+ send_user "usage: ftp-rfc \[#] \[-index]\n"
+ exit
+}
+
+set file "rfc$argv.Z"
+
+set timeout 60
+spawn ftp ftp.uu.net
+expect "Name*:"
+send "anonymous\r"
+expect "Password:"
+send "expect@nist.gov\r"
+expect "ftp>"
+send "binary\r"
+expect "ftp>"
+send "cd inet/rfc\r"
+expect "550*ftp>" exit "250*ftp>"
+send "get $file\r"
+expect "550*ftp>" exit "200*226*ftp>"
+close
+wait
+send_user "\nuncompressing file - wait...\n"
+exec uncompress $file
+
diff --git a/expect/example/gethostbyaddr b/expect/example/gethostbyaddr
new file mode 100755
index 00000000000..ca27f0f7be0
--- /dev/null
+++ b/expect/example/gethostbyaddr
@@ -0,0 +1,326 @@
+#!../expect --
+#
+# gethostbyaddr a.b.c.d - translate an internet address to a FQDN,
+# guessing (a lot) if necessary.
+# Author: Don Libes, NIST
+# Version 4.0
+# Written: January 11, 1991
+# Last revised: March 21, 1996
+
+# By default, return a FQDN (fully qualified domain name) or descriptive
+# string (if FQDN is not easily determinable). This is tagged with a brief
+# explanation of how it was determined.
+#
+# If the host part of the FQDN cannot be determined, the original IP address
+# is used.
+#
+# Optional arguments act as toggles: Default
+# -t tag names with a description of how derived. true
+# -v verbose. false
+# -r reverse names to see if they resolve back to orig IP address. true
+# -n query nic for a descriptive string if it begins to look like true
+# the FQDN may be hard to derive.
+# -d turn on debugging to expose underlying dialogue false
+#
+# These options and others (see below) may be set in a ~/.gethostbyaddr file
+# To set options from that file, use the same syntax as below.
+set timeout 120 ;# timeout query after this many seconds
+set tag 1 ;# same as -t
+set reverse 1 ;# same as -r
+set verbose 0 ;# same as -v
+set nic 1 ;# same as -n
+set debug 0 ;# same as -d
+log_user 0
+
+proc usage {} {
+ send_user "usage: gethostbyaddr \[options\] a.b.c.d\n"
+ send_user "options meaning (all options act as toggles) default\n"
+ send_user " -t tag with derivation description true\n"
+ send_user " -v verbose false\n"
+ send_user " -r reverse back to IP addr for verification true\n"
+ send_user " -n query nic true\n"
+ send_user " -d produce debugging output false\n"
+ send_user "options must be separate.\n"
+ exit
+}
+
+if [file readable ~/.gethostbyaddr] {source ~/.gethostbyaddr}
+
+while {[llength $argv]>0} {
+ set flag [lindex $argv 0]
+ switch -- $flag \
+ "-v" {
+ set verbose [expr !$verbose]
+ set argv [lrange $argv 1 end]
+ } "-r" {
+ set reverse [expr !$reverse]
+ set argv [lrange $argv 1 end]
+ } "-n" {
+ set nic [expr !$nic]
+ set argv [lrange $argv 1 end]
+ } "-t" {
+ set tag [expr !$tag]
+ set argv [lrange $argv 1 end]
+ } "-d" {
+ set debug [expr !$debug]
+ set argv [lrange $argv 1 end]
+ debug $debug
+ } default {
+ break
+ }
+}
+
+set IPaddress $argv
+
+if [llength $argv]!=1 usage
+if 4!=[scan $IPaddress "%d.%d.%d.%d" a b c d] usage
+
+proc vprint {s} {
+ global verbose
+
+ if !$verbose return
+ send_user $s\n
+}
+
+# dn==1 if domain name, 0 if text (from nic)
+proc printhost {name how dn} {
+ global reverse tag IPaddress
+
+ if {$dn && $reverse} {
+ set verified [verify $name $IPaddress]
+ } else {set verified 0}
+
+ if {$verified || !$reverse || !$dn} {
+ if $tag {
+ send_user "$name ($how)\n"
+ } else {
+ send_user "$name\n"
+ }
+
+ if {$verified || !$reverse} {
+ close
+ wait
+ exit
+ }
+ }
+}
+
+# return 1 if name resolves to IP address
+proc verify {name IPaddress} {
+ vprint "verifying $name is $IPaddress"
+ set rc 0
+ spawn nslookup
+ expect ">*"
+ send $name\r
+
+ expect {
+ -re "\\*\\*\\* (\[^\r]*)\r" {
+ vprint $expect_out(1,string)
+ } timeout {
+ vprint "timed out"
+ } -re "Address:.*Address: (\[^\r]*)\r" {
+ set addr2 $expect_out(1,string)
+ if [string match $IPaddress $addr2] {
+ vprint "verified"
+ set rc 1
+ } else {
+ vprint "not verified - $name is $addr2"
+ }
+ }
+ }
+ close
+ wait
+ return $rc
+}
+
+set bad_telnet_responses "(telnet:|: unknown).*"
+
+proc telnet_error {s} {
+ regexp ": (.*)\r" $s dontcare msg
+ vprint $msg
+}
+
+proc guessHost {guess} {
+ global guessHost
+ if [info exists guessHost] return
+ set guessHost $guess
+}
+
+proc guessDomain {guess} {
+ global guessDomain
+ if [info exists guessDomain] return
+ set guessDomain $guess
+}
+
+proc guessFQDN {} {
+ global guessHost guessDomain
+ return $guessHost.$guessDomain
+}
+
+######################################################################
+# first do a simple reverse nslookup
+######################################################################
+
+vprint "using nslookup"
+spawn nslookup
+expect ">*"
+send "set query=ptr\r"
+expect ">*"
+send "$d.$c.$b.$a.in-addr.arpa\r"
+expect {
+ timeout {
+ vprint "timed out"
+ } -re "\\*\\*\\* (\[^\r]*)\r" {
+ vprint $expect_out(1,string)
+ } -re "name = (\[^\r]*)\r" {
+ set host $expect_out(1,string)
+ printhost $host nslookup 1
+
+ # split out hostname from FQDN as guess for later
+ guessHost [lindex [split $host "."] 0]
+ }
+}
+
+close
+wait
+
+######################################################################
+# next telnet to host and ask it what its name is
+######################################################################
+
+vprint "talking smtp to $IPaddress"
+spawn telnet $IPaddress smtp
+expect {
+ -re $bad_telnet_responses {
+ telnet_error $expect_out(buffer)
+ } timeout {
+ vprint "timed out"
+ } -re "\n220 (\[^\\. ]*).?(\[^ ]*)" {
+ set host $expect_out(1,string)
+ set domain $expect_out(2,string)
+ printhost $host.$domain smtp 1
+
+ # if not valid FQDN, it's likely either host or domain
+ if [string length $domain] {
+ guessDomain $host.$domain
+ } else {
+ guessHost $host
+ }
+ }
+}
+catch close
+wait
+
+######################################################################
+# ask NIC for any info about this host
+######################################################################
+
+if {$nic || ($d == 0)} {
+ vprint "talking to nic"
+ spawn telnet internic.net
+ expect {
+ -re $bad_telnet_responses {
+ telnet_error $expect_out(buffer)
+ } timeout {
+ vprint "timed out"
+ } "InterNIC >" {
+ send "whois\r"
+ expect "Whois: "
+ vprint "getting info on network $a.$b.$c"
+ send "net $a.$b.$c\r"
+ expect {
+ "No match*" {
+ vprint "no info"
+ expect "Whois: "
+ vprint "getting info on network $a.$b"
+ send "net $a.$b\r"
+ expect {
+ "No match*" {
+ vprint "no info"
+ } -re "net\r\n(\[^\r]*)\r" {
+ printhost $expect_out(1,string) nic 0
+ } timeout {
+ vprint "timed out"
+ }
+ }
+ } -re "net\r\n(\[^\r]*)\r" {
+ printhost $expect_out(1,string) nic 0
+ } timeout {
+ vprint "timed out"
+ }
+ }
+ }
+ }
+ catch close
+ wait
+ if {$d == 0} exit
+}
+
+######################################################################
+# ask other hosts in the same class C what their name is
+# so that we can at least get the likely domain
+#
+# do this in two loops - first from current IP address down to 0
+# and then next from current IP address up to 255
+######################################################################
+
+# give up guessing host name
+guessHost "unknown"
+
+for {set i [expr $d-1]} {$i>0} {incr i -1} {
+ vprint "talking smtp to $a.$b.$c.$i"
+ spawn telnet $a.$b.$c.$i smtp
+ expect {
+ -re $bad_telnet_responses {
+ telnet_error $expect_out(buffer)
+ } timeout {
+ vprint "timed out"
+ } -re "\n220 (\[^\\. ]*).?(\[^ ]*)" {
+ set host $expect_out(1,string)
+ set domain $expect_out(2,string)
+ printhost $guessHost.$domain "smtp - $a.$b.$c.$i is $host.$domain" 1
+
+ # if not valid FQDN, it's likely either host or domain
+ # don't bother recording host since it can't be for
+ # original addr.
+ if [string length $domain] {
+ guessDomain $host.$domain
+ }
+ }
+ }
+ catch close
+ wait
+}
+
+for {set i [expr $d+1]} {$i<255} {incr i} {
+ vprint "talking smtp to $a.$b.$c.$i"
+ spawn telnet $a.$b.$c.$i smtp
+ expect {
+ -re $bad_telnet_responses {
+ telnet_error $expect_out(buffer)
+ } timeout {
+ vprint "timed out"
+ } -re "\n220 (\[^ ]*.(\[^ ])) " {
+ set host $expect_out(1,string)
+ set domain $expect_out(2,string)
+ printhost $guessHost.$domain "smtp - $a.$b.$c.$i is $host.$domain" 1
+
+ # if not valid FQDN, it's likely either host or domain
+ # don't bother recording host since it can't be for
+ # original addr.
+ if [string length $domain] {
+ guessDomain $host.$domain
+ }
+ }
+ }
+ catch close
+ wait
+}
+
+######################################################################
+# print our best guess as to the name
+######################################################################
+
+
+# How pathetic. Print something, anything!
+if {!$verbose && !$tag} {send_user [guessFQDN]}
diff --git a/expect/example/irsh b/expect/example/irsh
new file mode 100755
index 00000000000..029c8c87109
--- /dev/null
+++ b/expect/example/irsh
@@ -0,0 +1,11 @@
+#!/depot/path/expect --
+
+# Do rsh interactively. For example, consider the following command:
+# rsh <remote> ls -l "|" more
+# where it would be nice to get a listing page by page
+
+spawn -noecho rlogin [lindex $argv 0]
+set timeout -1
+expect "% " ;# customize appropriately
+send "[lrange $argv 1 end];exit\r"
+interact
diff --git a/expect/example/kibitz b/expect/example/kibitz
new file mode 100755
index 00000000000..38a8978974c
--- /dev/null
+++ b/expect/example/kibitz
@@ -0,0 +1,406 @@
+#!../expect --
+# allow another user to share a shell (or other program) with you
+# See kibitz(1) man page for complete info.
+# Author: Don Libes, NIST
+# Date written: December 5, 1991
+# Date last editted: October 19, 1994
+# Version: 2.11
+exp_version -exit 5.0
+
+# if environment variable "EXPECT_PROMPT" exists, it is taken as a regular
+# expression which matches the end of your login prompt (but does not other-
+# wise occur while logging in).
+
+set prompt "(%|#|\\$) $" ;# default prompt
+set noproc 0
+set tty "" ;# default if no -tty flag
+set allow_escape 1 ;# allow escapes if true
+set escape_char \035 ;# control-right-bracket
+set escape_printable "^\]"
+set verbose 1 ;# if true, describe what kibitz is doing
+
+set kibitz "kibitz" ;# where kibitz lives if some unusual place.
+ ;# this must end in "kibitz", but can have
+ ;# things in front (like directory names).
+#set proxy "kibitz" ;# uncomment and set if you want kibitz to use
+ ;# some other account on remote systems
+
+# The following code attempts to intuit whether cat buffers by default.
+# The -u flag is required on HPUX (8 and 9) and IBM AIX (3.2) systems.
+if [file exists $exp_exec_library/cat-buffers] {
+ set catflags "-u"
+} else {
+ set catflags ""
+}
+# If this fails, you can also force it by commenting in one of the following.
+# Or, you can use the -catu flag to the script.
+#set catflags ""
+#set catflags "-u"
+
+# Some flags must be passed onto the remote kibitz process. They are stored
+# in "kibitz_flags". Currently, they include -tty and -silent.
+set kibitz_flags ""
+
+while {[llength $argv]>0} {
+ set flag [lindex $argv 0]
+ switch -- $flag \
+ "-noproc" {
+ set noproc 1
+ set argv [lrange $argv 1 end]
+ } "-catu" {
+ set catflags "-u"
+ set argv [lrange $argv 1 end]
+ } "-tty" {
+ set tty [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ set kibitz_flags "$kibitz_flags -tty $tty"
+ } "-noescape" {
+ set allow_escape 0
+ set argv [lrange $argv 1 end]
+ } "-escape" {
+ set escape_char [lindex $argv 1]
+ set escape_printable $escape_char
+ set argv [lrange $argv 2 end]
+ } "-silent" {
+ set verbose 0
+ set argv [lrange $argv 1 end]
+ set kibitz_flags "$kibitz_flags -silent"
+ } "-proxy" {
+ set proxy [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ } default {
+ break
+ }
+}
+
+if {([llength $argv]<1) && ($noproc==0)} {
+ send_user "usage: kibitz \[args] user \[program ...]\n"
+ send_user " or: kibitz \[args] user@host \[program ...]\n"
+ exit
+}
+
+log_user 0
+set timeout -1
+
+set user [lindex $argv 0]
+if [string match -r $user] {
+ send_user "KRUN" ;# this tells user_number 1 that we're running
+ ;# and to prepare for possible error messages
+ set user_number 3
+ # need to check that it exists first!
+ set user [lindex $argv 1]
+} else {
+ set user_number [expr 1+(0==[string first - $user])]
+}
+
+# at this point, user_number and user are correctly determined
+# User who originated kibitz session has user_number == 1 on local machine.
+# User who is responding to kibitz has user_number == 2.
+# User who originated kibitz session has user_number == 3 on remote machine.
+
+# user 1 invokes kibitz as "kibitz user[@host]"
+# user 2 invokes kibitz as "kibitz -####" (some pid).
+# user 3 invokes kibitz as "kibitz -r user".
+
+# uncomment for debugging: leaves each user's session in a file: 1, 2 or 3
+#exec rm -f $user_number
+#exp_internal -f $user_number 0
+
+set user2_islocal 1 ;# assume local at first
+
+# later move inside following if $user_number == 1
+# return true if x is a prefix of xjunk, given that prefixes are only
+# valid at . delimiters
+# if !do_if0, skip the whole thing - this is here just to make caller simpler
+proc is_prefix {do_if0 x xjunk} {
+ if 0!=$do_if0 {return 0}
+ set split [split $xjunk .]
+ for {set i [expr [llength $split]-1]} {$i>=0} {incr i -1} {
+ if [string match $x [join [lrange $split 0 $i] .]] {return 1}
+ }
+ return 0
+}
+
+# get domainname. Unfortunately, on some systems, domainname(1)
+# returns NIS domainname which is not the internet domainname.
+proc domainname {} {
+ # open pops stack upon failure
+ set rc [catch {open /etc/resolv.conf r} file]
+ if {$rc==0} {
+ while {-1!=[gets $file buf]} {
+ if 1==[scan $buf "domain %s" name] {
+ close $file
+ return $name
+ }
+ }
+ close $file
+ }
+
+ # fall back to using domainname
+ if {0==[catch {exec domainname} name]} {return $name}
+
+ error "could not figure out domainname"
+}
+
+if $user_number==1 {
+ if $noproc==0 {
+ if [llength $argv]>1 {
+ set pid [eval spawn [lrange $argv 1 end]]
+ } else {
+ # if running as CGI, shell may not be set!
+ set shell /bin/sh
+ catch {set shell $env(SHELL)}
+ set pid [spawn $shell]
+ }
+ set shell $spawn_id
+ }
+
+ # is user2 remote?
+ regexp (\[^@\]*)@*(.*) $user ignore tmp host
+ set user $tmp
+ if ![string match $host ""] {
+ set h_rc [catch {exec hostname} hostname]
+ set d_rc [catch domainname domainname]
+
+ if {![is_prefix $h_rc $host $hostname]
+ && ![is_prefix $d_rc $host $hostname.$domainname]} {
+ set user2_islocal 0
+ }
+ }
+
+ if !$user2_islocal {
+ if $verbose {send_user "connecting to $host\n"}
+
+ if ![info exists proxy] {
+ proc whoami {} {
+ global env
+ if [info exists env(USER)] {return $env(USER)}
+ if [info exists env(LOGNAME)] {return $env(LOGNAME)}
+ if ![catch {exec whoami} user] {return $user}
+ if ![catch {exec logname} user] {return $user}
+ # error "can't figure out who you are!"
+ }
+ set proxy [whoami]
+ }
+ spawn rlogin $host -l $proxy -8
+ set userin $spawn_id
+ set userout $spawn_id
+
+ catch {set prompt $env(EXPECT_PROMPT)}
+
+ set timeout 120
+ expect {
+ assword: {
+ stty -echo
+ send_user "password (for $proxy) on $host: "
+ set old_timeout $timeout; set timeout -1
+ expect_user -re "(.*)\n"
+ send_user "\n"
+ set timeout $old_timeout
+ send "$expect_out(1,string)\r"
+ # bother resetting echo?
+ exp_continue
+ } incorrect* {
+ send_user "invalid password or account\n"
+ exit
+ } "TERM = *) " {
+ send "\r"
+ exp_continue
+ } timeout {
+ send_user "connection to $host timed out\n"
+ exit
+ } eof {
+ send_user "connection to host failed: $expect_out(buffer)"
+ exit
+ } -re $prompt
+ }
+ if $verbose {send_user "starting kibitz on $host\n"}
+ # the kill protects user1 from receiving user3's
+ # prompt if user2 exits via expect's exit.
+ send "$kibitz $kibitz_flags -r $user;kill -9 $$\r"
+
+ expect {
+ -re "kibitz $kibitz_flags -r $user.*KRUN" {}
+ -re "kibitz $kibitz_flags -r $user.*(kibitz\[^\r\]*)\r" {
+ send_user "unable to start kibitz on $host: \"$expect_out(1,string)\"\n"
+ send_user "try rlogin by hand followed by \"kibitz $user\"\n"
+ exit
+ }
+ timeout {
+ send_user "unable to start kibitz on $host: "
+ set expect_out(buffer) "timed out"
+ set timeout 0; expect -re .+
+ send_user $expect_out(buffer)
+ exit
+ }
+ }
+ expect {
+ -re ".*\n" {
+ # pass back diagnostics
+ # should really strip out extra cr
+ send_user $expect_out(buffer)
+ exp_continue
+ }
+ KABORT exit
+ default exit
+ KDATA
+ }
+ }
+}
+
+if $user_number==2 {
+ set pid [string trimleft $user -]
+}
+
+set local_io [expr ($user_number==3)||$user2_islocal]
+if $local_io||($user_number==2) {
+ if 0==[info exists pid] {set pid [pid]}
+
+ set userinfile /tmp/exp0.$pid
+ set useroutfile /tmp/exp1.$pid
+}
+
+proc prompt1 {} {
+ return "kibitz[info level].[history nextid]> "
+}
+
+set esc_match {}
+if {$allow_escape} {
+ set esc_match {
+ $escape_char {
+ send_user "\nto exit kibitz, enter: exit\n"
+ send_user "to suspend kibitz, press appropriate job control sequence\n"
+ send_user "to return to kibitzing, enter: return\n"
+ interpreter
+ send_user "returning to kibitz\n"
+ }
+ }
+}
+
+proc prompt1 {} {
+ return "kibitz[info level].[history nextid]> "
+}
+
+set timeout -1
+
+# kibitzer executes following code
+if $user_number==2 {
+ # for readability, swap variables
+ set tmp $userinfile
+ set userinfile $useroutfile
+ set useroutfile $tmp
+
+ if ![file readable $userinfile] {
+ send_user "Eh? No one is asking you to kibitz.\n"
+ exit -1
+ }
+ spawn -open [open "|cat $catflags < $userinfile" "r"]
+ set userin $spawn_id
+
+ spawn -open [open $useroutfile w]
+ set userout $spawn_id
+ # open will hang until other user's cat starts
+
+ stty -echo raw
+ if $allow_escape {send_user "Escape sequence is $escape_printable\r\n"}
+
+ # While user is reading message, try to delete other fifo
+ catch {exec rm -f $userinfile}
+
+ eval interact $esc_match \
+ -output $userout \
+ -input $userin
+
+ exit
+}
+
+# only user_numbers 1 and 3 execute remaining code
+
+proc abort {} {
+ global user_number
+
+ # KABORT tells user_number 1 that user_number 3 has run into problems
+ # and is exiting, and diagnostics have been returned already
+ if $user_number==3 {send_user KABORT}
+ exit
+}
+
+if $local_io {
+ proc mkfifo {f} {
+ if 0==[catch {exec mkfifo $f}] return ;# POSIX
+ if 0==[catch {exec mknod $f p}] return
+ # some systems put mknod in wierd places
+ if 0==[catch {exec /usr/etc/mknod $f p}] return ;# Sun
+ if 0==[catch {exec /etc/mknod $f p}] return ;# AIX, Cray
+ puts "Couldn't figure out how to make a fifo - where is mknod?"
+ abort
+ }
+
+ proc rmfifos {} {
+ global userinfile useroutfile
+ catch {exec rm -f $userinfile $useroutfile}
+ }
+
+ trap {rmfifos; exit} {SIGINT SIGQUIT SIGTERM}
+
+ # create 2 fifos to communicate with other user
+ mkfifo $userinfile
+ mkfifo $useroutfile
+ # make sure other user can access despite umask
+ exec chmod 666 $userinfile $useroutfile
+
+ if $verbose {send_user "asking $user to type: kibitz -$pid\n"}
+
+ # can't use exec since write insists on being run from a tty!
+ set rc [catch {
+ system echo "Can we talk? Run: \"kibitz -$pid\"" | \
+ /bin/write $user $tty
+ }
+ ]
+ if $rc {rmfifos;abort}
+
+ spawn -open [open $useroutfile w]
+ set userout $spawn_id
+ # open will hang until other user's cat starts
+
+ spawn -open [open "|cat $catflags < $userinfile" "r"]
+ set userin $spawn_id
+ catch {exec rm $userinfile}
+}
+
+stty -echo raw
+
+if $user_number==3 {
+ send_user "KDATA" ;# this tells user_number 1 to send data
+
+ interact {
+ -output $userout
+ -input $userin eof {
+ wait -i $userin
+ return -tcl
+ } -output $user_spawn_id
+ }
+} else {
+ if $allow_escape {send_user "Escape sequence is $escape_printable\r\n"}
+
+ if $noproc {
+ interact {
+ -output $userout
+ -input $userin eof {wait -i $userin; return}
+ -output $user_spawn_id
+ }
+ } else {
+ eval interact $esc_match {
+ -output $shell \
+ -input $userin eof {
+ wait -i $userin
+ close -i $shell
+ return
+ } -output $shell \
+ -input $shell -output "$user_spawn_id $userout"
+ }
+ wait -i $shell
+ }
+}
+
+if $local_io rmfifos
diff --git a/expect/example/kibitz.man b/expect/example/kibitz.man
new file mode 100644
index 00000000000..ef1d32059b6
--- /dev/null
+++ b/expect/example/kibitz.man
@@ -0,0 +1,266 @@
+.TH KIBITZ 1 "19 October 1994"
+.SH NAME
+kibitz \- allow two people to interact with one shell
+.SH SYNOPSIS
+.B kibitz
+[
+.I kibitz-args
+]
+.I user
+[
+.I program program-args...
+]
+.br
+.B kibitz
+[
+.I kibitz-args
+]
+.I user@host
+[
+.I program program-args...
+]
+.SH INTRODUCTION
+.B kibitz
+allows two (or more) people to interact with one shell (or any arbitrary
+program). Uses include:
+.RS
+.TP 4
+\(bu
+A novice user can ask an expert user for help. Using
+.BR kibitz ,
+the expert can see what the user is doing, and offer advice or
+show how to do it right.
+.TP
+\(bu
+By running
+.B kibitz
+and then starting a full-screen editor, people may carry out a
+conversation, retaining the ability to scroll backwards,
+save the entire conversation, or even edit it while in progress.
+.TP
+\(bu
+People can team up on games, document editing, or other cooperative
+tasks where each person has strengths and weaknesses that complement one
+another.
+.SH USAGE
+To start
+.BR kibitz ,
+user1
+runs kibitz with the argument of the
+user to kibitz. For example:
+
+ kibitz user2
+
+.B kibitz
+starts a new shell (or another program, if given on the command
+line), while prompting user2 to run
+.BR kibitz .
+If user2 runs
+.B kibitz
+as directed, the keystrokes of both users become the input of
+the shell. Similarly, both users receive the output from the
+shell.
+
+To terminate
+.B kibitz
+it suffices to terminate the shell itself. For example, if either user
+types ^D (and the shell accepts this to be EOF), the shell terminates
+followed by
+.BR kibitz .
+
+Normally, all characters are passed uninterpreted. However, if the
+escape character (described when
+.B kibitz
+starts) is issued, the user
+may talk directly to the
+.B kibitz
+interpreter. Any
+.BR Expect (1)
+or
+.BR Tcl (3)
+commands may be given.
+Also, job control may be used while in the interpreter, to, for example,
+suspend or restart
+.BR kibitz .
+
+Various processes
+can provide various effects. For example, you can emulate a two-way write(1)
+session with the command:
+
+ kibitz user2 sleep 1000000
+.SH ARGUMENTS
+.B kibitz
+takes arguments, these should also be separated by whitespace.
+
+The
+.B \-noproc
+flag runs
+.B kibitz
+with no process underneath. Characters are passed to the other
+.BR kibitz .
+This is particularly useful for connecting multiple
+interactive processes together.
+In this mode, characters are not echoed back to the typist.
+
+.B \-noescape
+disables the escape character.
+
+.BI \-escape " char"
+sets the escape character. The default escape character is ^].
+
+.B \-silent
+turns off informational messages describing what kibitz is doing to
+initiate a connection.
+
+.BI \-tty " ttyname"
+defines the tty to which the invitation should be sent.
+
+If you start
+.B kibitz
+to user2 on a remote computer,
+.B kibitz
+performs a
+.B rlogin
+to the remote computer with your current username. The flag
+.BI \-proxy " username"
+causes
+.B rlogin
+to use
+.I username
+for the remote login (e.g. if your account on the remote computer has a
+different username). If the
+.B -proxy
+flag is not given,
+.B kibitz
+tries to determine your current username by (in that order) inspecting the
+environment variables USER and LOGNAME, then by using the commands
+.B whoami
+and
+.BR logname .
+
+The arguments
+.B -noescape
+and
+.B -escape
+can also be given by user2 when prompted to run
+.BR kibitz .
+
+.SH MORE THAN TWO USERS
+The current implementation of kibitz explicitly understands only two users,
+however, it is nonetheless possible to have a three (or more) -way kibitz,
+by kibitzing another
+.BR kibitz .
+For example, the following command runs
+.B kibitz
+with the current user, user2, and user3:
+
+ % kibitz user2 kibitz user3
+
+Additional users may be added by simply appending more "kibitz user"
+commands.
+
+The
+.B xkibitz
+script is similar to
+.B kibitz
+but supports the ability to add additional users (and drop them)
+dynamically.
+.SH CAVEATS
+.B kibitz
+assumes the 2nd user has the same terminal type and size as the 1st user.
+If this assumption is incorrect, graphical programs may display oddly.
+
+.B kibitz
+handles character graphics, but cannot handle bitmapped graphics. Thus,
+.nf
+
+ % xterm -e kibitz will work
+ % kibitz xterm will not work
+
+.fi
+However, you can get the effect of the latter command by using
+.B xkibitz
+(see SEE ALSO below).
+.B kibitz
+uses the same permissions as used by rlogin, rsh, etc. Thus, you
+can only
+.B kibitz
+to users at hosts for which you can rlogin.
+Similarly,
+.B kibitz
+will prompt for a password on the remote host if
+rlogin would.
+
+If you
+.B kibitz
+to users at remote hosts,
+.B kibitz
+needs to distinguish your prompt from other things that may precede it
+during login.
+(Ideally, the end of it is preferred but any part should suffice.)
+If you have an unusual prompt,
+set the environment variable EXPECT_PROMPT to an egrep(1)-style
+regular expression.
+Brackets should be preceded with one backslash in ranges,
+and three backslashes for literal brackets.
+The default prompt r.e. is "($|%|#)\ ".
+
+.B kibitz
+requires the
+.B kibitz
+program on both hosts.
+.B kibitz
+requires
+.BR expect (1).
+
+By comparison, the
+.B xkibitz
+script uses the X authorization mechanism for inter-host communication
+so it does not need to login, recognize your prompt, or require kibitz
+on the remote host. It does however need permission to access
+the other X servers.
+.SH BUGS
+An early version of Sun's tmpfs had a bug in it that causes
+.B kibitz
+to blow up. If
+.B kibitz
+reports "error flushing ...: Is a directory"
+ask Sun for patch #100174.
+
+If your Expect is not compiled with multiple-process support (i.e., you do not
+have a working select or poll), you will not be able to run kibitz.
+.SH ENVIRONMENT
+The environment variable SHELL is used to determine the shell to start, if no
+other program is given on the command line.
+
+If the environment variable EXPECT_PROMPT exists, it is taken as a regular
+expression which matches the end of your login prompt (but does not otherwise
+occur while logging in). See also CAVEATS above.
+
+If the environment variables USER or LOGNAME are defined, they are used to
+determine the current user name for a
+.B kibitz
+to a remote computer. See description of the
+.B -proxy
+option in ARGUMENTS above.
+.SH SEE ALSO
+.BR Tcl (3),
+.BR libexpect (3),
+.BR xkibitz (1)
+.br
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.br
+.I
+"Kibitz \- Connecting Multiple Interactive Programs Together", \fRby Don Libes,
+Software \- Practice & Experience, John Wiley & Sons, West Sussex, England,
+Vol. 23, No. 5, May, 1993.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
+
+.B kibitz
+is in the public domain.
+NIST and I would
+appreciate credit if this program or parts of it are used.
diff --git a/expect/example/lpunlock b/expect/example/lpunlock
new file mode 100755
index 00000000000..dd3bbe26bde
--- /dev/null
+++ b/expect/example/lpunlock
@@ -0,0 +1,95 @@
+#!../expect -f
+
+# This script unhangs a printer which claims it is "waiting for lock".
+# Written by Don Libes. Based on English instructions from Scott Paisley.
+
+# lpunlock figures out if the printer is on a server, and if so which,
+# by looking in the local printcap file. (You can override this by
+# supplying a server name as an additional argument.) It then rlogins
+# to the server, recreates the device and resets the queue via lpc.
+
+# assumes user has root privs on remote host via /.rhosts
+
+# assumes printer is name of device on remote system
+
+proc usage {} {
+ send_user "usage: lpunlock <printer> \[<server>\]\n"
+ send_user "example: lpunlock lw-isg durer\n"
+ exit
+}
+
+if $argc==0 usage
+set printer [lindex $argv 0]
+
+set client [exec hostname]
+
+if {$argc == 1} {
+ # if no arg2, look in local printcap for info
+ spawn ed /etc/printcap
+ expect "\n" ;# discard character count
+ send "/$printer/\r"
+ for {} 1 {} {
+ expect -re ".*:rm=(\[^:]*):.*\r\n" {
+ set server $expect_out(1,string)
+ break
+ } "\r\n*\\\r\n" { ;# look at next line of entry
+ send "\r"
+ } "\r\n*\n" { ;# no more lines of entry - give up
+ set server $client
+ break
+ }
+ }
+} else {
+ if {$argc == 2} {
+ set server [lindex $argv 1]
+ } else usage
+}
+
+set whoami [exec whoami]
+if {[string match $server $client] && [string match $whoami "root"]} {
+ spawn csh
+ expect "# "
+} else {
+ # login to the print server as root.
+ # Set timeout high because login is slow.
+ set timeout 60
+ spawn rlogin $server -l root
+ expect timeout exit \
+ eof exit \
+ "Password*" {
+ send_user "\ncouldn't login to $server as root\n"
+ exit
+ } "1#*"
+ set timeout 10
+}
+
+# run lpc and 'stop printer'
+send lpc\r ; expect "lpc>*"
+send stop $printer\r ; expect "unknown*" exit \
+ "disabled*lpc>*"
+
+# exit lpc and cd /dev
+send quit\r ; expect "#*"
+send cd /dev\r ; expect "#*"
+
+# figure out major/minor device numbers
+send ls -l /dev/$printer\r ; expect timeout {
+ send_user "\nbad device - couldn't get major/minor numbers\n"; exit
+ } "crw*#*"
+scan $expect_out(buffer) "ls -l %*s %*s 1 root %d, %d" major minor
+
+# delete the lock and the printer device itself
+send rm /var/spool/$printer/lock /dev/$printer\r ; expect #*
+
+# recreate the printer device
+send mknod $printer c $major $minor\r ; expect #*
+
+# run lpc and 'start printer'
+send lpc\r ; expect lpc>*
+send start $printer\r ; expect started*lpc>*
+send quit\r ; expect #*
+
+# logout
+send exit\r ; expect eof
+
+send_user Printer unlocked and restarted.\n
diff --git a/expect/example/mkpasswd b/expect/example/mkpasswd
new file mode 100755
index 00000000000..37690cef829
--- /dev/null
+++ b/expect/example/mkpasswd
@@ -0,0 +1,203 @@
+#!/depot/path/expect --
+# mkpasswd - make a password, if username given, set it.
+# Author: Don Libes, NIST
+
+# defaults
+set length 9
+set minnum 2
+set minlower 2
+set minupper 2
+set verbose 0
+set distribute 0
+
+if [file executable /bin/yppasswd] {
+ set defaultprog /bin/yppasswd
+} elseif [file executable /bin/passwd] {
+ set defaultprog /bin/passwd
+} else {
+ set defaultprog passwd
+}
+set prog $defaultprog
+
+while {[llength $argv]>0} {
+ set flag [lindex $argv 0]
+ switch -- $flag \
+ "-l" {
+ set length [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ } "-d" {
+ set minnum [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ } "-c" {
+ set minlower [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ } "-C" {
+ set minupper [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ } "-v" {
+ set verbose 1
+ set argv [lrange $argv 1 end]
+ } "-p" {
+ set prog [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ } "-2" {
+ set distribute 1
+ set argv [lrange $argv 1 end]
+ } default {
+ set user [lindex $argv 0]
+ set argv [lrange $argv 1 end]
+ break
+ }
+}
+
+if {[llength $argv]} {
+ puts "usage: mkpasswd \[args] \[user]"
+ puts " where arguments are:"
+ puts " -l # (length of password, default = $length)"
+ puts " -d # (min # of digits, default = $minnum)"
+ puts " -c # (min # of lowercase chars, default = $minlower)"
+ puts " -C # (min # of uppercase chars, default = $minupper)"
+ puts " -v (verbose, show passwd interaction)"
+ puts " -p prog (program to set password, default = $defaultprog)"
+ exit 1
+}
+
+if {$minnum + $minlower + $minupper > $length} {
+ puts "impossible to generate $length-character password\
+ with $minnum numbers, $minlower lowercase letters,\
+ and $minupper uppercase letters"
+ exit 1
+}
+
+# if there is any underspecification, use additional lowercase letters
+set minlower [expr $length - ($minnum + $minupper)]
+
+set lpass "" ;# password chars typed by left hand
+set rpass "" ;# password chars typed by right hand
+
+# insert char into password at a random position
+proc insert {pvar char} {
+ upvar $pvar p
+
+ set p [linsert $p [rand [expr 1+[llength $p]]] $char]
+}
+
+set _ran [pid]
+
+proc rand {m} {
+ global _ran
+
+ set period 259200
+ set _ran [expr ($_ran*7141 + 54773) % $period]
+ expr int($m*($_ran/double($period)))
+}
+
+# choose left or right starting hand
+set initially_left [set isleft [rand 2]]
+
+# given a size, distribute between left and right hands
+# taking into account where we left off
+proc psplit {max lvar rvar} {
+ upvar $lvar left $rvar right
+ global isleft
+
+ if {$isleft} {
+ set right [expr $max/2]
+ set left [expr $max-$right]
+ set isleft [expr !($max%2)]
+ } else {
+ set left [expr $max/2]
+ set right [expr $max-$left]
+ set isleft [expr $max%2]
+ }
+}
+
+if {$distribute} {
+ set lkeys {q w e r t a s d f g z x c v b}
+ set rkeys {y u i o p h j k l n m}
+ set lnums {1 2 3 4 5 6}
+ set rnums {7 8 9 0}
+} else {
+ set lkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+ set rkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+ set lnums {0 1 2 3 4 5 6 7 8 9}
+ set rnums {0 1 2 3 4 5 6 7 8 9}
+}
+
+set lkeys_length [llength $lkeys]
+set rkeys_length [llength $rkeys]
+set lnums_length [llength $lnums]
+set rnums_length [llength $rnums]
+
+psplit $minnum left right
+for {set i 0} {$i<$left} {incr i} {
+ insert lpass [lindex $lnums [rand $lnums_length]]
+}
+for {set i 0} {$i<$right} {incr i} {
+ insert rpass [lindex $rnums [rand $rnums_length]]
+}
+
+psplit $minlower left right
+for {set i 0} {$i<$left} {incr i} {
+ insert lpass [lindex $lkeys [rand $lkeys_length]]
+}
+for {set i 0} {$i<$right} {incr i} {
+ insert rpass [lindex $rkeys [rand $rkeys_length]]
+}
+
+psplit $minupper left right
+for {set i 0} {$i<$left} {incr i} {
+ insert lpass [string toupper [lindex $lkeys [rand $lkeys_length]]]
+}
+for {set i 0} {$i<$right} {incr i} {
+ insert rpass [string toupper [lindex $rkeys [rand $rkeys_length]]]
+}
+
+# merge results together
+if {$initially_left} {
+ regexp "(\[^ ]*) *(.*)" "$lpass" x password lpass
+ while {[llength $lpass]} {
+ regexp "(\[^ ]*) *(.*)" "$password$rpass" x password rpass
+ regexp "(\[^ ]*) *(.*)" "$password$lpass" x password lpass
+ }
+ if {[llength $rpass]} {
+ append password $rpass
+ }
+} else {
+ regexp "(\[^ ]*) *(.*)" "$rpass" x password rpass
+ while {[llength $rpass]} {
+ regexp "(\[^ ]*) *(.*)" "$password$lpass" x password lpass
+ regexp "(\[^ ]*) *(.*)" "$password$rpass" x password rpass
+ }
+ if {[llength $lpass]} {
+ append password $lpass
+ }
+}
+
+if {[info exists user]} {
+ if {!$verbose} {
+ log_user 0
+ }
+
+ spawn $prog $user
+ expect {
+ "assword*:" {
+ # some systems say "Password (again):"
+ send "$password\r"
+ exp_continue
+ }
+ }
+
+ # if user isn't watching, check status
+ if {!$verbose} {
+ if {[lindex [wait] 3]} {
+ puts -nonewline "$expect_out(buffer)"
+ exit 1
+ }
+ }
+}
+
+if {$verbose} {
+ puts -nonewline "password for $user is "
+}
+puts "$password"
diff --git a/expect/example/mkpasswd.man b/expect/example/mkpasswd.man
new file mode 100644
index 00000000000..05aebcfa5d3
--- /dev/null
+++ b/expect/example/mkpasswd.man
@@ -0,0 +1,95 @@
+.TH MKPASSWD 1 "22 August 1994"
+.SH NAME
+mkpasswd \- generate new password, optionally apply it to a user
+.SH SYNOPSIS
+.B mkpasswd
+.I
+[
+.I args
+]
+[
+.I user
+]
+.SH INTRODUCTION
+.B mkpasswd
+generates passwords and can apply them automatically to users.
+mkpasswd is based on the code from Chapter 23 of the O'Reilly book
+"Exploring Expect".
+.SH USAGE
+With no arguments,
+.B mkpasswd
+returns a new password.
+
+ mkpasswd
+
+With a user name,
+.B mkpasswd
+assigns a new password to the user.
+
+ mkpasswd don
+
+The passwords are randomly generated according to the flags below.
+
+.SH FLAGS
+The
+.B \-l
+flag defines the length of the password. The default is 9.
+The following example creates a 20 character password.
+
+ mkpasswd -l 20
+
+The
+.B \-d
+flag defines the minimum number of digits that must be in the password.
+The default is 2. The following example creates a password with at least
+3 digits.
+
+ mkpasswd -d 3
+
+The
+.B \-c
+flag defines the minimum number of lowercase alphabetic characters that must be in the password.
+The default is 2.
+
+The
+.B \-C
+flag defines the minimum number of uppercase alphabetic characters that must be in the password.
+The default is 2.
+
+The
+.B \-p
+flag names a program to set the password.
+By default, /etc/yppasswd is used if present, otherwise /bin/passwd is used.
+
+The
+.B \-2
+flag causes characters to be chosen so that they alternate between
+right and left hands (qwerty-style), making it harder for anyone
+watching passwords being entered. This can also make it easier for
+a password-guessing program.
+
+The
+.B \-v
+flag causes the password-setting interaction to be visible.
+By default, it is suppressed.
+
+.SH EXAMPLE
+The following example creates a 15-character password
+that contains at least 3 digits and 5 uppercase characters.
+
+ mkpasswd -l 15 -d 3 -C 5
+
+.SH SEE ALSO
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
+
+.B mkpasswd
+is in the public domain.
+NIST and I would
+appreciate credit if this program or parts of it are used.
+
+
diff --git a/expect/example/passmass b/expect/example/passmass
new file mode 100755
index 00000000000..5c1bd44bfee
--- /dev/null
+++ b/expect/example/passmass
@@ -0,0 +1,189 @@
+#!../expect --
+# passmass: change password on many machines
+# Synopsis: passmass host1 host2 host3 ....
+# Don Libes - March 11, 1991
+
+# Description: Change passwords on the named machines.
+#
+# You are prompted for old/new passwords. (If you are changing root
+# passwords and have equivalencing, the old password is not used and may be
+# omitted.)
+#
+# Additional arguments may be used for fine tuning. They affect all hosts
+# which follow until another argument overrides.
+#
+# -user User whose password will be changed. By default, the current
+# user is used.
+# -rlogin Use rlogin to access host. (default)
+# -telnet Use telnet to access host.
+# -program Next argument is taken as program to run to set password.
+# Default is "passwd". Other common choices are "yppasswd" and
+# "set passwd" (e.g., VMS hosts).
+# -prompt Next argument is taken as a prompt suffix pattern. This allows
+# the script to know when the shell is prompting. The default is
+# "# " for root and "% " for non-root accounts.
+# -timeout Next argument is number of seconds to wait for responses.
+# Default is 30 but some systems can be much slower logging in.
+
+# The best way to run this is to put the command in a one-line shell script
+# or alias. (Presumably, the set of hosts and parameters will rarely change.)
+# Then run it whenever you want to change your passwords on all the hosts.
+
+exp_version -exit 5.0
+
+if $argc==0 {
+ send_user "usage: $argv0 host1 host2 host3 . . .\n"
+ exit
+}
+
+expect_before -i $user_spawn_id \003 exit
+
+proc badhost {host emsg} {
+ global badhosts
+
+ send_user "\r\n\007password not changed on $host - $emsg\n\n"
+ if 0==[llength $badhosts] {
+ set badhosts $host
+ } else {
+ set badhosts [concat $badhosts $host]
+ }
+}
+
+# set defaults
+set login "rlogin"
+set program "passwd"
+set user [exec whoami]
+
+set timeout 1000000
+stty -echo
+send_user "old password: "
+expect_user -re "(.*)\n"
+send_user "\n"
+set oldpassword $expect_out(1,string)
+send_user "new password: "
+expect_user -re "(.*)\n"
+send_user "\n"
+set newpassword $expect_out(1,string)
+send_user "retype new password: "
+expect_user -re "(.*)\n"
+set newpassword2 $expect_out(1,string)
+send_user "\n"
+stty echo
+trap exit SIGINT
+
+if ![string match $newpassword $newpassword2] {
+ send_user "mismatch - password unchanged\n"
+ exit
+}
+
+
+#send_user "want to see new password you just typed? (y|n) "
+#expect_user "*\n"
+#
+#if [string match "y" [lindex $expect_match 0 c]] {
+# send_user "password is <$newpassword>\nproceed? (y|n) "
+# expect_user "*\n"
+# if ![string match "y" [lindex $expect_match 0 c]] exit
+#}
+
+set timeout 30
+set badhosts {}
+for {set i 0} {$i<$argc} {incr i} {
+
+ set arg [lindex $argv $i]
+ switch -- $arg \
+ "-user" {
+ incr i
+ set user [lindex $argv $i]
+ continue
+ } "-prompt" {
+ incr i
+ set prompt [lindex $argv $i]
+ continue
+ } "-rlogin" {
+ set login "rlogin"
+ continue
+ } "-telnet" {
+ set login "telnet"
+ continue
+ } "-program" {
+ incr i
+ set program [lindex $argv $i]
+ continue
+ } "-timeout" {
+ incr i
+ set timeout [lindex $argv $i]
+ continue
+ }
+
+ set host $arg
+ if [string match $login "rlogin"] {
+ set pid [spawn rlogin $host -l $user]
+ } else {
+ set pid [spawn telnet $host]
+ expect -re "(login|Username):.*" {
+ send "$user\r"
+ }
+ }
+
+ if ![info exists prompt] {
+ if [string match $user "root"] {
+ set prompt "# "
+ } else {
+ set prompt "(%|\\\$) "
+ }
+ }
+
+ set logged_in 0
+ for {} 1 {} {
+ expect "Password*" {
+ send "$oldpassword\r"
+ } eof {
+ badhost $host "spawn failed"
+ break
+ } timeout {
+ badhost $host "could not log in (or unrecognized prompt)"
+ exec kill $pid
+ expect eof
+ break
+ } -re "incorrect|invalid" {
+ badhost $host "bad password or login"
+ exec kill $pid
+ expect eof
+ break
+ } -re $prompt {
+ set logged_in 1
+ break
+ }
+ }
+
+ if (!$logged_in) {
+ wait
+ continue
+ }
+
+ send "$program\r"
+ expect "Old password*" {
+ send "$oldpassword\r"
+ expect "Sorry*" {
+ badhost $host "old password is bad?"
+ continue
+ } "password:"
+ } -re "(n|N)ew password:"
+ send "$newpassword\r"
+ expect -re "not changed|unchanged" {
+ badhost $host "new password is bad?"
+ continue
+ } -re "(password|Verification|Verify|again):.*"
+ send "$newpassword\r"
+ expect -re "(not changed|incorrect|choose new).*" {
+ badhost $host "password is bad?"
+ continue
+ } -re "$prompt"
+ send_user "\n"
+
+ close
+ wait
+}
+
+if [llength $badhosts] {send_user "\nfailed to set password on $badhosts\n"}
diff --git a/expect/example/passmass.man b/expect/example/passmass.man
new file mode 100644
index 00000000000..cb08ca89d08
--- /dev/null
+++ b/expect/example/passmass.man
@@ -0,0 +1,88 @@
+.TH PASSMASS 1 "7 October 1993"
+.SH NAME
+passmass \- change password on multiple machines
+.SH SYNOPSIS
+.B passmass
+[
+.I host1 host2 host3 ...
+]
+.SH INTRODUCTION
+.B Passmass
+changes a password on multiple machines. If you have accounts on
+several machines that do not share password databases, Passmass can
+help you keep them all in sync. This, in turn, will make it easier to
+change them more frequently.
+
+When Passmass runs, it asks you for the old and new passwords.
+(If you are changing root passwords and have equivalencing, the old
+password is not used and may be omitted.)
+
+Passmass understands the "usual" conventions. Additional arguments
+may be used for tuning. They affect all hosts which follow until
+another argument overrides it. For example, if you are known as
+"libes" on host1 and host2, but "don" on host3, you would say:
+
+ passmass host1 host2 -user don host3
+
+Arguments are:
+.RS
+.TP 4
+-user
+User whose password will be changed. By default, the current user is used.
+
+.TP 4
+-rlogin
+Use rlogin to access host. (default)
+
+.TP 4
+-telnet
+Use telnet to access host.
+
+.TP 4
+-program
+Next argument is taken as program to run to set password.
+Default is "passwd". Other common choices are "yppasswd" and
+"set passwd" (e.g., VMS hosts).
+
+.TP 4
+-prompt
+Next argument is taken as a prompt suffix pattern. This allows
+the script to know when the shell is prompting. The default is
+"# " for root and "% " for non-root accounts.
+
+.TP 4
+-timeout
+Next argument is number of seconds to wait for responses.
+Default is 30 but some systems can be much slower logging in.
+
+.SH HOW TO USE
+The best way to run Passmass is to put the command in a one-line shell
+script or alias. Whenever you get a new account on a new machine, add
+the appropriate arguments to the command. Then run it whenever you
+want to change your passwords on all the hosts.
+
+.SH CAVEATS
+
+It should be obvious that using the same password on multiple hosts
+carries risks. In particular, if the password can be stolen, then all
+of your accounts are at risk. Thus, you should not use Passmass in
+situations where your password is visible, such as across a network
+where hackers are known to eavesdrop.
+
+On the other hand, if you have enough accounts with different
+passwords, you may end up writing them down somewhere - and
+.I that
+can be a security problem. Funny story: my college roommate had an
+11"x13" piece of paper on which he had listed accounts and passwords
+all across the Internet. This was several years worth of careful work
+and he carried it with him everywhere he went.
+Well one day, he forgot to remove it from his jeans, and we found a
+perfectly blank sheet of paper when we took out the wash the following
+day!
+.SH SEE ALSO
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
diff --git a/expect/example/passwd.cgi b/expect/example/passwd.cgi
new file mode 100644
index 00000000000..6e12dcede06
--- /dev/null
+++ b/expect/example/passwd.cgi
@@ -0,0 +1,105 @@
+#!/depot/path/expect --
+
+# This is a CGI script to process requests created by the accompanying
+# passwd.html form. This script is pretty basic, although it is
+# reasonably robust. (Purposely intent users can make the script bomb
+# by mocking up their own HTML form, however they can't expose or steal
+# passwords or otherwise open any security holes.) This script doesn't
+# need any special permissions. The usual (ownership nobody) is fine.
+#
+# With a little more code, the script can do much more exotic things -
+# for example, you could have the script:
+#
+# - telnet to another host first (useful if you run CGI scripts on a
+# firewall), or
+#
+# - change passwords on multiple password server hosts, or
+#
+# - verify that passwords aren't in the dictionary, or
+#
+# - verify that passwords are at least 8 chars long and have at least 2
+# digits, 2 uppercase, 2 lowercase, or whatever restrictions you like,
+# or
+#
+# - allow short passwords by responding appropriately to passwd
+#
+# and so on. Have fun!
+#
+# Don Libes, NIST
+
+puts "Content-type: text/html\n" ;# note extra newline
+
+puts "
+<head>
+<title>Passwd Change Acknowledgment</title>
+</head>
+
+<h2>Passwd Change Acknowledgment</h2>
+"
+
+proc cgi2ascii {buf} {
+ regsub -all {\+} $buf { } buf
+ regsub -all {([\\["$])} $buf {\\\1} buf
+ regsub -all -nocase "%0d%0a" $buf "\n" buf
+ regsub -all -nocase {%([a-f0-9][a-f0-9])} $buf {[format %c 0x\1]} buf
+ eval return \"$buf\"
+}
+
+foreach pair [split [read stdin $env(CONTENT_LENGTH)] &] {
+ regexp (.*)=(.*) $pair dummy varname val
+ set val [cgi2ascii $val]
+ set var($varname) $val
+}
+
+log_user 0
+
+proc errormsg {s} {puts "<h3>Error: $s</h3>"}
+proc successmsg {s} {puts "<h3>$s</h3>"}
+
+# Need to su first to get around passwd's requirement that passwd cannot
+# be run by a totally unrelated user. Seems rather pointless since it's
+# so easy to satisfy, eh?
+
+# Change following line appropriately for your site.
+# (We use yppasswd, but you might use something else.)
+spawn /bin/su $var(name) -c "/bin/yppasswd $var(name)"
+# This fails on SunOS 4.1.3 (passwd says "you don't have a login name")
+# run on (or telnet first to) host running SunOS 4.1.4 or later.
+
+expect {
+ "Unknown login:" {
+ errormsg "unknown user: $var(name)"
+ exit
+ } default {
+ errormsg "$expect_out(buffer)"
+ exit
+ } "Password:"
+}
+send "$var(old)\r"
+expect {
+ "unknown user" {
+ errormsg "unknown user: $var(name)"
+ exit
+ } "Sorry" {
+ errormsg "Old password incorrect"
+ exit
+ } default {
+ errormsg "$expect_out(buffer)"
+ exit
+ } "Old password:"
+}
+send "$var(old)\r"
+expect "New password:"
+send "$var(new1)\r"
+expect "New password:"
+send "$var(new2)\r"
+expect -re (.*)\r\n {
+ set error $expect_out(1,string)
+}
+
+if [info exists error] {
+ errormsg "$error"
+} else {
+ successmsg "Password changed successfully."
+}
+
diff --git a/expect/example/passwd.html b/expect/example/passwd.html
new file mode 100644
index 00000000000..8d53a6cd7d4
--- /dev/null
+++ b/expect/example/passwd.html
@@ -0,0 +1,25 @@
+<HTML>
+<head>
+<title>Change your login password</title>
+</head>
+<body>
+
+This HTML creates a form for letting users change login passwords with
+a browser. To actually use this form, install the corresponding
+accompanying cgi script and then modify the action value to identify
+where you put the cgi script. (Also read the comments at the
+beginning of the CGI script.) - Don Libes
+<hr>
+
+<form method=post
+action="http://www-i.cme.nist.gov/cgi-bin/expect/passwd.cgi">
+<h2>Change your login password</h2>
+<br>Username: <input name="name">
+<br>Old password: <input type=password name="old">
+<br>New password: <input type=password name="new1">
+<br>New password: <input type=password name="new2">
+<br>New password must be entered twice to avoid typos.
+<br><input type=submit value="Change password">
+</form>
+</body>
+</html>
diff --git a/expect/example/read1char b/expect/example/read1char
new file mode 100755
index 00000000000..422d93e369a
--- /dev/null
+++ b/expect/example/read1char
@@ -0,0 +1,8 @@
+#!../expect --
+
+# read a single character
+# Author: Don Libes, NIST
+
+stty raw
+expect ?
+send_user $expect_out(buffer)
diff --git a/expect/example/reprompt b/expect/example/reprompt
new file mode 100644
index 00000000000..927f145e4a7
--- /dev/null
+++ b/expect/example/reprompt
@@ -0,0 +1,20 @@
+#!/depot/path/expect --
+
+# Name: reprompt
+# Description: reprompt every so often until user enters something
+# Usage: reprompt timeout prompt
+# Author: Don Libes, NIST
+
+foreach {timeout prompt} $argv {}
+
+send_error $prompt
+expect {
+ timeout {
+ send_error "\nwake up!!\a"
+ send_error \n$prompt
+ exp_continue
+ }
+ -re .+ {
+ send_user $expect_out(buffer)
+ }
+}
diff --git a/expect/example/rftp b/expect/example/rftp
new file mode 100755
index 00000000000..13bb0e5bb61
--- /dev/null
+++ b/expect/example/rftp
@@ -0,0 +1,339 @@
+#!../expect -f
+# rftp - ftp a directory hierarchy (i.e. recursive ftp)
+# Version 2.10
+# Don Libes, NIST
+exp_version -exit 5.0
+
+# rftp is much like ftp except that the command ~g copies everything in
+# the remote current working directory to the local current working
+# directory. Similarly ~p copies in the reverse direction. ~l just
+# lists the remote directories.
+
+# rftp takes an argument of the host to ftp to. Username and password
+# are prompted for. Other ftp options can be set interactively at that
+# time. If your local ftp understands .netrc, that is also used.
+
+# ~/.rftprc is sourced after the user has logged in to the remote site
+# and other ftp commands may be sent at that time. .rftprc may also be
+# used to override the following rftp defaults. The lines should use
+# the same syntax as these:
+
+set file_timeout 3600 ;# timeout (seconds) for retrieving files
+set timeout 1000000 ;# timeout (seconds) for other ftp dialogue
+set default_type binary ;# default type, i.e., ascii, binary, tenex
+set binary {} ;# files matching are transferred as binary
+set ascii {} ;# as above, but as ascii
+set tenex {} ;# as above, but as tenex
+
+# The values of binary, ascii and tenex should be a list of (Tcl) regular
+# expressions. For example, the following definitions would force files
+# ending in *.Z and *.tar to be transferred as binaries and everything else
+# as text.
+
+# set default_type ascii
+# set binary {*.Z *.tar}
+
+# If you are on a UNIX machine, you can probably safely ignore all of this
+# and transfer everything as "binary".
+
+# The current implementation requires that the source host be able to
+# provide directory listings in UNIX format. Hence, you cannot copy
+# from a VMS host (although you can copy to it). In fact, there is no
+# standard for the output that ftp produces, and thus, ftps that differ
+# significantly from the ubiquitous UNIX implementation may not work
+# with rftp (at least, not without changing the scanning and parsing).
+
+####################end of documentation###############################
+
+match_max -d 100000 ;# max size of a directory listing
+
+# return name of file from one line of directory listing
+proc getname {line} {
+ # if it's a symbolic link, return local name
+ set i [lsearch $line "->"]
+ if {-1==$i} {
+ # not a sym link, return last token of line as name
+ return [lindex $line [expr [llength $line]-1]]
+ } else {
+ # sym link, return "a" of "a -> b"
+ return [lindex $line [expr $i-1]]
+ }
+}
+
+proc putfile {name} {
+ global current_type default_type
+ global binary ascii tenex
+ global file_timeout
+
+ switch -- $name $binary {set new_type binary} \
+ $ascii {set new_type ascii} \
+ $tenex {set new_type tenex} \
+ default {set new_type $default_type}
+
+ if {$current_type != $new_type} {
+ settype $new_type
+ }
+
+ set timeout $file_timeout
+ send "put $name\r"
+ expect timeout {
+ send_user "ftp timed out in response to \"put $name\"\n"
+ exit
+ } "ftp>*"
+}
+
+proc getfile {name} {
+ global current_type default_type
+ global binary ascii tenex
+ global file_timeout
+
+ switch -- $name $binary {set new_type binary} \
+ $ascii {set new_type ascii} \
+ $tenex {set new_type tenex} \
+ default {set new_type $default_type}
+
+ if {$current_type != $new_type} {
+ settype $new_type
+ }
+
+ set timeout $file_timeout
+ send "get $name\r"
+ expect timeout {
+ send_user "ftp timed out in response to \"get $name\"\n"
+ exit
+ } "ftp>*"
+}
+
+# returns 1 if successful, 0 otherwise
+proc putdirectory {name} {
+ send "mkdir $name\r"
+ expect "550*denied*ftp>*" {
+ send_user "failed to make remote directory $name\n"
+ return 0
+ } timeout {
+ send_user "timed out on make remote directory $name\n"
+ return 0
+ } -re "(257|550.*exists).*ftp>.*"
+ # 550 is returned if directory already exists
+
+ send "cd $name\r"
+ expect "550*ftp>*" {
+ send_user "failed to cd to remote directory $name\n"
+ return 0
+ } timeout {
+ send_user "timed out on cd to remote directory $name\n"
+ return 0
+ } -re "2(5|0)0.*ftp>.*"
+ # some ftp's return 200, some return 250
+
+ send "lcd $name\r"
+ # hard to know what to look for, since my ftp doesn't return status
+ # codes. It is evidentally very locale-dependent.
+ # So, assume success.
+ expect "ftp>*"
+ putcurdirectory
+ send "lcd ..\r"
+ expect "ftp>*"
+ send "cd ..\r"
+ expect timeout {
+ send_user "failed to cd to remote directory ..\n"
+ return 0
+ } -re "2(5|0)0.*ftp>.*"
+
+ return 1
+}
+
+# returns 1 if successful, 0 otherwise
+proc getdirectory {name transfer} {
+ send "cd $name\r"
+ # this can fail normally if it's a symbolic link, and we are just
+ # experimenting
+ expect "550*ftp>*" {
+ send_user "failed to cd to remote directory $name\n"
+ return 0
+ } timeout {
+ send_user "timed out on cd to remote directory $name\n"
+ return 0
+ } -re "2(5|0)0.*ftp>.*"
+ # some ftp's return 200, some return 250
+
+ if $transfer {
+ send "!mkdir $name\r"
+ expect "denied*" return timeout return "ftp>"
+ send "lcd $name\r"
+ # hard to know what to look for, since my ftp doesn't return
+ # status codes. It is evidentally very locale-dependent.
+ # So, assume success.
+ expect "ftp>*"
+ }
+ getcurdirectory $transfer
+ if $transfer {
+ send "lcd ..\r"
+ expect "ftp>*"
+ }
+ send "cd ..\r"
+ expect timeout {
+ send_user "failed to cd to remote directory ..\n"
+ return 0
+ } -re "2(5|0)0.*ftp>.*"
+
+ return 1
+}
+
+proc putentry {name type} {
+ switch -- $type \
+ d {
+ # directory
+ if {$name=="." || $name==".."} return
+ putdirectory $name
+ } - {
+ # file
+ putfile $name
+ } l {
+ # symlink, could be either file or directory
+ # first assume it's a directory
+ if [putdirectory $name] return
+ putfile $name
+ } default {
+ send_user "can't figure out what $name is, skipping\n"
+ }
+}
+
+proc getentry {name type transfer} {
+ switch -- $type \
+ d {
+ # directory
+ getdirectory $name $transfer
+ } - {
+ # file
+ if !$transfer return
+ getfile $name
+ } l {
+ # symlink, could be either file or directory
+ # first assume it's a directory
+ if [getdirectory $name $transfer] return
+ if !$transfer return
+ getfile $name
+ } default {
+ send_user "can't figure out what $name is, skipping\n"
+ }
+}
+
+proc putcurdirectory {} {
+ send "!/bin/ls -alg\r"
+ expect timeout {
+ send_user "failed to get directory listing\n"
+ return
+ } "ftp>*"
+
+ set buf $expect_out(buffer)
+
+ for {} 1 {} {
+ # if end of listing, succeeded!
+ if 0==[regexp "(\[^\n]*)\n(.*)" $buf dummy line buf] return
+
+ set token [lindex $line 0]
+ switch -- $token \
+ !/bin/ls {
+ # original command
+ } total {
+ # directory header
+ } . {
+ # unreadable
+ } default {
+ # either file or directory
+ set name [getname $line]
+ set type [string index $line 0]
+ putentry $name $type
+ }
+ }
+}
+
+
+# look at result of "dir". If transfer==1, get all files and directories
+proc getcurdirectory {transfer} {
+ send "dir\r"
+ expect timeout {
+ send_user "failed to get directory listing\n"
+ return
+ } "ftp>*"
+
+ set buf $expect_out(buffer)
+
+ for {} 1 {} {
+ regexp "(\[^\n]*)\n(.*)" $buf dummy line buf
+
+ set token [lindex $line 0]
+ switch -- $token \
+ dir {
+ # original command
+ } 200 {
+ # command successful
+ } 150 {
+ # opening data connection
+ } total {
+ # directory header
+ } 226 {
+ # transfer complete, succeeded!
+ return
+ } ftp>* {
+ # next prompt, failed!
+ return
+ } . {
+ # unreadable
+ } default {
+ # either file or directory
+ set name [getname $line]
+ set type [string index $line 0]
+ getentry $name $type $transfer
+ }
+ }
+}
+
+proc settype {t} {
+ global current_type
+
+ send "type $t\r"
+ set current_type $t
+ expect "200*ftp>*"
+}
+
+proc final_msg {} {
+ # write over the previous prompt with our message
+ send_user "\rQuit ftp or cd to another directory and press ~g, ~p, or ~l\n"
+ # and then reprompt
+ send_user "ftp> "
+}
+
+if [file readable ~/.rftprc] {source ~/.rftprc}
+set first_time 1
+
+if $argc>1 {
+ send_user "usage: rftp [host]
+ exit
+}
+
+send_user "Once logged in, cd to the directory to be transferred and press:\n"
+send_user "~p to put the current directory from the local to the remote host\n"
+send_user "~g to get the current directory from the remote host to the local host\n"
+send_user "~l to list the current directory from the remote host\n"
+
+if $argc==0 {spawn ftp} else {spawn ftp $argv}
+interact -echo ~g {
+ if $first_time {
+ set first_time 0
+ settype $default_type
+ }
+ getcurdirectory 1
+ final_msg
+} -echo ~p {
+ if $first_time {
+ set first_time 0
+ settype $default_type
+ }
+ putcurdirectory
+ final_msg
+} -echo ~l {
+ getcurdirectory 0
+ final_msg
+}
diff --git a/expect/example/rlogin-cwd b/expect/example/rlogin-cwd
new file mode 100755
index 00000000000..322926386f0
--- /dev/null
+++ b/expect/example/rlogin-cwd
@@ -0,0 +1,14 @@
+#!../expect --
+# rlogin-cwd - rlogin but with same directory
+#
+# You can extend this idea to save any arbitrary information across rlogin
+# Don Libes - Oct 17, 1991.
+
+set prompt "(%|#|\\$) $" ;# default prompt
+catch {set prompt $env(EXPECT_PROMPT)}
+
+eval spawn rlogin $argv
+set timeout 60
+expect eof exit timeout {send_user "timed out\n"; exit} -re $prompt
+send "cd [pwd]\r"
+interact
diff --git a/expect/example/rlogin-display b/expect/example/rlogin-display
new file mode 100755
index 00000000000..9f114ab9d30
--- /dev/null
+++ b/expect/example/rlogin-display
@@ -0,0 +1,18 @@
+#!/depot/path/expect --
+# rlogin.exp - rlogin but with current DISPLAY
+#
+# You can extend this idea to save any arbitrary information across rlogin
+# Don Libes - Oct 17, 1991.
+
+set prompt "(%|#|\\$) $" ;# default prompt
+catch {set prompt $env(EXPECT_PROMPT)}
+
+eval spawn rlogin $argv
+set timeout 60
+expect eof exit timeout {send_user "timed out\n"; exit} -re $prompt
+if [string match "unix:0.0" $env(DISPLAY)] {
+ send "setenv DISPLAY [exec hostname].[exec domainname]:0.0\r"
+} else {
+ send "setenv DISPLAY $env(DISPLAY)\r"
+}
+interact
diff --git a/expect/example/robohunt b/expect/example/robohunt
new file mode 100644
index 00000000000..c85801104ae
--- /dev/null
+++ b/expect/example/robohunt
@@ -0,0 +1,80 @@
+#!../expect -f
+# Synopsis
+# robohunt player-name [-nodisplay]
+
+# Plays hunt automatically. Optional "-nodisplay" argument disables output.
+
+# by Don Libes
+
+expect_version -exit 5.0
+
+set timeout 1
+
+proc random {} {
+ global ia ic im jran
+
+ set jran [expr ($jran*$ia + $ic) % $im]
+ return $jran
+}
+
+set ia 7141
+set ic 54773
+set im 259200
+set jran [pid]
+
+# given a direction and number, moves that many spaces in that direction
+proc mv {dir num} {
+ # first try firing a bullet (what the hell...open some walls to move!)
+ send "f"
+ for {set i 0} {$i<$num} {incr i} {
+ send $dir
+ }
+}
+
+# move a random distance/direction
+
+# 31 is arbitrarily used as a max distance to move in any one direction
+# this is a compromise between long horizontal and vertical moves
+# but since excess movement is good for stabbing, this is reasonable
+proc move {} {
+ set num [random]
+ set mask [expr $num&3]
+ set num [expr $num&31]
+ if $mask==0 {send "H"; mv "h" $num; return}
+ if $mask==1 {send "L"; mv "l" $num; return}
+ if $mask==2 {send "K"; mv "k" $num; return}
+ send "J"; mv "j" $num; return
+}
+
+if 2==$argc { set output 0 } {set output 1}
+if 1>$argc { send_user "usage: robohunt name \[-nodisplay\]\n"; exit}
+spawn hunt -b -c -n [lindex $argv 0]
+expect "team"
+send "\r"
+
+set several_moves 5
+
+expect "Monitor:"
+sleep 1
+expect ;# flush output
+log_user 0
+# output is turned off so that we can first strip out ^Gs before they
+# are sent to the tty. It seems to drive xterms crazy - because our
+# rather stupid algorithm off not checking after every move can cause
+# the game to send a lot of them.
+
+for {} 1 {} {
+ # make several moves at a time, before checking to see if we are dead
+ # this is a compromise between just ignoring our status after each move
+ # and looking at our status after each move
+ for {set j $several_moves} {$j} {incr j -1} {
+ move
+ }
+
+ expect {
+ -re ^\007+ {exp_continue}
+ -re "\\? " {send y}
+ -re .+
+ }
+ if $output {send_user -raw $expect_out(buffer)}
+}
diff --git a/expect/example/rogue.exp b/expect/example/rogue.exp
new file mode 100755
index 00000000000..712f68c9f0f
--- /dev/null
+++ b/expect/example/rogue.exp
@@ -0,0 +1,17 @@
+#!../expect -f
+# Look for a GREAT game of rogue.
+# Idea is that any game with a Strength of 18 is unusually good.
+# Written by Don Libes - March, 1990
+
+set timeout -1
+while {1} {
+ spawn rogue
+ expect "Str: 18" break \
+ "Str: 16"
+ send "Q"
+ expect "quit?"
+ send "y"
+ close
+ wait
+}
+interact
diff --git a/expect/example/telnet-cwd b/expect/example/telnet-cwd
new file mode 100755
index 00000000000..2a032926fd9
--- /dev/null
+++ b/expect/example/telnet-cwd
@@ -0,0 +1,13 @@
+#!../expect --
+# telnet-cwd - telnet but with same directory
+#
+# You can extend this idea to save any arbitrary information across telnet
+# Don Libes - Oct 17, 1991.
+
+set prompt "(%|#|\\$) $" ;# default prompt
+catch {set prompt $env(EXPECT_PROMPT)}
+
+eval spawn telnet $argv
+interact -o -nobuffer -re $prompt return
+send "cd [pwd]\r"
+interact
diff --git a/expect/example/telnet-in-bg b/expect/example/telnet-in-bg
new file mode 100644
index 00000000000..f4edd964caf
--- /dev/null
+++ b/expect/example/telnet-in-bg
@@ -0,0 +1,18 @@
+# Start telnet and when you press ^Z, put telnet in background and save any
+# remaining output in "telnet.log". You can actually apply this technique
+# to any interactive program - I just chose telnet here.
+
+# Author: Don Libes, NIST, 1/5/95
+
+spawn -ignore HUP telnet $argv ;# start telnet
+interact \032 return ;# interact until ^Z
+
+if [fork] exit ;# disconnect from terminal
+disconnect
+
+set log [open logfile w] ;# open logfile
+expect -re .+ { ;# and record everything to it
+ puts -nonewline $log $expect_out(buffer)
+ exp_continue
+}
+
diff --git a/expect/example/term_expect b/expect/example/term_expect
new file mode 100755
index 00000000000..0b3feda833c
--- /dev/null
+++ b/expect/example/term_expect
@@ -0,0 +1,488 @@
+#!/usr/local/bin/expectk --
+
+# Name: tkterm - terminal emulator using Expect and Tk text widget, v1.0
+# Author: Don Libes, July '94
+
+# This is primarily for regression testing character-graphic applications.
+# You can certainly use it as a terminal emulator - however many features
+# in a real terminal emulator are not supported (although I'll probably
+# add some of them later).
+
+###############################
+# Quick overview of this emulator
+###############################
+# Very good attributes:
+# Understands both termcap and terminfo
+# Understands meta-key (zsh, emacs, etc work)
+# Is fast
+# Understands X selections
+# Looks best with fixed-width font but doesn't require it
+# Good-enough-for-starters attributes:
+# Understands one kind of standout mode (reverse video)
+# Should-be-fixed-soon attributes:
+# Does not support scrollbar or resize
+# Probably-wont-be-fixed-soon attributes:
+# Assumes only one terminal exists
+
+###############################################
+# To try out this package, just run it. Using it in
+# your scripts is simple. Here are directions:
+###############################################
+# 0) make sure Expect is linked into your Tk-based program (or vice versa)
+# 1) modify the variables/procedures below these comments appropriately
+# 2) source this file
+# 3) pack the text widget ($term) if you have so configured it (see
+# "term_alone" below). As distributed, it packs into . automatically.
+
+#############################################
+# Variables that must be initialized before using this:
+#############################################
+set rows 24 ;# number of rows in term
+set cols 80 ;# number of columns in term
+set term .t ;# name of text widget used by term
+set term_alone 1 ;# if 1, directly pack term into .
+ ;# else you must pack
+set termcap 1 ;# if your applications use termcap
+set terminfo 1 ;# if your applications use terminfo
+ ;# (you can use both, but note that
+ ;# starting terminfo is slow)
+set term_shell $env(SHELL) ;# program to run in term
+
+#############################################
+# Readable variables of interest
+#############################################
+# cur_row ;# current row where insert marker is
+# cur_col ;# current col where insert marker is
+# term_spawn_id ;# spawn id of term
+
+#############################################
+# Procs you may want to initialize before using this:
+#############################################
+
+# term_exit is called if the spawned process exits
+proc term_exit {} {
+ exit
+}
+
+# term_chars_changed is called after every change to the displayed chars
+# You can use if you want matches to occur in the background (a la bind)
+# If you want to test synchronously, then just do so - you don't need to
+# redefine this procedure.
+proc term_chars_changed {} {
+}
+
+# term_cursor_changed is called after the cursor is moved
+proc term_cursor_changed {} {
+}
+
+# Example tests you can make
+#
+# Test if cursor is at some specific location
+# if {$cur_row == 1 && $cur_col == 0} ...
+#
+# Test if "foo" exists anywhere in line 4
+# if {[string match *foo* [$term get 4.0 4.end]]}
+#
+# Test if "foo" exists at line 4 col 7
+# if {[string match foo* [$term get 4.7 4.end]]}
+#
+# Test if a specific character at row 4 col 5 is in standout
+# if {-1 != [lsearch [$term tag names 4.5] standout]} ...
+#
+# Return contents of screen
+# $term get 1.0 end
+#
+# Return indices of first string on lines 4 to 6 that is in standout mode
+# $term tag nextrange standout 4.0 6.end
+#
+# Replace all occurrences of "foo" with "bar" on screen
+# for {set i 1} {$i<=$rows} {incr i} {
+# regsub -all "foo" [$term get $i.0 $i.end] "bar" x
+# $term delete $i.0 $i.end
+# $term insert $i.0 $x
+# }
+
+#############################################
+# End of things of interest
+#############################################
+
+
+unset env(DISPLAY)
+set env(LINES) $rows
+set env(COLUMNS) $cols
+
+set env(TERM) "tt"
+if $termcap {
+ set env(TERMCAP) {tt:
+ :cm=\E[%d;%dH:
+ :up=\E[A:
+ :nd=\E[C:
+ :cl=\E[H\E[J:
+ :do=^J:
+ :so=\E[7m:
+ :se=\E[m:
+ :k1=\EOP:
+ :k2=\EOQ:
+ :k3=\EOR:
+ :k4=\EOS:
+ :k5=\EOT:
+ :k6=\EOU:
+ :k7=\EOV:
+ :k8=\EOW:
+ :k9=\EOX:
+ }
+}
+
+if $terminfo {
+ set env(TERMINFO) /tmp
+ set ttsrc "/tmp/tt.src"
+ set file [open $ttsrc w]
+
+ puts $file {tt|textterm|Don Libes' tk text widget terminal emulator,
+ cup=\E[%p1%d;%p2%dH,
+ cuu1=\E[A,
+ cuf1=\E[C,
+ clear=\E[H\E[J,
+ ind=\n,
+ cr=\r,
+ smso=\E[7m,
+ rmso=\E[m,
+ kf1=\EOP,
+ kf2=\EOQ,
+ kf3=\EOR,
+ kf4=\EOS,
+ kf5=\EOT,
+ kf6=\EOU,
+ kf7=\EOV,
+ kf8=\EOW,
+ kf9=\EOX,
+ }
+ close $file
+
+ set oldpath $env(PATH)
+ set env(PATH) "/usr/5bin:/usr/lib/terminfo"
+ if 1==[catch {exec tic $ttsrc} msg] {
+ puts "WARNING: tic failed - if you don't have terminfo support on"
+ puts "your system, change \"set terminfo 1\" to \"set terminfo 0\"."
+ puts "Here is the original error from running tic:"
+ puts $msg
+ }
+ set env(PATH) $oldpath
+
+ exec rm $ttsrc
+}
+
+set term_standout 0 ;# if in standout mode or not
+
+log_user 0
+
+# start a shell and text widget for its output
+set stty_init "-tabs"
+eval spawn $term_shell
+stty rows $rows columns $cols < $spawn_out(slave,name)
+set term_spawn_id $spawn_id
+
+# this shouldn't be needed if Ousterhout fixes text bug
+text $term -relief sunken -bd 1 -width $cols -height $rows -wrap none
+
+if {$term_alone} {
+ pack $term
+}
+
+$term tag configure standout -background black -foreground white
+
+proc term_clear {} {
+ global term
+
+ $term delete 1.0 end
+ term_init
+}
+
+proc term_init {} {
+ global rows cols cur_row cur_col term
+
+ # initialize it with blanks to make insertions later more easily
+ set blankline [format %*s $cols ""]\n
+ for {set i 1} {$i <= $rows} {incr i} {
+ $term insert $i.0 $blankline
+ }
+
+ set cur_row 1
+ set cur_col 0
+
+ $term mark set insert $cur_row.$cur_col
+}
+
+proc term_down {} {
+ global cur_row rows cols term
+
+ if {$cur_row < $rows} {
+ incr cur_row
+ } else {
+ # already at last line of term, so scroll screen up
+ $term delete 1.0 "1.end + 1 chars"
+
+ # recreate line at end
+ $term insert end [format %*s $cols ""]\n
+ }
+}
+
+proc term_insert {s} {
+ global cols cur_col cur_row
+ global term term_standout
+
+ set chars_rem_to_write [string length $s]
+ set space_rem_on_line [expr $cols - $cur_col]
+
+ if {$term_standout} {
+ set tag_action "add"
+ } else {
+ set tag_action "remove"
+ }
+
+ ##################
+ # write first line
+ ##################
+
+ if {$chars_rem_to_write > $space_rem_on_line} {
+ set chars_to_write $space_rem_on_line
+ set newline 1
+ } else {
+ set chars_to_write $chars_rem_to_write
+ set newline 0
+ }
+
+ $term delete $cur_row.$cur_col $cur_row.[expr $cur_col + $chars_to_write]
+ $term insert $cur_row.$cur_col [
+ string range $s 0 [expr $space_rem_on_line-1]
+ ]
+
+ $term tag $tag_action standout $cur_row.$cur_col $cur_row.[expr $cur_col + $chars_to_write]
+
+ # discard first line already written
+ incr chars_rem_to_write -$chars_to_write
+ set s [string range $s $chars_to_write end]
+
+ # update cur_col
+ incr cur_col $chars_to_write
+ # update cur_row
+ if $newline {
+ term_down
+ }
+
+ ##################
+ # write full lines
+ ##################
+ while {$chars_rem_to_write >= $cols} {
+ $term delete $cur_row.0 $cur_row.end
+ $term insert $cur_row.0 [string range $s 0 [expr $cols-1]]
+ $term tag $tag_action standout $cur_row.0 $cur_row.end
+
+ # discard line from buffer
+ set s [string range $s $cols end]
+ incr chars_rem_to_write -$cols
+
+ set cur_col 0
+ term_down
+ }
+
+ #################
+ # write last line
+ #################
+
+ if {$chars_rem_to_write} {
+ $term delete $cur_row.0 $cur_row.$chars_rem_to_write
+ $term insert $cur_row.0 $s
+ $term tag $tag_action standout $cur_row.0 $cur_row.$chars_rem_to_write
+
+ set cur_col $chars_rem_to_write
+ }
+
+ term_chars_changed
+}
+
+proc term_update_cursor {} {
+ global cur_row cur_col term
+
+ $term mark set insert $cur_row.$cur_col
+
+ term_cursor_changed
+}
+
+term_init
+
+expect_background {
+ -i $term_spawn_id
+ -re "^\[^\x01-\x1f]+" {
+ # Text
+ term_insert $expect_out(0,string)
+ term_update_cursor
+ } "^\r" {
+ # (cr,) Go to beginning of line
+ set cur_col 0
+ term_update_cursor
+ } "^\n" {
+ # (ind,do) Move cursor down one line
+ term_down
+ term_update_cursor
+ } "^\b" {
+ # Backspace nondestructively
+ incr cur_col -1
+ term_update_cursor
+ } "^\a" {
+ bell
+ } "^\t" {
+ # Tab, shouldn't happen
+ send_error "got a tab!?"
+ } eof {
+ term_exit
+ } "^\x1b\\\[A" {
+ # (cuu1,up) Move cursor up one line
+ incr cur_row -1
+ term_update_cursor
+ } "^\x1b\\\[C" {
+ # (cuf1,nd) Non-destructive space
+ incr cur_col
+ term_update_cursor
+ } -re "^\x1b\\\[(\[0-9]*);(\[0-9]*)H" {
+ # (cup,cm) Move to row y col x
+ set cur_row [expr $expect_out(1,string)+1]
+ set cur_col $expect_out(2,string)
+ term_update_cursor
+ } "^\x1b\\\[H\x1b\\\[J" {
+ # (clear,cl) Clear screen
+ term_clear
+ term_update_cursor
+ } "^\x1b\\\[7m" {
+ # (smso,so) Begin standout mode
+ set term_standout 1
+ } "^\x1b\\\[m" {
+ # (rmso,se) End standout mode
+ set term_standout 0
+ }
+}
+
+bind $term <Any-Enter> {
+ focus %W
+}
+bind $term <Meta-KeyPress> {
+ if {"%A" != ""} {
+ exp_send -i $term_spawn_id "\033%A"
+ }
+}
+bind $term <KeyPress> {
+ exp_send -i $term_spawn_id -- %A
+ break
+}
+
+bind $term <Control-space> {exp_send -null}
+bind $term <Control-at> {exp_send -null}
+
+bind $term <F1> {exp_send -i $term_spawn_id "\033OP"}
+bind $term <F2> {exp_send -i $term_spawn_id "\033OQ"}
+bind $term <F3> {exp_send -i $term_spawn_id "\033OR"}
+bind $term <F4> {exp_send -i $term_spawn_id "\033OS"}
+bind $term <F5> {exp_send -i $term_spawn_id "\033OT"}
+bind $term <F6> {exp_send -i $term_spawn_id "\033OU"}
+bind $term <F7> {exp_send -i $term_spawn_id "\033OV"}
+bind $term <F8> {exp_send -i $term_spawn_id "\033OW"}
+bind $term <F9> {exp_send -i $term_spawn_id "\033OX"}
+
+set term_counter 0
+proc term_expect {args} {
+ upvar timeout localTimeout
+ upvar #0 timeout globalTimeout
+ set timeout 10
+ catch {set timeout $globalTimeout}
+ catch {set timeout $localTimeout}
+
+ global term_counter
+ incr term_counter
+ global [set strobe _data_[set term_counter]]
+ global [set tstrobe _timer_[set term_counter]]
+
+ proc term_chars_changed {} "uplevel #0 set $strobe 1"
+
+ set $strobe 1
+ set $tstrobe 0
+
+ if {$timeout >= 0} {
+ set mstimeout [expr 1000*$timeout]
+ after $mstimeout "set $strobe 1; set $tstrobe 1"
+ set timeout_act {}
+ }
+
+ set argc [llength $args]
+ if {$argc%2 == 1} {
+ lappend args {}
+ incr argc
+ }
+
+ for {set i 0} {$i<$argc} {incr i 2} {
+ set act_index [expr $i+1]
+ if {[string compare timeout [lindex $args $i]] == 0} {
+ set timeout_act [lindex $args $act_index]
+ set args [lreplace $args $i $act_index]
+ incr argc -2
+ break
+ }
+ }
+
+ while {![info exists act]} {
+ if {![set $strobe]} {
+ tkwait var $strobe
+ }
+ set $strobe 0
+
+ if {[set $tstrobe]} {
+ set act $timeout_act
+ } else {
+ for {set i 0} {$i<$argc} {incr i 2} {
+ if {[uplevel [lindex $args $i]]} {
+ set act [lindex $args [incr i]]
+ break
+ }
+ }
+ }
+ }
+
+ proc term_chars_changed {} {}
+
+ if {$timeout >= 0} {
+ after $mstimeout unset $strobe $tstrobe
+ } else {
+ unset $strobe $tstrobe
+ }
+
+ set code [catch {uplevel $act} string]
+ if {$code > 4} {return -code $code $string}
+ if {$code == 4} {return -code continue}
+ if {$code == 3} {return -code break}
+ if {$code == 2} {return -code return}
+ if {$code == 1} {return -code error -errorinfo $errorInfo \
+ -errorcode $errorCode $string}
+ return $string
+}
+
+##################################################
+# user-supplied code goes below here
+##################################################
+
+set timeout 200
+
+# for example, wait for a shell prompt
+term_expect {regexp "%" [$term get 1.0 3.end]}
+
+# invoke game of rogue
+exp_send "myrogue\r"
+
+# wait for strength of 18
+term_expect \
+ {regexp "Str: 18" [$term get 24.0 24.end]} {
+ # do something
+ } {timeout} {
+ puts "ulp...timed out!"
+ } {regexp "Str: 16" [$term get 24.0 24.end]}
+
+# and so on...
+
diff --git a/expect/example/timed-read b/expect/example/timed-read
new file mode 100755
index 00000000000..8c698960117
--- /dev/null
+++ b/expect/example/timed-read
@@ -0,0 +1,6 @@
+#!../expect -f
+# read a complete line from stdin
+# aborting after the number of seconds (given as an argument)
+# - Don Libes
+set timeout $argv
+expect -re \n {send_user $expect_out(buffer)}
diff --git a/expect/example/timed-run b/expect/example/timed-run
new file mode 100755
index 00000000000..730d0fb5bdb
--- /dev/null
+++ b/expect/example/timed-run
@@ -0,0 +1,7 @@
+#!../expect -f
+# run a program for a given amount of time
+# i.e. time 20 long_running_program
+
+set timeout [lindex $argv 0]
+eval spawn [lrange $argv 1 end]
+expect
diff --git a/expect/example/tknewsbiff b/expect/example/tknewsbiff
new file mode 100755
index 00000000000..4f0ae7d90b2
--- /dev/null
+++ b/expect/example/tknewsbiff
@@ -0,0 +1,515 @@
+#!../expectk -f
+
+# Name: tknewsbiff
+# Author: Don Libes
+# Version: 1.2b
+# Written: January 1, 1994
+
+# Description: When unread news appears in your favorite groups, pop up
+# a little window describing which newsgroups and how many articles.
+# Go away when articles are no longer unread.
+# Optionally, run a UNIX program (to play a sound, read news, etc.)
+
+# Default config file in ~/.tknewsbiff[-host]
+
+# These two procedures are needed because Tk provides no command to undo
+# the "wm unmap" command. You must remember whether it was iconic or not.
+# PUBLIC
+proc unmapwindow {} {
+ global _window_open
+
+ switch [wm state .] \
+ iconic {
+ set _window_open 0
+ } normal {
+ set _window_open 1
+ }
+ wm withdraw .
+}
+unmapwindow
+# window state starts out as "iconic" before it is mapped, Tk bug?
+# make sure that when we map it, it will be open (i.e., "normal")
+set _window_open 1
+
+# PUBLIC
+proc mapwindow {} {
+ global _window_open
+
+ if $_window_open {
+ wm deiconify .
+ } else {
+ wm iconify .
+ }
+}
+
+proc _abort {msg} {
+ global argv0
+
+ puts "$argv0: $msg"
+ exit 1
+}
+
+if [info exists env(DOTDIR)] {
+ set home $env(DOTDIR)
+} else {
+ set home [glob ~]
+}
+
+set delay 60
+set width 27
+set height 10
+set _default_config_file $home/.tknewsbiff
+set _config_file $_default_config_file
+set _default_server news
+set server $_default_server
+set server_timeout 60
+
+log_user 0
+
+listbox .list -yscroll ".scrollbar set" -font "*-m-*" -setgrid 1
+scrollbar .scrollbar -command ".list yview" -relief raised
+.list config -highlightthickness 0 -border 0
+.scrollbar config -highlightthickness 0
+pack .scrollbar -side left -fill y
+pack .list -side left -fill both -expand 1
+
+while {[llength $argv]>0} {
+ set arg [lindex $argv 0]
+
+ if [file readable $arg] {
+ if 0==[string compare active [file tail $arg]] {
+ set active_file $arg
+ set argv [lrange $argv 1 end]
+ } else {
+ # must be a config file
+ set _config_file $arg
+ set argv [lrange $argv 1 end]
+ }
+ } elseif {[file readable $_config_file-$arg]} {
+ # maybe it's a hostname suffix for a newsrc file?
+ set _config_file $_default_config_file-$arg
+ set argv [lrange $argv 1 end]
+ } else {
+ # maybe it's just a hostname for regular newsrc file?
+ set server $arg
+ set argv [lrange $argv 1 end]
+ }
+}
+
+proc _read_config_file {} {
+ global _config_file argv0 watch_list ignore_list
+
+ # remove previous user-provided proc in case user simply
+ # deleted it from config file
+ proc user {} {}
+
+ set watch_list {}
+ set ignore_list {}
+
+ if [file exists $_config_file] {
+ # uplevel allows user to set global variables
+ if [catch {uplevel source $_config_file} msg] {
+ _abort "error reading $_config_file\n$msg"
+ }
+ }
+
+ if [llength $watch_list]==0 {
+ watch *
+ }
+}
+
+# PUBLIC
+proc watch {args} {
+ global watch_list
+
+ lappend watch_list $args
+}
+
+# PUBLIC
+proc ignore {ng} {
+ global ignore_list
+
+ lappend ignore_list $ng
+}
+
+# get time and server
+_read_config_file
+
+# if user didn't set newsrc, try ~/.newsrc-server convention.
+# if that fails, fall back to just plain ~/.newsrc
+if ![info exists newsrc] {
+ set newsrc $home/.newsrc-$server
+ if ![file readable $newsrc] {
+ set newsrc $home/.newsrc
+ if ![file readable $newsrc] {
+ _abort "cannot tell what newgroups you read
+found neither $home/.newsrc-$server nor $home/.newsrc"
+ }
+ }
+}
+
+# PRIVATE
+proc _read_newsrc {} {
+ global db newsrc
+
+ if [catch {set file [open $newsrc]} msg] {
+ _abort $msg
+ }
+ while {-1 != [gets $file buf]} {
+ if [regexp "!" $buf] continue
+ if [regexp "(\[^:]*):.*\[-, ](\[0-9]+)" $buf dummy ng seen] {
+ set db($ng,seen) $seen
+ }
+ # only way 2nd regexp can fail is on lines
+ # that have a : but no number
+ }
+ close $file
+}
+
+proc _unknown_host {} {
+ global server _default_server
+
+ if 0==[string compare $_default_server $server] {
+ puts "tknewsbiff: default server <$server> is not known"
+ } else {
+ puts "tknewsbiff: server <$server> is not known"
+ }
+
+ puts "Give tknewsbiff an argument - either the name of your news server
+or active file. I.e.,
+
+ tknewsbiff news.nist.gov
+ tknewsbiff /usr/news/lib/active
+
+If you have a correctly defined configuration file (.tknewsbiff),
+an argument is not required. See the man page for more info."
+ exit 1
+}
+
+# read active file
+# PRIVATE
+proc _read_active {} {
+ global db server active_list active_file
+ upvar #0 server_timeout timeout
+
+ set active_list {}
+
+ if [info exists active_file] {
+ spawn -open [open $active_file]
+ } else {
+ spawn telnet $server nntp
+ expect {
+ "20*\n" {
+ # should get 200 or 201
+ } "NNTP server*\n" {
+ puts "tknewsbiff: unexpected response from server:"
+ puts "$expect_out(buffer)"
+ return 1
+ } "unknown host" {
+ _unknown_host
+ } timeout {
+ close
+ wait
+ return 1
+ } eof {
+ # loadav too high probably
+ wait
+ return 1
+ }
+ }
+ exp_send "list\r"
+ expect "list\r\n" ;# ignore echo of "list" command
+ expect -re "215\[^\n]*\n" ;# skip "Newsgroups in form" line
+ }
+
+ expect {
+ -re "(\[^ ]*) 0*(\[^ ]+) \[^\n]*\n" {
+ set ng $expect_out(1,string)
+ set hi $expect_out(2,string)
+ lappend active_list $ng
+ set db($ng,hi) $hi
+ exp_continue
+ }
+ ".\r\n" close
+ ".\r\r\n" close
+ timeout close
+ eof
+ }
+
+ wait
+ return 0
+}
+
+# test in various ways for good newsgroups
+# return 1 if good, 0 if not good
+# PRIVATE
+proc _isgood {ng threshold} {
+ global db seen_list ignore_list
+
+ # skip if we don't subscribe to it
+ if ![info exists db($ng,seen)] {return 0}
+
+ # skip if the threshold isn't exceeded
+ if {$db($ng,hi) - $db($ng,seen) < $threshold} {return 0}
+
+ # skip if it matches an ignore command
+ foreach igpat $ignore_list {
+ if [string match $igpat $ng] {return 0}
+ }
+
+ # skip if we've seen it before
+ if [lsearch -exact $seen_list $ng]!=-1 {return 0}
+
+ # passed all tests, so remember that we've seen it
+ lappend seen_list $ng
+ return 1
+}
+
+# return 1 if not seen on previous turn
+# PRIVATE
+proc _isnew {ng} {
+ global previous_seen_list
+
+ if [lsearch -exact $previous_seen_list $ng]==-1 {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+# schedule display of newsgroup in global variable "newsgroup"
+# PUBLIC
+proc display {} {
+ global display_list newsgroup
+
+ lappend display_list $newsgroup
+}
+
+# PRIVATE
+proc _update_ngs {} {
+ global watch_list active_list newsgroup
+
+ foreach watch $watch_list {
+ set threshold 1
+ set display display
+ set new {}
+
+ set ngpat [lindex $watch 0]
+ set watch [lrange $watch 1 end]
+
+ while {[llength $watch] > 0} {
+ switch -- [lindex $watch 0] \
+ -threshold {
+ set threshold [lindex $watch 1]
+ set watch [lrange $watch 2 end]
+ } -display {
+ set display [lindex $watch 1]
+ set watch [lrange $watch 2 end]
+ } -new {
+ set new [lindex $watch 1]
+ set watch [lrange $watch 2 end]
+ } default {
+ _abort "watch: expecting -threshold -display or -new but found: [lindex $watch 0]"
+ }
+ }
+
+ foreach ng $active_list {
+ if [string match $ngpat $ng] {
+ if [_isgood $ng $threshold] {
+ if [llength $display] {
+ set newsgroup $ng
+ uplevel $display
+ }
+ if [_isnew $ng] {
+ if [llength $new] {
+ set newsgroup $ng
+ uplevel $new
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+# initialize display
+
+set min_reasonable_width 8
+
+wm minsize . $min_reasonable_width 1
+wm maxsize . 999 999
+if {0 == [info exists active_file] &&
+ 0 != [string compare $server $_default_server]} {
+ wm title . "news@$server"
+ wm iconname . "news@$server"
+}
+
+# PRIVATE
+proc _update_window {} {
+ global server display_list height width min_reasonable_width
+
+ if {0 == [llength $display_list]} {
+ unmapwindow
+ return
+ }
+
+ # make height correspond to length of display_list or
+ # user's requested max height, whichever is smaller
+
+ if {[llength $display_list] < $height} {
+ set current_height [llength $display_list]
+ } else {
+ set current_height $height
+ }
+
+ # force reasonable min width
+ if {$width < $min_reasonable_width} {
+ set width $min_reasonable_width
+ }
+
+ wm geometry . ${width}x$current_height
+ wm maxsize . 999 [llength $display_list]
+
+ _display_ngs $width
+
+ if [string compare [wm state .] withdrawn]==0 {
+ mapwindow
+ }
+}
+
+# actually write all newsgroups to the window
+# PRIVATE
+proc _display_ngs {width} {
+ global db display_list
+
+ set str_width [expr $width-7]
+
+ .list delete 0 end
+ foreach ng $display_list {
+ .list insert end [format \
+ "%-$str_width.${str_width}s %5d" $ng \
+ [expr $db($ng,hi) - $db($ng,seen)]]
+ }
+}
+
+# PUBLIC
+proc help {} {
+ catch {destroy .help}
+ toplevel .help
+ message .help.text -aspect 400 -text \
+{tknewsbiff - written by Don Libes, NIST, 1/1/94
+
+tknewsbiff displays newsgroups with unread articles based on your .newsrc\
+and your .tknewsbiff files.\
+If no articles are unread, no window is displayed.
+
+Click mouse button 1 for this help,\
+button 2 to force display to query news server immediately,\
+and button 3 to remove window from screen until the next update.
+
+Example .tknewsbiff file:}
+ message .help.sample -font "*-r-normal-*-m-*" \
+ -relief raised -aspect 10000 -text \
+{set width 30 ;# max width, defaults to 27
+set height 17 ;# max height, defaults to 10
+set delay 120 ;# in seconds, defaults to 60
+set server news.nist.gov ;# defaults to "news"
+set server_timeout 60 ;# in seconds, defaults to 60
+set newsrc ~/.newsrc ;# defaults to ~/.newsrc
+ ;# after trying ~/.newsrc-$server
+# Groups to watch.
+watch comp.lang.tcl
+watch dc.dining -new "play yumyum"
+watch nist.security -new "exec red-alert"
+watch nist.*
+watch dc.general -threshold 5
+watch *.sources.* -threshold 20
+watch alt.howard-stern -threshold 100 -new "play robin"
+
+# Groups to ignore (but which match patterns above).
+# Note: newsgroups that you don't read are ignored automatically.
+ignore *.d
+ignore nist.security
+ignore nist.sport
+
+# Change background color of newsgroup list
+.list config -bg honeydew1
+
+# Play a sound file
+proc play {sound} {
+ exec play /usr/local/lib/sounds/$sound.au
+}}
+ message .help.end -aspect 10000 -text \
+"Other customizations are possible. See man page for more information."
+
+ button .help.ok -text "ok" -command {destroy .help}
+ pack .help.text
+ pack .help.sample
+ pack .help.end -anchor w
+ pack .help.ok -fill x -padx 2 -pady 2
+}
+
+spawn cat -u; set _cat_spawn_id $spawn_id
+set _update_flag 0
+
+# PUBLIC
+proc update-now {} {
+ global _update_flag _cat_spawn_id
+
+ if $_update_flag return ;# already set, do nothing
+ set _update_flag 1
+
+ exp_send -i $_cat_spawn_id "\r"
+}
+
+bind .list <1> help
+bind .list <2> update-now
+bind .list <3> unmapwindow
+bind .list <Configure> {
+ scan [wm geometry .] "%%dx%%d" w h
+ _display_ngs $w
+}
+
+# PRIVATE
+proc _sleep {timeout} {
+ global _cat_spawn_id _update_flag
+
+ set _update_flag 0
+
+ # restore to idle cursor
+ .list config -cursor ""; update
+
+ # sleep for a little while, subject to click from "update" button
+ expect -i $_cat_spawn_id -re "...." ;# two crlfs
+
+ # change to busy cursor
+ .list config -cursor watch; update
+}
+
+set previous_seen_list {}
+set seen_list {}
+
+# PRIVATE
+proc _init_ngs {} {
+ global display_list db
+ global seen_list previous_seen_list
+
+ set previous_seen_list $seen_list
+
+ set display_list {}
+ set seen_list {}
+
+ catch {unset db}
+}
+
+for {} 1 {_sleep $delay} {
+ _init_ngs
+
+ _read_newsrc
+ if [_read_active] continue
+ _read_config_file
+
+ _update_ngs
+ user
+ _update_window
+}
diff --git a/expect/example/tknewsbiff.man b/expect/example/tknewsbiff.man
new file mode 100644
index 00000000000..dc5d4adc71b
--- /dev/null
+++ b/expect/example/tknewsbiff.man
@@ -0,0 +1,412 @@
+.TH TKNEWSBIFF 1 "1 January 1994"
+.SH NAME
+tknewsbiff \- pop up a window when news appears
+.SH SYNOPSIS
+.B tknewsbiff
+[
+.I server or config-file
+]
+.br
+.SH INTRODUCTION
+.B tknewsbiff
+pops up a window when there is unread news in your favorite newsgroups
+and removes the window after you've read the news. tknewsbiff can
+optionally play a sound, start your newsreader, etc.
+
+.SH SELECTING NEWSGROUPS
+
+By default, the configuration file ~/.tknewsbiff describes how
+tknewsbiff behaves. The syntax observes the usual Tcl rules
+- however, even if you don't know Tcl, all but the most esoteric
+configurations will be obvious.
+
+Each newsgroup (or set of newsgroups) to be watched is described by
+using the "watch" command. For example:
+
+.nf
+
+watch dc.dining
+watch nist.*
+watch comp.unix.wizard -threshold 3
+watch *.sources.* -threshold 20
+
+.fi
+
+For each newsgroup pattern, any newsgroup that matches it and which
+you are subscribed to (according to your newsrc file) is eligible for
+reporting. By default, tknewsbiff reports on the newsgroup if there
+is at least one unread article. The "-threshold" flag changes the
+threshold to the following number. For example, "-threshold 3" means
+there must be at least three articles unread before tknewsbiff will
+report the newsgroup.
+
+If no watch commands are given (or no configuration file exists), all
+groups which are subscribed to are watched.
+
+To suppress newsgroups that would otherwise be reported, use the
+"ignore" command. For example, the following matches all comp.* and
+nist.* newgroups except for nist.posix or .d (discussion) groups:
+
+.nf
+
+watch comp.*
+watch nist.*
+ignore nist.posix.*
+ignore *.d
+
+.fi
+
+The flag "-new" describes a command to be executed when the newsgroup
+is first reported as having unread news. For example, the following
+lines invoke the UNIX command "play" to play a sound.
+
+.nf
+
+watch dc.dining -new "exec play /usr/local/sounds/yumyum.au"
+watch rec.auto* -new "exec play /usr/local/sounds/vroom.au"
+
+.fi
+
+You can cut down on the verbosity of actions by defining procedures.
+For example, if you have many -new flags that all play sound files,
+you could define a sound procedure. This would allow the -new
+specification to be much shorter.
+
+.nf
+
+proc play {sound} {
+ exec play /usr/local/sounds/$sound.au
+}
+
+watch dc.dining -new "play yumyum"
+watch rec.auto* -new "play vroom"
+
+.fi
+
+As an aside, you can put an "&" at the end of an "exec" command to get
+commands to execute asynchronously. However, it's probably not a good
+idea to do this when playing sound files anyway.
+
+"newsgroup" is a read-only variable which contains the name of the
+newsgroup that is being reported. This is useful when the action is
+triggered by a pattern. For example, the following line could run the
+newsgroup name through a speech synthesizer:
+
+.nf
+
+watch * -new {
+ exec play herald.au
+ exec speak "New news has arrived in $newsgroup."
+}
+
+.fi
+
+The flag "\-display" describes a command to be executed every time the
+newsgroup is reported as having unread news. The special command
+"display" is the default command. It schedules $newsgroup to be
+written to tknewsbiff's display when it is rewritten. For example, by
+explicitly providing a -display flag that omits the display command,
+you can disable the display of newsgroups that are already reported
+via -new.
+
+.nf
+
+watch dc.dining -new {exec play yumyum.au} -display {}
+
+.fi
+
+If you want to execute an action repeatedly and
+.I still
+display the newsgroup in the default manner,
+explicitly invoke the display command via the -display flag. For example:
+
+.nf
+
+watch *security* -display {
+ exec play red-alert.au
+ display
+}
+
+.fi
+
+Actions associated with the -new and -display flags are executed only
+once for each matching newsgroup. The command executed is the one
+associated with the first pattern in the configuration file that
+matches and observes the given threshold.
+
+Any command that is simply listed in the configuration file is
+executed each time before the update loop in tknewsbiff. The reserved
+(but user-defined) procedure "user" is run immediately after the
+newsgroups are scheduled to be written to the display and before they
+are actually written.
+
+For example, suppose unread articles appear in several rec.auto groups
+and you play the same sound for each one. To prevent playing the
+sound several times in a row, make the -new command simply set a flag.
+In the user procedure, play the sound if the flag is set (and then
+reset the flag).
+
+The user procedure could also be used to start a newsreader. This
+would avoid the possibility of starting multiple newsreaders just
+because multiple newsgroups contained unread articles. (A check
+should, of course, be made to make sure that a newsreader is not
+already running.)
+
+.SH MORE VARIABLES
+
+The following example lines show variables that can affect the
+behavior of tknewsbiff
+
+.nf
+
+set delay 120
+set server news.nist.gov
+set server_timeout 60
+set newsrc ~/.newsrc
+set width 40
+set height 20
+set active_file /usr/news/lib/active
+
+.fi
+
+tknewsbiff alternates between checking for unread news and
+sleeping (kind of like many undergraduates). The "delay" variable
+describes how many seconds to sleep.
+
+The "server" variable names an NNTP news-server.
+The default is "news". The "server" variable is
+only used if the "active_file" variable is not set.
+
+The "server_timeout" variable describes how how many seconds to wait
+for a response from the server before giving up. -1 means wait
+forever or until the server itself times out. The default is 60
+seconds.
+
+The "newsrc" variable describes the name of your .newsrc file. By
+default, tknewsbiff looks in your home directory for a newsrc file. A
+server-specific newsrc is used if found. For example, if you have set
+server to "cubit.nist.gov", then tknewsbiff looks for
+~/.newsrc-cubit.nist.gov. (This is the Emacs gnus convention - which
+is very convenient when you read news from multiple servers.) If
+there is no server-specific newsrc, tknewsbiff uses ~/.newsrc.
+
+The "width" variable describes the width that tknewsbiff will use to
+display information. If any newsgroup names are long enough, they
+will be truncated so that the article counts can still be shown. You
+can manually resize the window to see what was truncated. However, if
+your configuration file sets the width variable, the window will be
+restored to that size the next time that tknewsbiff checks for unread
+news and updates its display.
+
+The "height" variable describes the maximum height that tknewsbiff
+will use to display information. If fewer newsgroups are reported,
+tknewsbiff will shrink the window appropriately. You can manually
+resize the window but if your configuration file sets the height
+variable, the window will be restored to that size the next time that
+tknewsbiff checks for unread news and updates its display.
+
+The "active_file" variable describes the name of the news active file.
+If set, the active file is read directly in preference to using NNTP
+(even if the "server" variable is set). This is particularly useful
+for testing out new configuration files since you can edit a fake
+active file and then click button 2 to immediately see how tknewsbiff
+responds (see BUTTONS below).
+
+If the environment variable DOTDIR is set, then its value is used as a
+directory in which to find all dotfiles instead of from the home
+directory. In particular, this affects the tknewsbiff configuration
+file and the .newsrc file (assuming the newsrc variable is not set
+explicitly).
+
+.SH WATCHING DIFFERENT NEWS SERVERS
+
+To watch multiple servers, run tknewsbiff multiple times. (Since you
+need different .newsrc files and the servers have different newsgroups
+and article numbers anyway, there is no point in trying to do this in
+a single process.)
+
+You can point tknewsbiff at a different server with an appropriate
+argument. The argument is tried both as a configuration file name and
+as a suffix to the string "~/.tknewsbiff-". So if you want to watch
+the server "kidney", store the tknewsbiff configuration information in
+~/.tknewsbiff-kidney". The following two commands will both use that
+configuration file.
+
+.nf
+
+ tknewsbiff kidney
+ tknewsbiff ~/.tknewsbiff-kidney
+
+.fi
+
+In both cases, the actual server to contact is set by the value of the
+server variable in the configuration file.
+
+If no configuration file is found, the argument is used as the server
+to contact. This allows tknewsbiff to be run with no preparation
+whatsoever.
+
+If the argument is the special keyword "active" (or ends in
+"/active"), it is used as the name of an active file. This is in turn
+used to initialize the variable "active_file" so that tknewsbiff reads
+from the active file directly rather than using NNTP.
+
+Creating your own active file is a convenient way of testing your
+configuration file. For example, after running the following command,
+you can repeatedly edit your active file and trigger the update-now
+command (either by pressing button 2 or setting the delay variable
+very low) to see how tknewsbiff responds.
+
+The active file must follow the format of a real active file. The
+format is one newsgroup per line. After the newsgroup name is the
+number of the highest article, the lowest article. Lastly is the
+letter y or m. m means the newsgroup is moderated. y means posting
+is allowed.
+
+.SH WINDOW
+
+When unread news is found, a window is popped up. The window lists
+the names of the newsgroups and the number of unread articles in each
+(unless suppressed by the -display flag). When there is no longer any
+unread news, the window disappears (although the process continues to
+run).
+
+.SH BUTTONS
+
+Button or key bindings may be assigned by bind commands. Feel free to
+change them. The default bind commands are:
+
+.nf
+
+bind .list <1> help
+bind .list <2> update-now
+bind .list <3> unmapwindow
+
+.fi
+
+By default button 1 (left) is bound to "help". The help command
+causes tknewsbiff to pop up a help window.
+
+By default, button 2 (middle) is bound to "update-now". The update-now
+command causes tknewsbiff to immediately check for unread news. If
+your news server is slow or maintains a very large number of
+newsgroups, or you have a large number of patterns in your
+configuration file, tknewsbiff can take considerable time before
+actually updating the window.
+
+By default, button 3 (right) is bound to "unmapwindow". The
+unmapwindow command causes tknewsbiff to remove the window from the
+display until the next time it finds unread news. (The mapwindow
+command causes tknewsbiff to restore the window.)
+
+As an example, here is a binding to pop up an xterm and run rn when
+you hold down the shift key and press button 1 in the listing window.
+
+.nf
+
+bind .list <Shift-1> {
+ exec xterm -e rn &
+}
+
+.fi
+
+Here is a similar binding. However it tells rn to look only at the
+newsgroup that is under the mouse when you pressed it. (The
+"display_list" variable is described later in this man page.)
+
+.nf
+
+bind .list <Shift-1> {
+ exec xterm -e rn [lindex $display_list [.list nearest %y]] &
+}
+
+.fi
+
+.SH OTHER COMMANDS AND VARIABLES
+
+Built-in commands already mentioned are: watch, ignore, display, help,
+update-now, unmapwindow, and mapwindow.
+
+Any Tcl and Tk command can also be given. In particular, the list of
+newsgroups is stored in the list widget ".list", and the scroll bar is
+stored in the scrollbar widget ".scroll". So for example, if you want
+to change the foreground and background colors of the newsgroup list,
+you can say:
+
+.nf
+
+ .list config -bg honeydew1 -fg orchid2
+
+.fi
+
+These can also be controlled by the X resource database as well.
+However, the configuration file allows arbitrarily complex commands to
+be evaluated rather than simple assignments.
+
+Certain Tcl/Tk commands can disrupt proper function of tknewsbiff.
+These will probably be obvious to anyone who knows enough to give
+these commands in the first place. As a simple example, the program
+assumes the font in the list box is of fixed width. The newsgroups
+will likely not align if you use a variable-width font.
+
+The following variables are accessible and can be used for esoteric
+uses. All other variables are private. Private variables and
+commands begin with "_" so you don't need to worry about accidental
+collisions.
+
+The array "db" is a database which maintains information about read
+and unread news. db($newsgroup,hi) is the highest article that
+exists. db($newsgroup,seen) is the highest article that you have
+read.
+
+A number of lists maintain interesting information. "active_list" is a
+list of known newsgroups. "seen_list" is a list of newsgroups that
+have been seen so far as the -new and -display flags are being
+processed. "previous_seen_list" is "seen_list" from the previous
+cycle. "ignore_list" is the list of newsgroup patterns to ignore.
+"watch_list" is the list of newsgroup patterns to watch.
+"display_list" is the list of newsgroup will be displayed at the next
+opportunity.
+
+.SH UPDATING YOUR FILES
+
+tknewsbiff automatically rereads your configuration file each time it
+wakes up to check for unread news. To force tknewsbiff to reread the
+file immediately (such as if you are testing a new configuration or
+have just modified your newsrc file), press button 2 in the display
+(see BUTTONS above).
+
+.SH CAVEATS
+
+tknewsbiff defines the number of unread articles as the highest
+existing article minus the highest article that you've read. So if
+you've read the last article in the newsgroup but no others,
+tknewsbiff thinks there are no unread articles. (It's impossible to
+do any better by reading the active file and it would be very time
+consuming to do this more accurately via NNTP since servers provide no
+efficient way of reporting their own holes in the newsgroups.)
+Fortunately, this definition is considered a feature by most people.
+It allows you to read articles and then mark them "unread" but not
+have tknewsbiff continue telling you that they are unread.
+
+.SH UNWARRANTED CONCERNS
+
+Your news administrator may wonder if many people using tknewsbiff
+severely impact an NNTP server. In fact, the impact is negligible
+even when the delay is very low. To gather all the information it
+needs, tknewsbiff uses a single NNTP query - it just asks for the
+active file. The NNTP server does no computation, formatting, etc, it
+just sends the file. All the interesting processing happens locally
+in the tknewsbiff program itself.
+
+.SH BUGS
+
+The man page is longer than the program.
+
+.SH SEE ALSO
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
diff --git a/expect/example/tkpasswd b/expect/example/tkpasswd
new file mode 100755
index 00000000000..68e9c441f44
--- /dev/null
+++ b/expect/example/tkpasswd
@@ -0,0 +1,630 @@
+#!/depot/path/expectk -f
+# tkpasswd - Change passwords using Expectk
+# Author: Don Libes, NIST, October 1, 1993
+# Version: 1.8 - Added support for Tk 4.1
+
+# There is no man page. However, there is some on-line help when you run
+# the program. Technical details and insights are described in the
+# O'Reilly book "Exploring Expect".
+
+proc prog_exists {prog} {
+ global env
+
+ foreach dir [split $env(PATH) :] {
+ if [file executable $dir/$prog] {
+ return 1
+ }
+ }
+ return 0
+}
+
+frame .type -relief raised -bd 1
+
+radiobutton .passwd -text passwd -variable passwd_cmd \
+ -value {passwd {cat /etc/passwd}} \
+ -anchor w -command get_users -relief flat
+pack .passwd -in .type -fill x
+
+if [prog_exists yppasswd] {
+ radiobutton .yppasswd -text yppasswd -variable passwd_cmd \
+ -value {yppasswd {ypcat passwd}} \
+ -anchor w -command get_users -relief flat
+ pack .yppasswd -in .type -fill x
+}
+
+if [prog_exists nispasswd] {
+ radiobutton .nispasswd -text nispasswd -variable passwd_cmd \
+ -value {nispasswd {niscat passwd}} \
+ -anchor w -command get_users -relief flat
+ pack .nispasswd -in .type -fill x
+}
+pack .type -fill x
+
+frame .sort -relief raised -bd 1
+radiobutton .unsorted -text unsorted -variable sort_cmd -value " " \
+ -anchor w -relief flat -command get_users
+radiobutton .name -text name -variable sort_cmd -value "| sort" \
+ -anchor w -relief flat -command get_users
+radiobutton .uid -text uid -variable sort_cmd -value "| sort -t: -n +2" \
+ -anchor w -relief flat -command get_users
+pack .unsorted .name .uid -in .sort -fill x
+pack .sort -fill x
+
+frame .users -relief raised -bd 1
+# has to be wide enough for 8+1+5=14
+text .names -yscrollcommand ".scroll set" -width 14 -height 1 \
+ -font "*-bold-o-normal-*-120-*-m-*" -setgrid 1
+.names tag configure nopassword -relief raised
+.names tag configure selection -relief raised
+
+set iscolor 0
+if {[winfo depth .] > 1} {
+ set iscolor 1
+}
+
+if {$iscolor} {
+ .names tag configure nopassword -background red
+ .names tag configure selection -background green
+} else {
+ .names tag configure nopassword -background black -foreground white
+ .names tag configure selection -background white -foreground black
+}
+scrollbar .scroll -command ".names yview" -relief raised
+pack .scroll -in .users -side left -fill y
+pack .names -in .users -side left -fill y
+pack .users -expand 1 -fill y
+
+wm minsize . 14 1
+wm maxsize . 14 999
+wm geometry . 14x10
+
+frame .password_frame -relief raised -bd 1
+entry .password -textvar password -relief sunken -width 1
+focus .password
+bind .password <Return> password_set
+label .prompt -text "Password:" -bd 0
+button .password_set -text "set" -command password_set
+button .generate_button -text "generate" -command password_generate
+pack .prompt .password -in .password_frame -fill x -padx 2 -pady 2
+pack .password_set .generate_button -in .password_frame -side left -expand 1 -fill x -padx 2 -pady 2
+pack .password_frame -fill x
+
+set dict_loaded 0
+checkbutton .dict -text "test dictionary" -variable dict_check \
+ -command {if !$dict_loaded load_dict} \
+ -anchor w
+pack .dict -fill x -padx 2 -pady 2
+
+
+button .quit -text quit -command exit
+button .help_button -text help -command help
+pack .quit .help_button -side left -expand 1 -fill x -padx 2 -pady 2
+
+proc help {} {
+ if [catch {toplevel .help}] return
+ message .help.text -text \
+"tkpasswd - written by Don Libes, NIST, 10/1/93.
+
+Click on passwd (local users) or yppasswd (NIS users).\
+Select user using mouse (or keys - see below).\
+Enter password or press ^G to generate a random password.\
+(Press ^A to adjust the generation parameters.)\
+Press return to set the password.\
+If the dictionary is enabled and the password is in it,\
+the password is rejected.
+
+You must be root to set local passwords besides your own.\
+If you are not root, you must also enter an old password\
+when requested.
+
+You do not have to move mouse into password field(s) to enter password.\
+^U clears password field.\
+^N and ^P select next/previous user.\
+M-n and M-p select next/previous user with no password.\
+(Users with no passwords are highlighted.)"
+
+ button .help.ok -text "ok" -command {destroy .help}
+ pack .help.text
+ pack .help.ok -fill x -padx 2 -pady 2
+}
+
+# get list of local users
+proc get_users {} {
+ global sort_cmd passwd_cmd
+ global nopasswords ;# line numbers of entries with no passwords
+ global last_line ;# last line of text box
+ global selection_line
+
+ .names delete 1.0 end
+
+ set file [open "|[lindex $passwd_cmd 1] $sort_cmd"]
+ set last_line 1
+ set nopasswords {}
+ while {[gets $file buf] != -1} {
+ set buf [split $buf :]
+ if [llength $buf]>2 {
+ # normal password entry
+ .names insert end "[format "%-8.8s %5d" [lindex $buf 0] [lindex $buf 2]]\n"
+ if 0==[string compare [lindex $buf 1] ""] {
+ .names tag add nopassword \
+ {end - 2 line linestart} \
+ {end - 2 line lineend}
+ lappend nopasswords $last_line
+ }
+ } else {
+ # +name style entry
+ .names insert end "$buf\n"
+ }
+ incr last_line
+ }
+ incr last_line -1
+ close $file
+ set selection_line 0
+}
+
+proc feedback {msg} {
+ global password
+
+ set password $msg
+ .password select from 0
+ .password select to end
+ update
+}
+
+proc load_dict {} {
+ global dict dict_loaded
+
+ feedback "loading dictionary..."
+
+ if 0==[catch {open /usr/dict/words} file] {
+ rename set s
+ foreach w [split [read $file] "\n"] {s dict($w) ""}
+ close $file
+ rename s set
+ set dict_loaded 1
+ feedback "dictionary loaded"
+ } else {
+ feedback "dictionary missing"
+ .dict deselect
+ }
+}
+
+# put whatever security checks you like in here
+proc weak_password {password} {
+ global dict dict_check
+
+ if $dict_check {
+ feedback "checking password"
+
+ if [info exists dict($password)] {
+ feedback "sorry - in dictionary"
+ return 1
+ }
+ }
+ return 0
+}
+
+proc password_set {} {
+ global password passwd_cmd selection_line
+
+ set new_password $password
+
+ if {$selection_line==0} {
+ feedback "select a user first"
+ return
+ }
+ set user [lindex [.names get selection.first selection.last] 0]
+
+ if [weak_password $password] return
+
+ feedback "setting password . . ."
+
+ set cmd [lindex $passwd_cmd 0]
+ spawn -noecho $cmd $user
+ log_user 0
+ set last_msg "error in $cmd"
+ while 1 {
+ expect {
+ -nocase "old password:" {
+ exp_send "[get_old_password]\r"
+ } "assword*:" {
+ exp_send "$new_password\r"
+ } -re "(.*)\r\n" {
+ set last_msg $expect_out(1,string)
+ } eof break
+ }
+ }
+ set status [wait]
+ if [lindex $status 3]==0 {
+ feedback "set successfully"
+ } else {
+ feedback $last_msg
+ }
+}
+
+# defaults for generating passwords
+set length 9
+set minnum 2
+set minlower 5
+set minupper 2
+set distribute 0
+
+proc parameter_filename {} {
+ set file .tkpasswd.rc
+ if [info exists env(DOTDIR)] {
+ set file "$env(DOTDIR)/$file"
+ }
+ return ~/$file
+}
+
+catch {source [parameter_filename]}
+
+# save parameters in a file
+proc save_parameters {} {
+ global minnum minlower minupper length
+
+ if [catch {open [parameter_filename] w} f] {
+ # should never happen, so don't bother with window code
+ puts "tkpasswd: could not write [parameter_filename]"
+ return
+ }
+ puts $f "# This is the .tkpasswd.rc file. Do not edit it by hand as"
+ puts $f "# it is automatically maintained by tkpasswd. Any manual"
+ puts $f "# modifications will be lost."
+ puts $f ""
+ puts $f "set length $length"
+ puts $f "set minnum $minnum"
+ puts $f "set minupper $minupper"
+ puts $f "set minlower $minlower"
+ close $f
+}
+
+# insert char into password at a random position
+proc insert {pvar char} {
+ upvar $pvar p
+
+ set p [linsert $p [rand [expr 1+[llength $p]]] $char]
+}
+
+# given a size, distribute between left and right hands
+# taking into account where we left off
+proc psplit {max lvar rvar} {
+ upvar $lvar left $rvar right
+ global isleft
+
+ if {$isleft} {
+ set right [expr $max/2]
+ set left [expr $max-$right]
+ set isleft [expr !($max%2)]
+ } else {
+ set left [expr $max/2]
+ set right [expr $max-$left]
+ set isleft [expr $max%2]
+ }
+}
+
+proc password_generate {} {
+ global password length minnum minlower minupper
+ global lpass rpass initially_left isleft
+ global distribute
+
+ if {$distribute} {
+ set lkeys {q w e r t a s d f g z x c v b}
+ set rkeys {y u i o p h j k l n m}
+ set lnums {1 2 3 4 5 6}
+ set rnums {7 8 9 0}
+ } else {
+ set lkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+ set rkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+ set lnums {0 1 2 3 4 5 6 7 8 9}
+ set rnums {0 1 2 3 4 5 6 7 8 9}
+ }
+ set lkeys_length [llength $lkeys]
+ set rkeys_length [llength $rkeys]
+ set lnums_length [llength $lnums]
+ set rnums_length [llength $rnums]
+
+ # if there is any underspecification, use additional lowercase letters
+ set minlower [expr $length - ($minnum + $minupper)]
+
+
+ set lpass "" ;# password chars typed by left hand
+ set rpass "" ;# password chars typed by right hand
+ set password "" ;# merged password
+
+ # choose left or right starting hand
+ set initially_left [set isleft [rand 2]]
+
+ psplit $minnum left right
+ for {set i 0} {$i<$left} {incr i} {
+ insert lpass [lindex $lnums [rand $lnums_length]]
+ }
+ for {set i 0} {$i<$right} {incr i} {
+ insert rpass [lindex $rnums [rand $rnums_length]]
+ }
+
+ psplit $minlower left right
+ for {set i 0} {$i<$left} {incr i} {
+ insert lpass [lindex $lkeys [rand $lkeys_length]]
+ }
+ for {set i 0} {$i<$right} {incr i} {
+ insert rpass [lindex $rkeys [rand $rkeys_length]]
+ }
+
+ psplit $minupper left right
+ for {set i 0} {$i<$left} {incr i} {
+ insert lpass [string toupper [lindex $lkeys [rand $lkeys_length]]]
+ }
+ for {set i 0} {$i<$right} {incr i} {
+ insert rpass [string toupper [lindex $rkeys [rand $rkeys_length]]]
+ }
+
+ # merge results together
+ if {$initially_left} {
+ regexp "(\[^ ]*) *(.*)" "$lpass" x password lpass
+ while {[llength $lpass]} {
+ regexp "(\[^ ]*) *(.*)" "$password$rpass" x password rpass
+ regexp "(\[^ ]*) *(.*)" "$password$lpass" x password lpass
+ }
+ if {[llength $rpass]} {
+ append password $rpass
+ }
+ } else {
+ regexp "(\[^ ]*) *(.*)" "$rpass" x password rpass
+ while {[llength $rpass]} {
+ regexp "(\[^ ]*) *(.*)" "$password$lpass" x password lpass
+ regexp "(\[^ ]*) *(.*)" "$password$rpass" x password rpass
+ }
+ if {[llength $lpass]} {
+ append password $lpass
+ }
+ }
+}
+
+set _ran [pid]
+proc rand {m} {
+ global _ran
+
+ set period 259200
+ set _ran [expr ($_ran*7141 + 54773) % $period]
+ expr int($m*($_ran/double($period)))
+}
+
+proc gen_bad_args {msg} {
+ if ![llength [info commands .parameters.errmsg]] {
+ message .parameters.errmsg -aspect 300
+ pack .parameters.errmsg
+ }
+ .parameters.errmsg configure -text "$msg\
+Please adjust the password generation arguments."
+}
+
+
+# tell tab what window to move between
+set parm_tabList {}
+
+# The procedure below is invoked in response to tabs in the entry
+# windows. It moves the focus to the next window in the tab list.
+# Arguments:
+#
+# list - Ordered list of windows to receive focus
+
+proc Tab {list} {
+ set i [lsearch $list [focus]]
+ if {$i < 0} {
+ set i 0
+ } else {
+ incr i
+ if {$i >= [llength $list]} {
+ set i 0
+ }
+ }
+ focus [lindex $list $i]
+}
+
+# adjust args used in password generation
+proc adjust_parameters {} {
+ global parm_tabList
+ set parm_tabList {}
+
+ toplevel [set w .parameters]
+
+# wm title $w ""
+# wm iconname $w ""
+
+ message $w.text -aspect 300 -text \
+"These parameters control generation of random passwords.
+
+It is not necessary to move the mouse into this window to operate it.\
+Press <tab> to move to the next entry.\
+Press <return> or click the <ok> button when you are done."
+
+ foreach desc {
+ {length {total length}}
+ {minnum {minimum number of digits}}
+ {minupper {minimum number of uppercase letters}}
+ {minlower {minimum number of lowercase letters}}} {
+ set name [lindex $desc 0]
+ set text [lindex $desc 1]
+ frame $w.$name -bd 1
+ entry $w.$name.entry -relief sunken -width 2 -textvar $name
+ bind $w.$name.entry <Tab> "Tab \$parm_tabList"
+ bind $w.$name.entry <Return> "destroy_parm_window"
+ label $w.$name.text -text $text
+ pack $w.$name.entry -side left
+ pack $w.$name.text -side left
+ lappend parm_tabList $w.$name.entry
+ }
+ frame $w.2 -bd 1
+ checkbutton $w.2.cb -text "alternate characters across hands" \
+ -relief flat -variable distribute
+ pack $w.2.cb -side left
+
+ button $w.ok -text "ok" -command "destroy_parm_window"
+ pack $w.text -expand 1 -fill x
+ pack $w.length $w.minnum $w.minupper $w.minlower $w.2 -expand 1 -fill x
+ pack $w.ok -side left -fill x -expand 1 -padx 2 -pady 2
+
+#strace 10
+ set oldfocus [focus]
+# $w.length.entry icursor end
+ tkwait visibility $w.length.entry
+ focus $w.length.entry
+# grab $w
+ tkwait window $w
+# grab release $w
+ focus $oldfocus
+
+#strace 0
+
+ save_parameters
+}
+
+proc isnumber {n} {
+ regexp "^\[0-9\]+$" $n
+}
+
+# destroy parm window IF all values are legal
+proc destroy_parm_window {} {
+ global minnum minlower minupper length
+
+ set mustbe "must be a number greater than or equal to zero."
+
+ # check all variables
+ if {![isnumber $length]} {
+ gen_bad_args "The total length $mustbe"
+ return
+ }
+ if {![isnumber $minlower]} {
+ gen_bad_args "The minimum number of lowercase characters $mustbe"
+ return
+ }
+ if {![isnumber $minupper]} {
+ gen_bad_args "The minimum number of uppercase characters $mustbe"
+ return
+ }
+ if {![isnumber $minnum]} {
+ gen_bad_args "The minimum number of digits $mustbe"
+ return
+ }
+
+ # check constraints
+ if {$minnum + $minlower + $minupper > $length} {
+ gen_bad_args \
+"It is impossible to generate a $length-character password with\
+$minnum number[pluralize $minnum],\
+$minlower lowercase letter[pluralize $minlower], and\
+$minupper uppercase letter[pluralize $minupper]."
+ return
+ }
+
+ destroy .parameters
+}
+
+# return appropriate ending for a count of "n" nouns
+proc pluralize {n} {
+ expr $n!=1?"s":""
+}
+
+
+proc get_old_password {} {
+ global old
+
+ toplevel .old
+ label .old.label -text "Old password:"
+ catch {unset old}
+ entry .old.entry -textvar old -relief sunken -width 1
+
+ pack .old.label
+ pack .old.entry -fill x -padx 2 -pady 2
+
+ bind .old.entry <Return> {destroy .old}
+ set oldfocus [focus]
+ focus .old.entry
+ tkwait visibility .old
+ grab .old
+ tkwait window .old
+ focus $oldfocus
+ return $old
+}
+
+.unsorted select
+.passwd invoke
+
+proc make_selection {} {
+ global selection_line last_line
+
+ .names tag remove selection 0.0 end
+
+ # don't let selection go off top of screen
+ if {$selection_line < 1} {
+ set selection_line $last_line
+ } elseif {$selection_line > $last_line} {
+ set selection_line 1
+ }
+ .names yview -pickplace [expr $selection_line-1]
+ .names tag add selection $selection_line.0 [expr 1+$selection_line].0
+}
+
+proc select_next_nopassword {direction} {
+ global selection_line last_line
+ global nopasswords
+
+ if 0==[llength $nopasswords] {
+ feedback "no null passwords"
+ return
+ }
+
+ if $direction==1 {
+ # is there a better way to get last element of list?
+ if $selection_line>=[lindex $nopasswords [expr [llength $nopasswords]-1]] {
+ set selection_line 0
+ }
+ foreach i $nopasswords {
+ if $selection_line<$i break
+ }
+ } else {
+ if $selection_line<=[lindex $nopasswords 0] {
+ set selection_line $last_line
+ }
+ set j [expr [llength $nopasswords]-1]
+ for {} {$j>=0} {incr j -1} {
+ set i [lindex $nopasswords $j]
+ if $selection_line>$i break
+ }
+ }
+ set selection_line $i
+ make_selection
+}
+
+proc select {w coords} {
+ global selection_line
+
+ $w mark set insert "@$coords linestart"
+ $w mark set anchor insert
+ set first [$w index "anchor linestart"]
+ set last [$w index "insert lineend + 1c"]
+ scan $first %d selection_line
+
+ $w tag remove selection 0.0 end
+ $w tag add selection $first $last
+}
+
+bind Text <1> {select %W %x,%y}
+bind Text <Double-1> {select %W %x,%y}
+bind Text <Triple-1> {select %W %x,%y}
+bind Text <2> {select %W %x,%y}
+bind Text <3> {select %W %x,%y}
+bind Text <B1-Motion> {}
+bind Text <Shift-1> {}
+bind Text <Shift-B1-Motion> {}
+bind Text <B2-Motion> {}
+
+bind .password <Control-n> {incr selection_line 1; make_selection}
+bind .password <Control-p> {incr selection_line -1;make_selection}
+bind .password <Meta-n> {select_next_nopassword 1}
+bind .password <Meta-p> {select_next_nopassword -1}
+bind .password <Control-g> {password_generate}
+bind .password <Control-a> {adjust_parameters}
+bind .password <Control-u> {set password ""}
+bind Entry <Control-c> {exit}
diff --git a/expect/example/tkterm b/expect/example/tkterm
new file mode 100755
index 00000000000..c143fbba984
--- /dev/null
+++ b/expect/example/tkterm
@@ -0,0 +1,409 @@
+#!../expectk -f
+
+# Name: tkterm - terminal emulator using Expect and Tk text widget, v1.0
+# Author: Don Libes, July '94
+
+# This is primarily for regression testing character-graphic applications.
+# You can certainly use it as a terminal emulator - however many features
+# in a real terminal emulator are not supported (although I'll probably
+# add some of them later).
+
+# A paper on the implementation: Libes, D., Automation and Testing of
+# Interactive Character Graphic Programs", Software - Practice &
+# Experience, John Wiley & Sons, West Sussex, England, Vol. 27(2),
+# p. 123-137, February 1997.
+
+###############################
+# Quick overview of this emulator
+###############################
+# Very good attributes:
+# Understands both termcap and terminfo
+# Understands meta-key (zsh, emacs, etc work)
+# Is fast
+# Understands X selections
+# Looks best with fixed-width font but doesn't require it
+# Good-enough-for-starters attributes:
+# Understands one kind of standout mode (reverse video)
+# Should-be-fixed-soon attributes:
+# Does not support scrollbar or resize
+# Probably-wont-be-fixed-soon attributes:
+# Assumes only one terminal exists
+
+###############################################
+# To try out this package, just run it. Using it in
+# your scripts is simple. Here are directions:
+###############################################
+# 0) make sure Expect is linked into your Tk-based program (or vice versa)
+# 1) modify the variables/procedures below these comments appropriately
+# 2) source this file
+# 3) pack the text widget ($term) if you have so configured it (see
+# "term_alone" below). As distributed, it packs into . automatically.
+
+#############################################
+# Variables that must be initialized before using this:
+#############################################
+set rows 24 ;# number of rows in term
+set cols 80 ;# number of columns in term
+set term .t ;# name of text widget used by term
+set term_alone 1 ;# if 1, directly pack term into .
+ ;# else you must pack
+set termcap 1 ;# if your applications use termcap
+set terminfo 1 ;# if your applications use terminfo
+ ;# (you can use both, but note that
+ ;# starting terminfo is slow)
+set term_shell $env(SHELL) ;# program to run in term
+
+#############################################
+# Readable variables of interest
+#############################################
+# cur_row ;# current row where insert marker is
+# cur_col ;# current col where insert marker is
+# term_spawn_id ;# spawn id of term
+
+#############################################
+# Procs you may want to initialize before using this:
+#############################################
+
+# term_exit is called if the spawned process exits
+proc term_exit {} {
+ exit
+}
+
+# term_chars_changed is called after every change to the displayed chars
+# You can use if you want matches to occur in the background (a la bind)
+# If you want to test synchronously, then just do so - you don't need to
+# redefine this procedure.
+proc term_chars_changed {} {
+}
+
+# term_cursor_changed is called after the cursor is moved
+proc term_cursor_changed {} {
+}
+
+# Example tests you can make
+#
+# Test if cursor is at some specific location
+# if {$cur_row == 1 && $cur_col == 0} ...
+#
+# Test if "foo" exists anywhere in line 4
+# if {[string match *foo* [$term get 4.0 4.end]]}
+#
+# Test if "foo" exists at line 4 col 7
+# if {[string match foo* [$term get 4.7 4.end]]}
+#
+# Test if a specific character at row 4 col 5 is in standout
+# if {-1 != [lsearch [$term tag names 4.5] standout]} ...
+#
+# Return contents of screen
+# $term get 1.0 end
+#
+# Return indices of first string on lines 4 to 6 that is in standout mode
+# $term tag nextrange standout 4.0 6.end
+#
+# Replace all occurrences of "foo" with "bar" on screen
+# for {set i 1} {$i<=$rows} {incr i} {
+# regsub -all "foo" [$term get $i.0 $i.end] "bar" x
+# $term delete $i.0 $i.end
+# $term insert $i.0 $x
+# }
+
+#############################################
+# End of things of interest
+#############################################
+
+
+unset env(DISPLAY)
+set env(LINES) $rows
+set env(COLUMNS) $cols
+
+set env(TERM) "tt"
+if $termcap {
+ set env(TERMCAP) {tt:
+ :cm=\E[%d;%dH:
+ :up=\E[A:
+ :nd=\E[C:
+ :cl=\E[H\E[J:
+ :do=^J:
+ :so=\E[7m:
+ :se=\E[m:
+ :k1=\EOP:
+ :k2=\EOQ:
+ :k3=\EOR:
+ :k4=\EOS:
+ :k5=\EOT:
+ :k6=\EOU:
+ :k7=\EOV:
+ :k8=\EOW:
+ :k9=\EOX:
+ }
+}
+
+if $terminfo {
+ set env(TERMINFO) /tmp
+ set ttsrc "/tmp/tt.src"
+ set file [open $ttsrc w]
+
+ puts $file {tt|textterm|Don Libes' tk text widget terminal emulator,
+ cup=\E[%p1%d;%p2%dH,
+ cuu1=\E[A,
+ cuf1=\E[C,
+ clear=\E[H\E[J,
+ ind=\n,
+ cr=\r,
+ smso=\E[7m,
+ rmso=\E[m,
+ kf1=\EOP,
+ kf2=\EOQ,
+ kf3=\EOR,
+ kf4=\EOS,
+ kf5=\EOT,
+ kf6=\EOU,
+ kf7=\EOV,
+ kf8=\EOW,
+ kf9=\EOX,
+ }
+ close $file
+
+ set oldpath $env(PATH)
+ set env(PATH) "/usr/5bin:/usr/lib/terminfo"
+ if 1==[catch {exec tic $ttsrc} msg] {
+ puts "WARNING: tic failed - if you don't have terminfo support on"
+ puts "your system, change \"set terminfo 1\" to \"set terminfo 0\"."
+ puts "Here is the original error from running tic:"
+ puts $msg
+ }
+ set env(PATH) $oldpath
+
+ exec rm $ttsrc
+}
+
+set term_standout 0 ;# if in standout mode or not
+
+log_user 0
+
+# start a shell and text widget for its output
+set stty_init "-tabs"
+eval spawn $term_shell
+stty rows $rows columns $cols < $spawn_out(slave,name)
+set term_spawn_id $spawn_id
+
+# this shouldn't be needed if Ousterhout fixes text bug
+text $term -relief sunken -bd 1 -width $cols -height $rows -wrap none
+
+if {$term_alone} {
+ pack $term
+}
+
+$term tag configure standout -background black -foreground white
+
+proc term_clear {} {
+ global term
+
+ $term delete 1.0 end
+ term_init
+}
+
+proc term_init {} {
+ global rows cols cur_row cur_col term
+
+ # initialize it with blanks to make insertions later more easily
+ set blankline [format %*s $cols ""]\n
+ for {set i 1} {$i <= $rows} {incr i} {
+ $term insert $i.0 $blankline
+ }
+
+ set cur_row 1
+ set cur_col 0
+
+ $term mark set insert $cur_row.$cur_col
+}
+
+proc term_down {} {
+ global cur_row rows cols term
+
+ if {$cur_row < $rows} {
+ incr cur_row
+ } else {
+ # already at last line of term, so scroll screen up
+ $term delete 1.0 "1.end + 1 chars"
+
+ # recreate line at end
+ $term insert end [format %*s $cols ""]\n
+ }
+}
+
+proc term_insert {s} {
+ global cols cur_col cur_row
+ global term term_standout
+
+ set chars_rem_to_write [string length $s]
+ set space_rem_on_line [expr $cols - $cur_col]
+
+ if {$term_standout} {
+ set tag_action "add"
+ } else {
+ set tag_action "remove"
+ }
+
+ ##################
+ # write first line
+ ##################
+
+ if {$chars_rem_to_write > $space_rem_on_line} {
+ set chars_to_write $space_rem_on_line
+ set newline 1
+ } else {
+ set chars_to_write $chars_rem_to_write
+ set newline 0
+ }
+
+ $term delete $cur_row.$cur_col $cur_row.[expr $cur_col + $chars_to_write]
+ $term insert $cur_row.$cur_col [
+ string range $s 0 [expr $space_rem_on_line-1]
+ ]
+
+ $term tag $tag_action standout $cur_row.$cur_col $cur_row.[expr $cur_col + $chars_to_write]
+
+ # discard first line already written
+ incr chars_rem_to_write -$chars_to_write
+ set s [string range $s $chars_to_write end]
+
+ # update cur_col
+ incr cur_col $chars_to_write
+ # update cur_row
+ if $newline {
+ term_down
+ }
+
+ ##################
+ # write full lines
+ ##################
+ while {$chars_rem_to_write >= $cols} {
+ $term delete $cur_row.0 $cur_row.end
+ $term insert $cur_row.0 [string range $s 0 [expr $cols-1]]
+ $term tag $tag_action standout $cur_row.0 $cur_row.end
+
+ # discard line from buffer
+ set s [string range $s $cols end]
+ incr chars_rem_to_write -$cols
+
+ set cur_col 0
+ term_down
+ }
+
+ #################
+ # write last line
+ #################
+
+ if {$chars_rem_to_write} {
+ $term delete $cur_row.0 $cur_row.$chars_rem_to_write
+ $term insert $cur_row.0 $s
+ $term tag $tag_action standout $cur_row.0 $cur_row.$chars_rem_to_write
+ set cur_col $chars_rem_to_write
+ }
+
+ term_chars_changed
+}
+
+proc term_update_cursor {} {
+ global cur_row cur_col term
+
+ $term mark set insert $cur_row.$cur_col
+
+ term_cursor_changed
+}
+
+term_init
+
+set flush 0
+proc screen_flush {} {
+ global flush
+ incr flush
+ if {$flush == 24} {
+ update idletasks
+ set flush 0
+ }
+# update idletasks
+# after 1000 a
+}
+
+
+
+expect_background {
+ -i $term_spawn_id
+ -re "^\[^\x01-\x1f]+" {
+ # Text
+ term_insert $expect_out(0,string)
+ term_update_cursor
+ } "^\r" {
+ # (cr,) Go to beginning of line
+ screen_flush
+ set cur_col 0
+ term_update_cursor
+ } "^\n" {
+ # (ind,do) Move cursor down one line
+ term_down
+ term_update_cursor
+ } "^\b" {
+ # Backspace nondestructively
+ incr cur_col -1
+ term_update_cursor
+ } "^\a" {
+ bell
+ } "^\t" {
+ # Tab, shouldn't happen
+ send_error "got a tab!?"
+ } eof {
+ term_exit
+ } "^\x1b\\\[A" {
+ # (cuu1,up) Move cursor up one line
+ incr cur_row -1
+ term_update_cursor
+ } "^\x1b\\\[C" {
+ # (cuf1,nd) Non-destructive space
+ incr cur_col
+ term_update_cursor
+ } -re "^\x1b\\\[(\[0-9]*);(\[0-9]*)H" {
+ # (cup,cm) Move to row y col x
+ set cur_row [expr $expect_out(1,string)+1]
+ set cur_col $expect_out(2,string)
+ term_update_cursor
+ } "^\x1b\\\[H\x1b\\\[J" {
+ # (clear,cl) Clear screen
+ term_clear
+ term_update_cursor
+ } "^\x1b\\\[7m" {
+ # (smso,so) Begin standout mode
+ set term_standout 1
+ } "^\x1b\\\[m" {
+ # (rmso,se) End standout mode
+ set term_standout 0
+ }
+}
+
+bind $term <Any-Enter> {
+ focus %W
+}
+bind $term <Meta-KeyPress> {
+ if {"%A" != ""} {
+ exp_send -i $term_spawn_id "\033%A"
+ }
+}
+
+bind $term <KeyPress> {
+ exp_send -i $term_spawn_id -- %A
+ break
+}
+
+bind $term <Control-space> {exp_send -null}
+bind $term <Control-at> {exp_send -null}
+
+bind $term <F1> {exp_send -i $term_spawn_id "\033OP"}
+bind $term <F2> {exp_send -i $term_spawn_id "\033OQ"}
+bind $term <F3> {exp_send -i $term_spawn_id "\033OR"}
+bind $term <F4> {exp_send -i $term_spawn_id "\033OS"}
+bind $term <F5> {exp_send -i $term_spawn_id "\033OT"}
+bind $term <F6> {exp_send -i $term_spawn_id "\033OU"}
+bind $term <F7> {exp_send -i $term_spawn_id "\033OV"}
+bind $term <F8> {exp_send -i $term_spawn_id "\033OW"}
+bind $term <F9> {exp_send -i $term_spawn_id "\033OX"}
diff --git a/expect/example/unbuffer b/expect/example/unbuffer
new file mode 100755
index 00000000000..f37ebc76c7f
--- /dev/null
+++ b/expect/example/unbuffer
@@ -0,0 +1,7 @@
+#!../expect --
+# Description: unbuffer stdout of a program
+# Author: Don Libes, NIST
+
+eval spawn -noecho $argv
+set timeout -1
+expect
diff --git a/expect/example/unbuffer.man b/expect/example/unbuffer.man
new file mode 100644
index 00000000000..66e18c62f02
--- /dev/null
+++ b/expect/example/unbuffer.man
@@ -0,0 +1,41 @@
+.TH UNBUFFER 1 "1 June 1994"
+.SH NAME
+unbuffer \- unbuffer output
+.SH SYNOPSIS
+.B unbuffer
+.I program
+[
+.I args
+]
+.SH INTRODUCTION
+.B unbuffer
+disables the output buffering that occurs when program output
+is redirected.
+For example, suppose you are watching the output from a fifo by running it
+through od and then more.
+.nf
+
+ od -c /tmp/fifo | more
+
+.fi
+You will not see anything until a full page
+of output has been produced.
+
+You can disable this automatic buffering as follows:
+
+.nf
+
+ unbuffer od -c /tmp/fifo | more
+
+.fi
+.SH BUGS
+
+The man page is longer than the program.
+
+.SH SEE ALSO
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
diff --git a/expect/example/virterm b/expect/example/virterm
new file mode 100755
index 00000000000..a703081b37d
--- /dev/null
+++ b/expect/example/virterm
@@ -0,0 +1,634 @@
+#!../expect --
+
+# Name: virterm - terminal emulator using Expect, v1.0, December, 1994
+# Author: Adrian Mariano <adrian@cam.cornell.edu>
+#
+# Derived from Done Libes' tkterm
+
+# This is a program for interacting with applications that use terminal
+# control sequences. It is a subset of Don Libes' tkterm emulator
+# with a compatible interface so that programs can be written to work
+# under both.
+#
+# Internally, it uses arrays instead of the Tk widget. Nonetheless, this
+# code is not as fast as it should be. I need an Expect profiler to go
+# any further.
+#
+# standout mode is not supported like it is in tkterm.
+# the only terminal widget operation that is supported for the user
+# is the "get" operation.
+###############################################
+# Variables that must be initialized before using this:
+#############################################
+set rows 24 ;# number of rows in term
+set cols 80 ;# number of columns in term
+set term myterm ;# name of text widget used by term
+set termcap 1 ;# if your applications use termcap
+set terminfo 0 ;# if your applications use terminfo
+ ;# (you can use both, but note that
+ ;# starting terminfo is slow)
+set term_shell $env(SHELL) ;# program to run in term
+
+#############################################
+# Readable variables of interest
+#############################################
+# cur_row ;# current row where insert marker is
+# cur_col ;# current col where insert marker is
+# term_spawn_id ;# spawn id of term
+
+#############################################
+# Procs you may want to initialize before using this:
+#############################################
+
+# term_exit is called if the associated proc exits
+proc term_exit {} {
+ exit
+}
+
+# term_chars_changed is called after every change to the displayed chars
+# You can use if you want matches to occur in the background (a la bind)
+# If you want to test synchronously, then just do so - you don't need to
+# redefine this procedure.
+proc term_chars_changed {} {
+}
+
+# term_cursor_changed is called after the cursor is moved
+proc term_cursor_changed {} {
+}
+
+# Example tests you can make
+#
+# Test if cursor is at some specific location
+# if {$cur_row == 1 && $cur_col == 0} ...
+#
+# Test if "foo" exists anywhere in line 4
+# if {[string match *foo* [$term get 4.0 4.end]]}
+#
+# Test if "foo" exists at line 4 col 7
+# if {[string match foo* [$term get 4.7 4.end]]}
+#
+# Return contents of screen
+# $term get 1.0 end
+
+#############################################
+# End of things of interest
+#############################################
+
+set blankline ""
+set env(LINES) $rows
+set env(COLUMNS) $cols
+
+set env(TERM) "tt"
+if $termcap {
+ set env(TERMCAP) {tt:
+ :cm=\E[%d;%dH:
+ :up=\E[A:
+ :cl=\E[H\E[J:
+ :do=^J:
+ :so=\E[7m:
+ :se=\E[m:
+ :nd=\E[C:
+ }
+}
+
+if $terminfo {
+ set env(TERMINFO) /tmp
+ set ttsrc "/tmp/tt.src"
+ set file [open $ttsrc w]
+
+ puts $file {tt|textterm|Don Libes' tk text widget terminal emulator,
+ cup=\E[%p1%d;%p2%dH,
+ cuu1=\E[A,
+ cuf1=\E[C,
+ clear=\E[H\E[J,
+ ind=\n,
+ cr=\r,
+ smso=\E[7m,
+ rmso=\E[m,
+ }
+ close $file
+
+ set oldpath $env(PATH)
+ set env(PATH) "/usr/5bin:/usr/lib/terminfo"
+ if 1==[catch {exec tic $ttsrc} msg] {
+ puts "WARNING: puts "tic failed - if you don't have terminfo support on"
+ puts "your system, change \"set terminfo 1\" to \"set terminfo 0\"."
+ puts "Here is the original error from running tic:"
+ puts $msg
+ }
+ set env(PATH) $oldpath
+
+ exec rm $ttsrc
+}
+
+log_user 0
+
+# start a shell and text widget for its output
+set stty_init "-tabs"
+eval spawn $term_shell
+stty rows $rows columns $cols < $spawn_out(slave,name)
+set term_spawn_id $spawn_id
+
+proc term_replace {reprow repcol text} {
+ global termdata
+ set middle $termdata($reprow)
+ set termdata($reprow) \
+ [string range $middle 0 [expr $repcol-1]]$text[string \
+ range $middle [expr $repcol+[string length $text]] end]
+}
+
+
+proc parseloc {input row col} {
+ upvar $row r $col c
+ global rows
+ switch -glob -- $input \
+ end { set r $rows; set c end } \
+ *.* { regexp (.*)\\.(.*) $input dummy r c
+ if {$r == "end"} { set r $rows }
+ }
+}
+
+proc myterm {command first second args} {
+ global termdata
+ if {[string compare get $command]} {
+ send_error "Unknown terminal command: $command\r"
+ } else {
+ parseloc $first startrow startcol
+ parseloc $second endrow endcol
+ if {$endcol != "end"} {incr endcol -1}
+ if {$startrow == $endrow} {
+ set data [string range $termdata($startrow) $startcol $endcol]
+ } else {
+ set data [string range $termdata($startrow) $startcol end]
+ for {set i [expr $startrow + 1]} {$i < $endrow} {incr i} {
+ append data $termdata($i)
+ }
+ append data [string range $termdata($endrow) 0 $endcol]
+ }
+ return $data
+ }
+}
+
+
+proc scrollup {} {
+ global termdata blankline
+ for {set i 1} {$i < $rows} {incr i} {
+ set termdata($i) $termdata([expr $i+1])
+ }
+ set termdata($rows) $blankline
+}
+
+
+proc term_init {} {
+ global rows cols cur_row cur_col term termdata blankline
+
+ # initialize it with blanks to make insertions later more easily
+ set blankline [format %*s $cols ""]\n
+ for {set i 1} {$i <= $rows} {incr i} {
+ set termdata($i) "$blankline"
+ }
+
+ set cur_row 1
+ set cur_col 0
+}
+
+
+proc term_down {} {
+ global cur_row rows cols term
+
+ if {$cur_row < $rows} {
+ incr cur_row
+ } else {
+ scrollup
+ }
+}
+
+
+proc term_insert {s} {
+ global cols cur_col cur_row term
+
+ set chars_rem_to_write [string length $s]
+ set space_rem_on_line [expr $cols - $cur_col]
+
+ ##################
+ # write first line
+ ##################
+
+ if {$chars_rem_to_write <= $space_rem_on_line} {
+ term_replace $cur_row $cur_col \
+ [string range $s 0 [expr $space_rem_on_line-1]]
+ incr cur_col $chars_rem_to_write
+ term_chars_changed
+ return
+ }
+
+ set chars_to_write $space_rem_on_line
+ set newline 1
+
+ term_replace $cur_row $cur_col\
+ [string range $s 0 [expr $space_rem_on_line-1]]
+
+ # discard first line already written
+ incr chars_rem_to_write -$chars_to_write
+ set s [string range $s $chars_to_write end]
+
+ # update cur_col
+ incr cur_col $chars_to_write
+ # update cur_row
+ if $newline {
+ term_down
+ }
+
+ ##################
+ # write full lines
+ ##################
+ while {$chars_rem_to_write >= $cols} {
+ term_replace $cur_row 0 [string range $s 0 [expr $cols-1]]
+
+ # discard line from buffer
+ set s [string range $s $cols end]
+ incr chars_rem_to_write -$cols
+
+ set cur_col 0
+ term_down
+ }
+
+ #################
+ # write last line
+ #################
+
+ if {$chars_rem_to_write} {
+ term_replace $cur_row 0 $s
+ set cur_col $chars_rem_to_write
+ }
+
+ term_chars_changed
+}
+
+term_init
+
+expect_before {
+ -i $term_spawn_id
+ -re "^\[^\x01-\x1f]+" {
+ # Text
+ term_insert $expect_out(0,string)
+ term_cursor_changed
+ } "^\r" {
+ # (cr,) Go to to beginning of line
+ set cur_col 0
+ term_cursor_changed
+ } "^\n" {
+ # (ind,do) Move cursor down one line
+ term_down
+ term_cursor_changed
+ } "^\b" {
+ # Backspace nondestructively
+ incr cur_col -1
+ term_cursor_changed
+ } "^\a" {
+ # Bell, pass back to user
+ send_user "\a"
+ } "^\t" {
+ # Tab, shouldn't happen
+ send_error "got a tab!?"
+ } eof {
+ term_exit
+ } "^\x1b\\\[A" {
+ # (cuu1,up) Move cursor up one line
+ incr cur_row -1
+ term_cursor_changed
+ } "^\x1b\\\[C" {
+ # (cuf1,nd) Nondestructive space
+ incr cur_col
+ term_cursor_changed
+ } -re "^\x1b\\\[(\[0-9]*);(\[0-9]*)H" {
+ # (cup,cm) Move to row y col x
+ set cur_row [expr $expect_out(1,string)+1]
+ set cur_col $expect_out(2,string)
+ term_cursor_changed
+ } "^\x1b\\\[H\x1b\\\[J" {
+ # (clear,cl) Clear screen
+ term_init
+ term_cursor_changed
+ } "^\x1b\\\[7m" { # unsupported
+ # (smso,so) Begin standout mode
+ # set term_standout 1
+ } "^\x1b\\\[m" { # unsupported
+ # (rmso,se) End standout mode
+ # set term_standout 0
+ }
+}
+
+
+proc term_expect {args} {
+ global cur_row cur_col # used by expect_background actions
+
+ set desired_timeout [
+ uplevel {
+ if [info exists timeout] {
+ set timeout
+ } else {
+ uplevel #0 {
+ if {[info exists timeout]} {
+ set timeout
+ } else {
+ expr 10
+ }
+ }
+ }
+ }
+ ]
+
+ set timeout $desired_timeout
+
+ set timeout_act {}
+
+ set argc [llength $args]
+ if {$argc%2 == 1} {
+ lappend args {}
+ incr argc
+ }
+
+ for {set i 0} {$i<$argc} {incr i 2} {
+ set act_index [expr $i+1]
+ if {[string compare timeout [lindex $args $i]] == 0} {
+ set timeout_act [lindex $args $act_index]
+ set args [lreplace $args $i $act_index]
+ incr argc -2
+ break
+ }
+ }
+
+ set got_timeout 0
+
+ set start_time [timestamp]
+
+ while {![info exists act]} {
+ expect timeout {set got_timeout 1}
+ set timeout [expr $desired_timeout - [timestamp] + $start_time]
+ if {! $got_timeout} \
+ {
+ for {set i 0} {$i<$argc} {incr i 2} {
+ if {[uplevel [lindex $args $i]]} {
+ set act [lindex $args [incr i]]
+ break
+ }
+ }
+ } else { set act $timeout_act }
+
+ if {![info exists act]} {
+
+ }
+ }
+
+ set code [catch {uplevel $act} string]
+ if {$code > 4} {return -code $code $string}
+ if {$code == 4} {return -code continue}
+ if {$code == 3} {return -code break}
+ if {$code == 2} {return -code return}
+ if {$code == 1} {return -code error -errorinfo $errorInfo \
+ -errorcode $errorCode $string}
+ return $string
+}
+
+
+# ======= end of terminal emulator ========
+
+# The following is a program to interact with the Cornell Library catalog
+
+
+proc waitfornext {} {
+ global cur_row cur_col term
+ term_expect {expr {$cur_col==15 && $cur_row == 24 &&
+ " NEXT COMMAND: " == [$term get 24.0 24.16]}} {}
+}
+
+proc sendcommand {command} {
+ global cur_col
+ exp_send $command
+ term_expect {expr {$cur_col == 79}} {}
+}
+
+proc removespaces {intext} {
+ regsub -all " *\n" $intext \n intext
+ regsub "\n+$" $intext \n intext
+ return $intext
+}
+
+proc output {text} {
+ exp_send_user $text
+}
+
+
+
+proc connect {} {
+ global term
+ term_expect {regexp {.*[>%]} [$term get 1.0 3.end]}
+ exp_send "tn3270 notis.library.cornell.edu\r"
+ term_expect {regexp "desk" [$term get 19.0 19.end]} {
+ exp_send "\r"
+ }
+ waitfornext
+ exp_send_error "connected.\n\n"
+}
+
+
+proc dosearch {search} {
+ global term
+ exp_send_error "Searching for '$search'..."
+ if [string match ?=* "$search"] {set typ ""} else {set typ "k="}
+ sendcommand "$typ$search\r"
+ waitfornext
+ set countstr [$term get 2.17 2.35]
+ if {![regsub { Entries Found *} $countstr "" number]} {
+ set number 1
+ exp_send_error "one entry found.\n\n"
+ return 1
+ }
+ if {$number == 0} {
+ exp_send_error "no matches.\n\n"
+ return 0
+ }
+ exp_send_error "$number entries found.\n"
+ if {$number > 250} {
+ exp_send_error "(only the first 250 can be displayed)\n"
+ }
+ exp_send_error "\n"
+ return $number
+}
+
+
+proc getshort {count} {
+ global term
+ output [removespaces [$term get 5.0 19.0]]
+ while {[regexp "CONTINUED on next page" [$term get 19.0 19.end]]} {
+ sendcommand "for\r"
+ waitfornext
+ output [removespaces [$term get 5.0 19.0]]
+ }
+}
+
+proc getonecitation {} {
+ global term
+ output [removespaces [$term get 4.0 19.0]]
+ while {[regexp "FORward page" [$term get 20.0 20.end]]} {
+ sendcommand "for\r"
+ waitfornext
+ output [removespaces [$term get 5.0 19.0]]
+ }
+}
+
+
+proc getcitlist {} {
+ global term
+ getonecitation
+ set citcount 1
+ while {[regexp "NEXt record" [$term get 20.0 21.end]]} {
+ sendcommand "nex\r"
+ waitfornext
+ getonecitation
+ incr citcount
+ if {$citcount % 10 == 0} {exp_send_error "$citcount.."}
+ }
+}
+
+proc getlong {count} {
+ if {$count != 1} {
+ sendcommand "1\r"
+ waitfornext
+ }
+ sendcommand "lon\r"
+ waitfornext
+ getcitlist
+}
+
+proc getmed {count} {
+ if {$count != 1} {
+ sendcommand "1\r"
+ waitfornext
+ }
+ sendcommand "bri\r"
+ waitfornext
+ getcitlist
+}
+
+#################################################################
+#
+set help {
+libsearch version 1.0 by Adrian Mariano (adrian@cam.cornell.edu)
+
+Invocation: libsearch [options] search text
+
+ -i : interactive
+ -s : short listing
+ -l : long listing
+ -o file : output file (default stdout)
+ -h : print out list of options and version number
+ -H : print terse keyword search help
+
+The search will be a keyword search.
+Example: libsearch -i sound and arabic
+
+}
+
+#################################################################
+
+proc searchhelp {} {
+ send_error {
+? truncation wildcard default operator is AND
+
+AND - both words appear in record
+OR - one of the words appears
+NOT - first word appears, second words does not
+ADJ - words are adjacent
+SAME- words appear in the same field (any order)
+
+.su. - subject b.fmt. - books eng.lng. - English
+.ti. - title m.fmt. - music spa.lng. - Spanish
+.au. - author s.fmt. - serials fre.lng. - French
+
+.dt. or .dt1. -- limits to a specific publication year. E.g., 1990.dt.
+
+}
+}
+
+proc promptuser {prompt} {
+ exp_send_error "$prompt"
+ expect_user -re "(.*)\n"
+ return "$expect_out(1,string)"
+}
+
+
+set searchtype 1
+set outfile ""
+set search ""
+set interactive 0
+
+while {[llength $argv]>0} {
+ set flag [lindex $argv 0]
+ switch -glob -- $flag \
+ "-i" { set interactive 1; set argv [lrange $argv 1 end]} \
+ "-s" { set searchtype 0; set argv [lrange $argv 1 end] } \
+ "-l" { set searchtype 2; set argv [lrange $argv 1 end] } \
+ "-o" { set outfile [lindex $argv 1]; set argv [lrange $argv 2 end] } \
+ "-H" { searchhelp; exit } \
+ "-h" { send_error "$help"; exit } \
+ "-*" { send_error "\nUnknown option: $flag\n$help";exit }\
+ default { set search [join $argv]; set argv {};}
+}
+if { "$search" == "" } {
+ send_error "No search specified\n$help"
+ exit
+}
+
+exp_send_error "Connecting to the library..."
+
+set timeout 200
+
+trap { log_user 1;exp_send "\003";
+ expect_before
+ expect tn3270 {exp_send "quit\r"}
+ expect "Connection closed." {exp_send "exit\r"}
+ expect eof ; send_error "\n";
+ exit} SIGINT
+
+
+connect
+
+set result [dosearch $search]
+
+if {$interactive} {
+ set quit 0
+ while {!$quit} {
+ if {!$result} {
+ switch "[promptuser {(h)elp (n)ewsearch (q)uit? }]" {
+ n { }
+ h { searchhelp }
+ q { set quit 1}
+ }
+ } else {
+ switch "[promptuser {(s)hort (m)ed (l)ong (h)elp (n)ewsearch (q)uit? }]" {
+ s { getshort $result; ;}
+ l { getlong $result; ;}
+ m { getmed $result; ; }
+ n { research; }
+ h { searchhelp }
+ q { set quit 1; }
+ }
+ }
+ }
+} else {
+ if {$result} {
+ switch $searchtype {
+ 0 { getshort $result}
+ 1 { getmed $result }
+ 2 { getlong $result }
+ }
+ }
+}
+
+
+
+
+
+
diff --git a/expect/example/vrfy b/expect/example/vrfy
new file mode 100755
index 00000000000..49c1b182c83
--- /dev/null
+++ b/expect/example/vrfy
@@ -0,0 +1,27 @@
+#!/depot/path/expect -f
+
+
+# separate address into user and host
+regexp (.*)@(.*) $argv ignore user host
+
+log_user 0
+set timeout -1
+
+# host might be an mx record, convert to a real host via nslookup
+spawn nslookup
+expect "> "
+send "set query=mx\r"
+expect "> "
+send "$host\r"
+expect {
+ "No mail exchanger" {}
+ -re "mail exchanger = (\[^\r]*)" {
+ set host $expect_out(1,string)
+ }
+}
+
+spawn telnet $host smtp
+expect "220*\r\n"
+send "vrfy $user\r"
+expect "250" {send_user "GOOD\n"} \
+ "550" {send_user "BAD\n"}
diff --git a/expect/example/weather b/expect/example/weather
new file mode 100755
index 00000000000..5007958093f
--- /dev/null
+++ b/expect/example/weather
@@ -0,0 +1,81 @@
+#!../expect -f
+
+# weather - Expect script to get the weather (courtesy University of Michigan)
+# Don Libes
+# Version 1.9
+
+# local weather is retrieved if no argument
+# argument is the National Weather Service designation for an area
+# I.e., WBC = Washington DC (oh yeah, that's obvious)
+
+exp_version -exit 5.0
+
+if $argc>0 {set code $argv} else {set code "WBC"}
+
+proc timedout {} {
+ send_user "Weather server timed out. Try again later when weather server is not so busy.\n"
+ exit 1
+}
+
+# delete special weather statement question
+proc delete_special {s} {
+ set x [string first " ******" $s]
+ return [join [lrange [split $s ""] 0 $x] ""]
+}
+
+set timeout 60
+log_user 0
+
+set env(TERM) vt100 ;# actual value doesn't matter, just has to be set
+
+spawn telnet downwind.sprl.umich.edu 3000
+match_max 100000
+for {} 1 {} {
+ expect timeout {
+ send_user "failed to contact weather server\n"
+ exit
+ } "Press Return to continue*" {
+ # this prompt used sometimes, eg, upon opening connection
+ send "\r"
+ } "Press Return for menu*" {
+ # this prompt used sometimes, eg, upon opening connection
+ send "\r"
+ } "M to display main menu*" {
+ # sometimes ask this if there is a weather watch in effect
+ send "M\r"
+ } "Change scrolling to screen*Selection:" {
+ break
+ } eof {
+ send_user "failed to telnet to weather server\n"
+ exit
+ }
+}
+send "C\r"
+expect timeout timedout "Selection:"
+send "4\r"
+expect timeout timedout "Selection:"
+send "1\r"
+expect timeout timedout "Selection:"
+send "1\r"
+expect timeout timedout "city code:"
+send "$code\r"
+expect $code ;# discard this
+
+for {} 1 {} {
+ expect timeout {
+ timedout
+ } "Press Return to continue*:*" {
+ send_user "\n[delete_special $expect_out(buffer)]\n"
+ send "\r"
+ } "Press Return to display statement, M for menu:*" {
+ send_user "\n[delete_special $expect_out(buffer)]\n"
+ send "\r"
+ } -re "(.*)CITY FORECAST MENU.*Selection:" {
+ send_user "\n$expect_out(1,string)\n"
+ break
+ }
+}
+
+send "X\r"
+expect
+
diff --git a/expect/example/xkibitz b/expect/example/xkibitz
new file mode 100755
index 00000000000..5b0d8ebfebb
--- /dev/null
+++ b/expect/example/xkibitz
@@ -0,0 +1,208 @@
+#!../expect --
+
+# share an xterm with other users
+# See xkibitz(1) man page for complete info.
+# Compare with kibitz.
+# Author: Don Libes, NIST
+# Version: 1.2
+
+proc help {} {
+ puts "Commands Meaning"
+ puts "-------- -------"
+ puts "return return to program"
+ puts "= list"
+ puts "+ <display> add"
+ puts "- <tag> drop"
+ puts "where <display> is an X display name such as nist.gov or nist.gov:0.0"
+ puts "and <tag> is a tag from the = command."
+ puts "+ and - require whitespace before argument."
+ puts {return command must be spelled out ("r", "e", "t", ...).}
+}
+
+proc prompt1 {} {
+ return "xkibitz> "
+}
+
+proc h {} help
+proc ? {} help
+
+# disable history processing - there seems to be some incestuous relationship
+# between history and unknown in Tcl 8.0
+proc history {args} {}
+proc unknown {args} {
+ puts "$args: invalid command"
+ help
+}
+
+set tag2pid(0) [pid]
+set pid2tty([pid]) "/dev/tty"
+if [info exists env(DISPLAY)] {
+ set pid2display([pid]) $env(DISPLAY)
+} else {
+ set pid2display([pid]) ""
+}
+
+# small int allowing user to more easily identify display
+# maxtag always points at highest in use
+set maxtag 0
+
+proc + {display} {
+ global ids pid2display pid2tag tag2pid maxtag pid2sid
+ global pid2tty env
+
+ if ![string match *:* $display] {
+ append display :0.0
+ }
+
+ if {![info exists env(XKIBITZ_XTERM_ARGS)]} {
+ set env(XKIBITZ_XTERM_ARGS) ""
+ }
+
+ set dummy1 [open /dev/null]
+ set dummy2 [open /dev/null]
+ spawn -pty -noecho
+ close $dummy1
+ close $dummy2
+
+ stty raw -echo < $spawn_out(slave,name)
+ # Linux needs additional stty, sounds like a bug in its stty to me.
+ # raw should imply this stuff, no?
+ stty -icrnl -icanon < $spawn_out(slave,name)
+
+ regexp ".*(.)(.)" $spawn_out(slave,name) dummy c1 c2
+ if {[string compare $c1 "/"] == 0} {
+ # On Pyramid and AIX, ttynames such as /dev/pts/1
+ # requre suffix to be padded with a 0
+ set c1 0
+ }
+
+ set pid [eval exec xterm \
+ -display $display \
+ -geometry [stty columns]x[stty rows] \
+ -S$c1$c2$spawn_out(slave,fd) \
+ $env(XKIBITZ_XTERM_ARGS) &]
+ close -slave
+
+ # xterm first sends back window id, discard
+ log_user 0
+ expect {
+ eof {wait;return}
+ \n
+ }
+ log_user 1
+
+ lappend ids $spawn_id
+ set pid2display($pid) $display
+ incr maxtag
+ set tag2pid($maxtag) $pid
+ set pid2tag($pid) $maxtag
+ set pid2sid($pid) $spawn_id
+ set pid2tty($pid) $spawn_out(slave,name)
+ return
+}
+
+proc = {} {
+ global pid2display tag2pid pid2tty
+
+ puts "Tag Size Display"
+ foreach tag [lsort -integer [array names tag2pid]] {
+ set pid $tag2pid($tag)
+ set tty $pid2tty($pid)
+
+ puts [format "%3d [stty columns < $tty]x[stty rows < $tty] $pid2display($pid)" $tag]
+ }
+}
+
+proc - {tag} {
+ global tag2pid pid2tag pid2display maxtag ids pid2sid
+ global pid2tty
+
+ if ![info exists tag2pid($tag)] {
+ puts "no such tag"
+ return
+ }
+ if {$tag == 0} {
+ puts "cannot drop self"
+ return
+ }
+
+ set pid $tag2pid($tag)
+
+ # close and remove spawn_id from list
+ set spawn_id $pid2sid($pid)
+ set index [lsearch $ids $spawn_id]
+ set ids [lreplace $ids $index $index]
+
+ exec kill -9 $pid
+ close
+ wait
+
+ unset tag2pid($tag)
+ unset pid2tag($pid)
+ unset pid2display($pid)
+ unset pid2sid($pid)
+ unset pid2tty($pid)
+
+ # lower maxtag if possible
+ while {![info exists tag2pid($maxtag)]} {
+ incr maxtag -1
+ }
+}
+
+exit -onexit {
+ unset pid2display([pid]) ;# avoid killing self
+
+ foreach pid [array names pid2display] {
+ catch {exec kill -9 $pid}
+ }
+}
+
+trap exit HUP
+
+trap {
+ set r [stty rows]
+ set c [stty columns]
+ stty rows $r columns $c < $app_tty
+ foreach pid [array names pid2tty] {
+ if {$pid == [pid]} continue
+ stty rows $r columns $c < $pid2tty($pid)
+ }
+} WINCH
+
+set escape \035 ;# control-right-bracket
+set escape_printable "^\]"
+
+while [llength $argv]>0 {
+ set flag [lindex $argv 0]
+ switch -- $flag \
+ "-escape" {
+ set escape [lindex $argv 1]
+ set escape_printable $escape
+ set argv [lrange $argv 2 end]
+ } "-display" {
+ + [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ } default {
+ break
+ }
+}
+
+if [llength $argv]>0 {
+ eval spawn -noecho $argv
+} else {
+ spawn -noecho $env(SHELL)
+}
+set prog $spawn_id
+set app_tty $spawn_out(slave,name)
+
+puts "Escape sequence is $escape_printable"
+
+interact {
+ -input $user_spawn_id -reset $escape {
+ puts "\nfor help enter: ? or h or help"
+ interpreter
+ } -output $prog
+ -input ids -output $prog
+ -input $prog -output $user_spawn_id -output ids
+}
+
diff --git a/expect/example/xkibitz.man b/expect/example/xkibitz.man
new file mode 100644
index 00000000000..c1d7fccb102
--- /dev/null
+++ b/expect/example/xkibitz.man
@@ -0,0 +1,170 @@
+.TH XKIBITZ 1 "06 October 1994"
+.SH NAME
+xkibitz \- allow multiple people to interact in an xterm
+.SH SYNOPSIS
+.B xkibitz
+[
+.I xkibitz-args
+] [
+.I program program-args...
+]
+.br
+.SH INTRODUCTION
+.B xkibitz
+allows users in separate xterms to share one shell (or any program
+that runs in an xterm). Uses include:
+.RS
+.TP 4
+\(bu
+A novice user can ask an expert user for help. Using
+.BR xkibitz ,
+the expert can see what the user is doing, and offer advice or
+show how to do it right.
+.TP
+\(bu
+By running
+.B xkibitz
+and then starting a full-screen editor, people may carry out a
+conversation, retaining the ability to scroll backwards,
+save the entire conversation, or even edit it while in progress.
+.TP
+\(bu
+People can team up on games, document editing, or other cooperative
+tasks where each person has strengths and weaknesses that complement one
+another.
+.TP
+\(bu
+If you want to have a large number of people do an on-line code
+walk-through, you can sit two in front of each workstation, and then
+connect them all together while you everyone looks at code together
+in the editor.
+.SH USAGE
+To start
+.BR xkibitz ,
+one user (the master) runs xkibitz with no arguments.
+
+.B xkibitz
+starts a new shell (or another program, if given on the command
+line). The user can interact normally with the shell, or
+upon entering an escape (described when xkibitz starts) can add
+users to the interaction.
+
+To add users, enter "+ display" where display is the X display name.
+If there is no ":X.Y" in the display name, ":0.0" is assumed.
+The master user must have permission to access each display.
+Each display is assigned
+a tag \- a small integer which can be used to reference the display.
+
+To show the current tags and displays, enter "=".
+
+To drop a display, enter "- tag" where tag is the display's tag
+according to the "=" command.
+
+To return to the shared shell, enter "return". Then the keystrokes of
+all users become the input of the shell. Similarly, all users receive
+the output from the shell.
+
+To terminate
+.B xkibitz
+it suffices to terminate the shell itself. For example, if any user
+types ^D (and the shell accepts this to be EOF), the shell terminates
+followed by
+.BR xkibitz .
+
+Normally, all characters are passed uninterpreted. However, in the
+escape dialogue the user talks directly to the
+.B xkibitz
+interpreter. Any
+.BR Expect (1)
+or
+.BR Tcl (3)
+commands may also be given.
+Also, job control may be used while in the interpreter, to, for example,
+suspend or restart
+.BR xkibitz .
+
+Various processes
+can produce various effects. For example, you can emulate a multi-way write(1)
+session with the command:
+
+ xkibitz sleep 1000000
+.PP
+.SH ARGUMENTS
+.B xkibitz
+understands a few special arguments
+which should appear before the
+.I program
+name (if given).
+Each argument should be separated by whitespace.
+If the arguments themselves takes arguments,
+these should also be separated by whitespace.
+
+.B \-escape
+sets the escape character. The default escape character is ^].
+
+.B \-display
+adds a display much like the "+" command. Multiple \-display flags
+can be given. For example, to start up xkibitz with three additional
+displays:
+
+ xkibitz -display mercury -display fox -display dragon:1.0
+
+.SH CAVEATS
+Due to limitations in both X and UNIX, resize propagation is weak.
+
+When the master user resizes the xterm, all the other xterms are logically
+resized.
+Unfortunately, xkibitz cannot force the physical xterm size to correspond
+with the logical xterm sizes.
+
+The other users are free to resize their xterm but their sizes are not
+propagated. The master can check the logical sizes with the "=" command.
+
+Deducing the window size is a non-portable operation. The code is known
+to work for recent versions of SunOS, AIX, Unicos, and HPUX. Send back
+mods if you add support for anything else.
+.SH ENVIRONMENT
+The environment variable SHELL is used to determine and start a shell, if no
+other program is given on the command line.
+
+If the environment variable DISPLAY is defined, its value is used for the
+display name of the
+.B xkibitz
+master (the display with tag number 0). Otherwise this name remains empty.
+
+Additional arguments may be passed to new xterms through
+the environment variable XKIBITZ_XTERM_ARGS.
+For example, to create xterms
+with a scrollbar and a green pointer cursor:
+.nf
+
+ XKIBITZ_XTERM_ARGS="-sb -ms green"
+ export XKIBITZ_XTERM_ARGS
+
+.fi
+(this is for the Bourne shell - use whatever syntax is appropriate for your
+favorite shell). Any option can be given that is valid for the
+.B xterm
+command, with the exception of
+.BR -display ,
+.B -geometry
+and
+.BI -S
+as those are set by
+.BR xkibitz .
+.SH SEE ALSO
+.BR Tcl (3),
+.BR libexpect (3)
+.BR kibitz (1)
+.br
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes,
+O'Reilly and Associates, January 1995.
+.br
+.I
+"kibitz \- Connecting Multiple Interactive Programs Together", \fRby Don Libes,
+Software \- Practice & Experience, John Wiley & Sons, West Sussex, England,
+Vol. 23, No. 5, May, 1993.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
diff --git a/expect/example/xpstat b/expect/example/xpstat
new file mode 100755
index 00000000000..d012bbd68ad
--- /dev/null
+++ b/expect/example/xpstat
@@ -0,0 +1,269 @@
+#!../expectk --
+
+# This script acts as a front-end for xpilot. Run it in the background,
+# and it will pop up a window for each server it finds running. After
+# you run it, press the "?" button for more info.
+
+# Store the filename of your xpilot client in the following variable.
+set xpilot /usr/local/bin/xpilot
+
+# Author: Don Libes, NIST, 12/29/92
+
+# I never have figured out how to get the alias out of xrdb. For now, just
+# read it ourselves out of .Xdefaults - ugh.
+
+log_user 0
+
+set timeout 60
+
+proc probe {} {
+ global max db hosts world
+
+ set timeout -1
+
+ expect_before eof {wait;return 0}
+
+ expect -re "Server on (.*). Enter command> " {
+ exp_send "S\r"
+ set host $expect_out(1,string)
+ # replace dots in hostnames by underscores
+ regsub -all . $host _ host
+ # force lowercase to avoid Tk widget name problems
+ set host [string tolower $host]
+ lappend hosts $host
+ }
+ expect -re "WORLD\[^:]*: (\[^\r]*)\r" {
+ set worldtmp $expect_out(1,string)
+ }
+ expect -re "AUTHOR\[^:]*: (\[^\r]*)\r" {
+ set author $expect_out(1,string)
+ }
+ set world($host) "$worldtmp by $author"
+
+ # skip over junk to get players
+ expect {
+ -re -+ {}
+ -re "Enter command> " {
+ set max($host) 0
+ display $host
+ return 1
+ }
+ }
+ set i 0
+ expect {
+ -re "\\.\\.\\. . (................) (...) *(\[^ ]*) *(\[^\r]*)\r" {
+ # strip trailing blanks
+ set alias [string trimright $expect_out(1,string)]
+ set db($host,$i,alias) $alias
+
+ # strip leading zeros
+ scan $expect_out(2,string) %d db($host,$i,life)
+
+ set db($host,$i,score) $expect_out(3,string)
+
+ set db($host,name,$alias) $expect_out(4,string)
+
+ incr i
+ exp_continue
+ }
+ -re "Enter command>"
+
+ }
+ set max($host) $i
+ display $host
+
+ return 1
+}
+
+proc resize {w a b} {
+ # 27 is a guess at a fixed-width sufficiently comfortable for
+ # the variable-width font. I don't know how to do better.
+ $w configure -width 27
+}
+
+proc play {host} {
+ global xpilot alias
+
+ exec xhost $host
+ catch {exec $xpilot -name $alias($host) -join $host} status
+}
+
+proc show-help {x y msg} {
+ catch {destroy .help}
+ toplevel .help
+ wm geometry .help +$x+$y
+
+ message .help.text -text $msg
+
+ button .help.ok -text "ok" -command {destroy .help}
+ pack .help.text
+ pack .help.ok -fill x
+}
+
+# pop up window with alias
+proc show-alias {host seln x y} {
+ global db
+
+ catch {destroy .alias}
+ toplevel .alias
+ wm geometry .alias +$x+$y
+ wm transient .alias .
+
+ regexp "(.*\[^ ]) +\[-0-9]+ +\[0-9]+$" $seln discard alias
+
+ button .alias.b -text "$db($host,name,$alias)" -command {
+ destroy .alias
+ }
+ .alias.b config -padx 1 -pady 1 -highlightthickness 0
+ pack .alias.b
+}
+
+proc help {x y} {
+ show-help $x $y "xpstat - written by Don Libes, NIST, December 29, 1992
+
+This script acts as a front-end for xpilot. Run it in the background, and it will pop up a window for each server it finds running. Press the \"?\" button for this info.
+
+This program polls each xpilot server once a minute. To make it poll immediately, press \"update\". Press \"play as\" to enter the current game with the alias to the right. Edit to taste. (Your alias is initialized from the value of xpilot.name in ~/.Xdefaults.)
+
+Double-click the left button on an alias to see the real user name. To remove the user name window, click on it with the left button.
+
+Pan the world/author text, player list, or your own alias by holding the middle mouse button down and moving the mouse."
+}
+
+# if user presses "update" try to update screen immediately
+proc prod {x y} {
+ global cat_spawn_id updateflag
+
+ if $updateflag {
+ show-help $x $y "I heard you, gimme a break. I'm waiting for the xpilot server to respond..."
+ }
+ set updateflag 1
+
+ exp_send -i $cat_spawn_id "\r"
+}
+
+proc display {host} {
+ global world db alias max env
+
+ set w .$host
+ #if 0==[llength [info com $w]]
+ if ![winfo exists $w] {
+
+ # window does not exist, create it
+
+ toplevel $w -class xpstat
+ wm minsize $w 1 1
+ wm title $w "xpilot@$host"
+ wm iconname $w "$host xpilot stats"
+ entry $w.world -state disabled -textvar world($host)
+
+ listbox $w.players -yscroll "resize $w.players" -font 7x13bold
+ $w.players config -highlightthickness 0 -border 0
+ $w.world config -highlightthickness 0
+
+ bind $w.players <Double-Button-1> {
+ scan %W ".%%\[^.]" host
+ show-alias $host [selection get] %X %Y
+ }
+
+ message $w.msg -text "no players" -aspect 1000 -justify center
+
+ button $w.help -text ? -command {
+ help 10 20
+ }
+
+ button $w.update -text "update"
+ bind $w.update <1> {
+ after 1 prod %X %Y
+ }
+
+ button $w.play -text "play as"
+ bind $w.play <1> {
+ scan %W ".%%\[^.]" host
+ after 1 play $host
+ }
+
+ entry $w.alias -textvar alias($host) -width 10
+ set alias($host) $env(USER)
+
+ bind $w.alias <Return> {
+ scan %W ".%%\[^.]" host
+ play $host
+ }
+
+ $w.play config -padx 1 -pady 1 -highlightthickness 0
+ $w.update config -padx 1 -pady 1 -highlightthickness 0
+ $w.help config -padx 1 -pady 1 -highlightthickness 0
+ $w.alias config -highlightthickness 0
+
+ pack $w.world -expand 1 -fill x
+ pack $w.msg
+ pack $w.help $w.update $w.play -side left
+ pack $w.alias -side left -expand 1 -fill x
+ set max($host,was) 0
+ }
+
+ if $max($host)==0 {
+ # put up "no players" message?
+ if $max($host,was)>0 {
+ pack $w.msg -after $w.world -fill x -side top
+ pack forget $w.world
+ }
+ } else {
+ # remove "no players" message?
+ if $max($host,was)==0 {
+ pack $w.players -after $w.world -side top
+ pack forget $w.msg
+ }
+ }
+
+ $w.players delete 0 end
+
+ for {set i 0} {$i<$max($host)} {incr i} {
+ $w.players insert end [format "%-17s %4d %d" \
+ $db($host,$i,alias) \
+ $db($host,$i,score) \
+ $db($host,$i,life) \
+ ]
+ }
+
+ set max($host,was) $max($host)
+}
+
+wm withdraw .
+set oldhosts {}
+
+set updateflag 0 ;# 1 if user pressed "update" button
+
+# look for desired alias in the .Xdefaults file
+set status [catch {exec egrep "xpilot.name:" [glob ~/.Xdefaults]} output]
+if $status==0 {
+ regexp "xpilot.name:\[ \t]*(\[^\r]*)" $output dummy env(USER)
+}
+
+spawn cat -u; set cat_spawn_id $spawn_id
+
+while 1 {
+ global xpilot hosts
+
+ set hosts {}
+
+ eval spawn $xpilot $argv
+ while {[probe]} {exp_send "N\r"}
+ catch {expect_before} ;# disable expect_before from inside probe
+
+ # clean up hosts that no longer are running xpilots
+
+ foreach host $oldhosts {
+ # if host not in hosts
+ if -1==[lsearch $hosts $host] {
+ destroy .$host
+ }
+ }
+ set oldhosts $hosts
+
+ set updateflag 0
+
+ # sleep for a little while, subject to click from "update" button
+ expect -i $cat_spawn_id -re "...." ;# two crlfs
+}
diff --git a/expect/example/xrlogin b/expect/example/xrlogin
new file mode 100644
index 00000000000..9513ec27b94
--- /dev/null
+++ b/expect/example/xrlogin
@@ -0,0 +1,22 @@
+#!/depot/path/expect --
+# xrlogin - rlogin but with current DISPLAY
+#
+# You can extend this idea to save any arbitrary information across rlogin
+# Don Libes - Oct 17, 1991.
+
+if {[llength $argv] != 1} {
+ puts "usage: xrlogin remotehost"
+ exit
+}
+
+set prompt "(%|#|\\$) $" ;# default prompt
+catch {set prompt $env(EXPECT_PROMPT)}
+
+set timeout -1
+eval spawn rlogin $argv
+expect eof exit -re $prompt
+if [string match "unix:0.0" $env(DISPLAY)] {
+ set env(DISPLAY) "[exec hostname].[exec domainname]:0.0\r"
+}
+send "setenv DISPLAY $env(DISPLAY)\r"
+interact
diff --git a/expect/exp_clib.c b/expect/exp_clib.c
new file mode 100644
index 00000000000..c5c253b57ce
--- /dev/null
+++ b/expect/exp_clib.c
@@ -0,0 +1,1202 @@
+/* exp_clib.c - top-level functions in the expect C library, libexpect.a
+
+Written by: Don Libes, libes@cme.nist.gov, NIST, 12/3/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+#include "expect_cf.h"
+#include <stdio.h>
+#include <setjmp.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#ifdef CRAY
+# ifndef TCSETCTTY
+# if defined(HAVE_TERMIOS)
+# include <termios.h>
+# else
+# include <termio.h>
+# endif
+# endif
+#endif
+
+#ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#else
+# include <fcntl.h>
+#endif
+
+#ifdef HAVE_STRREDIR_H
+#include <sys/strredir.h>
+# ifdef SRIOCSREDIR
+# undef TIOCCONS
+# endif
+#endif
+
+#include <signal.h>
+/*#include <memory.h> - deprecated - ANSI C moves them into string.h */
+#include "string.h"
+
+#include <errno.h>
+#include "exp_rename.h"
+#define EXP_AVOID_INCLUDING_TCL_H
+#include "expect.h"
+#include "exp_int.h"
+
+#include "exp_printify.h"
+
+#ifdef NO_STDLIB_H
+#include "../compat/stdlib.h"
+#else
+#include <stdlib.h> /* for malloc */
+#endif
+
+#define EXP_MATCH_MAX 2000
+/* public */
+char *exp_buffer = 0;
+char *exp_buffer_end = 0;
+char *exp_match = 0;
+char *exp_match_end = 0;
+int exp_match_max = EXP_MATCH_MAX; /* bytes */
+int exp_full_buffer = FALSE; /* don't return on full buffer */
+int exp_remove_nulls = TRUE;
+int exp_timeout = 10; /* seconds */
+int exp_pty_timeout = 5; /* seconds - see CRAY below */
+int exp_autoallocpty = TRUE; /* if TRUE, we do allocation */
+int exp_pty[2]; /* master is [0], slave is [1] */
+int exp_pid;
+char *exp_stty_init = 0; /* initial stty args */
+int exp_ttycopy = TRUE; /* copy tty parms from /dev/tty */
+int exp_ttyinit = TRUE; /* set tty parms to sane state */
+int exp_console = FALSE; /* redirect console */
+void (*exp_child_exec_prelude)() = 0;
+
+jmp_buf exp_readenv; /* for interruptable read() */
+int exp_reading = FALSE; /* whether we can longjmp or not */
+
+void debuglog();
+int getptymaster();
+int getptyslave();
+int Exp_StringMatch();
+
+#define sysreturn(x) return(errno = x, -1)
+
+void exp_init_pty();
+
+/*
+ The following functions are linked from the Tcl library. They
+ don't cause anything else in the library to be dragged in, so it
+ shouldn't cause any problems (e.g., bloat).
+
+ The functions are relatively small but painful enough that I don't care
+ to recode them. You may, if you absolutely want to get rid of any
+ vestiges of Tcl.
+*/
+extern char *TclGetRegError();
+extern void TclRegError();
+char *Tcl_ErrnoMsg();
+
+
+
+static unsigned int bufsiz = 2*EXP_MATCH_MAX;
+
+static struct f {
+ int valid;
+
+ char *buffer; /* buffer of matchable chars */
+ char *buffer_end; /* one beyond end of matchable chars */
+ /*char *match; /* start of matched string */
+ char *match_end; /* one beyond end of matched string */
+ int msize; /* size of allocate space */
+ /* actual size is one larger for null */
+} *fs = 0;
+
+static int fd_alloc_max = -1; /* max fd allocated */
+
+/* translate fd or fp to fd */
+static struct f *
+fdfp2f(fd,fp)
+int fd;
+FILE *fp;
+{
+ if (fd == -1) return(fs + fileno(fp));
+ else return(fs + fd);
+}
+
+static struct f *
+fd_new(fd)
+int fd;
+{
+ int i, low;
+ struct f *fp;
+ struct f *newfs; /* temporary, so we don't lose old fs */
+
+ if (fd > fd_alloc_max) {
+ if (!fs) { /* no fd's yet allocated */
+ newfs = (struct f *)malloc(sizeof(struct f)*(fd+1));
+ low = 0;
+ } else { /* enlarge fd table */
+ newfs = (struct f *)realloc((char *)fs,sizeof(struct f)*(fd+1));
+ low = fd_alloc_max+1;
+ }
+ fs = newfs;
+ fd_alloc_max = fd;
+ for (i = low; i <= fd_alloc_max; i++) { /* init new entries */
+ fs[i].valid = FALSE;
+ }
+ }
+
+ fp = fs+fd;
+
+ if (!fp->valid) {
+ /* initialize */
+ fp->buffer = malloc((unsigned)(bufsiz+1));
+ if (!fp->buffer) return 0;
+ fp->msize = bufsiz;
+ fp->valid = TRUE;
+ }
+ fp->buffer_end = fp->buffer;
+ fp->match_end = fp->buffer;
+ return fp;
+
+}
+
+/* returns fd of master side of pty */
+int
+exp_spawnv(file,argv)
+char *file;
+char *argv[]; /* some compiler complains about **argv? */
+{
+ int cc;
+ int errorfd; /* place to stash fileno(stderr) in child */
+ /* while we're setting up new stderr */
+ int ttyfd;
+ int sync_fds[2];
+ int sync2_fds[2];
+ char sync_byte;
+#ifdef PTYTRAP_DIES
+ int slave_write_ioctls = 1;
+ /* by default, slave will be write-ioctled this many times */
+#endif
+
+ static int first_time = TRUE;
+
+ if (first_time) {
+ first_time = FALSE;
+ exp_init_pty();
+ exp_init_tty();
+ }
+
+ if (!file || !argv) sysreturn(EINVAL);
+ if (!argv[0] || strcmp(file,argv[0])) {
+ debuglog("expect: warning: file (%s) != argv[0] (%s)\n",
+ file,
+ argv[0]?argv[0]:"");
+ }
+
+#ifdef PTYTRAP_DIES
+/* any extraneous ioctl's that occur in slave must be accounted for
+when trapping, see below in child half of fork */
+#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300)
+ slave_write_ioctls++;
+#endif
+#endif /*PTYTRAP_DIES*/
+
+ if (exp_autoallocpty) {
+ if (0 > (exp_pty[0] = getptymaster())) sysreturn(ENODEV);
+ }
+ fcntl(exp_pty[0],F_SETFD,1); /* close on exec */
+#ifdef PTYTRAP_DIES
+ exp_slave_control(exp_pty[0],1);*/
+#endif
+
+ if (!fd_new(exp_pty[0])) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ if (-1 == (pipe(sync_fds))) {
+ return -1;
+ }
+ if (-1 == (pipe(sync2_fds))) {
+ return -1;
+ }
+
+ if ((exp_pid = fork()) == -1) return(-1);
+ if (exp_pid) {
+ /* parent */
+ close(sync_fds[1]);
+ close(sync2_fds[0]);
+ if (!exp_autoallocpty) close(exp_pty[1]);
+
+#ifdef PTYTRAP_DIES
+#ifdef HAVE_PTYTRAP
+ if (exp_autoallocpty) {
+ /* trap initial ioctls in a feeble attempt to not */
+ /* block the initially. If the process itself */
+ /* ioctls /dev/tty, such blocks will be trapped */
+ /* later during normal event processing */
+
+ while (slave_write_ioctls) {
+ int cc;
+
+ cc = exp_wait_for_slave_open(exp_pty[0]);
+#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300)
+ if (cc == TIOCSCTTY) slave_write_ioctls = 0;
+#endif
+ if (cc & IOC_IN) slave_write_ioctls--;
+ else if (cc == -1) {
+ printf("failed to trap slave pty");
+ return -1;
+ }
+ }
+ }
+#endif
+#endif /*PTYTRAP_DIES*/
+
+ /*
+ * wait for slave to initialize pty before allowing
+ * user to send to it
+ */
+
+ debuglog("parent: waiting for sync byte\r\n");
+ cc = read(sync_fds[0],&sync_byte,1);
+ if (cc == -1) {
+ fprintf(stderr,"parent sync byte read: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+
+ /* turn on detection of eof */
+ exp_slave_control(exp_pty[0],1);
+
+ /*
+ * tell slave to go on now now that we have initialized pty
+ */
+
+ debuglog("parent: telling child to go ahead\r\n");
+ cc = write(sync2_fds[1]," ",1);
+ if (cc == -1) {
+ errorlog("parent sync byte write: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+
+ debuglog("parent: now unsynchronized from child\r\n");
+
+ close(sync_fds[0]);
+ close(sync2_fds[1]);
+
+ return(exp_pty[0]);
+ }
+
+ /* child process - do not return from here! all errors must exit() */
+
+ close(sync_fds[0]);
+ close(sync2_fds[1]);
+
+#ifdef CRAY
+ (void) close(exp_pty[0]);
+#endif
+
+/* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */
+/* is called. setpgrp works though. */
+#if defined(POSIX) && !defined(ultrix)
+#define DO_SETSID
+#endif
+#ifdef __convex__
+#define DO_SETSID
+#endif
+
+#ifdef DO_SETSID
+ setsid();
+#else
+#ifdef SYSV3
+#ifndef CRAY
+ setpgrp();
+#endif /* CRAY */
+#else /* !SYSV3 */
+#ifdef MIPS_BSD
+ /* required on BSD side of MIPS OS <jmsellen@watdragon.waterloo.edu> */
+# include <sysv/sys.s>
+ syscall(SYS_setpgrp);
+#endif
+ setpgrp(0,0);
+/* setpgrp(0,getpid());*/ /* make a new pgrp leader */
+
+#ifdef TIOCNOTTY
+ ttyfd = open("/dev/tty", O_RDWR);
+ if (ttyfd >= 0) {
+ (void) ioctl(ttyfd, TIOCNOTTY, (char *)0);
+ (void) close(ttyfd);
+ }
+#endif /* TIOCNOTTY */
+
+#endif /* SYSV3 */
+#endif /* DO_SETSID */
+
+ /* save error fd while we're setting up new one */
+ errorfd = fcntl(2,F_DUPFD,3);
+ /* and here is the macro to restore it */
+#define restore_error_fd {close(2);fcntl(errorfd,F_DUPFD,2);}
+
+ if (exp_autoallocpty) {
+
+ close(0);
+ close(1);
+ close(2);
+
+ /* since we closed fd 0, open of pty slave must return fd 0 */
+
+ if (0 > (exp_pty[1] = getptyslave(exp_ttycopy,exp_ttyinit,
+ exp_stty_init))) {
+ restore_error_fd
+ fprintf(stderr,"open(slave pty): %s\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+ /* sanity check */
+ if (exp_pty[1] != 0) {
+ restore_error_fd
+ fprintf(stderr,"getptyslave: slave = %d but expected 0\n",
+ exp_pty[1]);
+ exit(-1);
+ }
+ } else {
+ if (exp_pty[1] != 0) {
+ close(0); fcntl(exp_pty[1],F_DUPFD,0);
+ }
+ close(1); fcntl(0,F_DUPFD,1);
+ close(2); fcntl(0,F_DUPFD,1);
+ close(exp_pty[1]);
+ }
+
+
+
+/* The test for hpux may have to be more specific. In particular, the */
+/* code should be skipped on the hp9000s300 and hp9000s720 (but there */
+/* is no documented define for the 720!) */
+
+#if defined(TIOCSCTTY) && !defined(sun) && !defined(hpux)
+ /* 4.3+BSD way to acquire controlling terminal */
+ /* according to Stevens - Adv. Prog..., p 642 */
+#ifdef __QNX__ /* posix in general */
+ if (tcsetct(0, getpid()) == -1) {
+#else
+ if (ioctl(0,TIOCSCTTY,(char *)0) < 0) {
+#endif
+ restore_error_fd
+ fprintf(stderr,"failed to get controlling terminal using TIOCSCTTY");
+ exit(-1);
+ }
+#endif
+
+#ifdef CRAY
+ (void) setsid();
+ (void) ioctl(0,TCSETCTTY,0);
+ (void) close(0);
+ if (open("/dev/tty", O_RDWR) < 0) {
+ restore_error_fd
+ fprintf(stderr,"open(/dev/tty): %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+ (void) close(1);
+ (void) close(2);
+ (void) dup(0);
+ (void) dup(0);
+ setptyutmp(); /* create a utmp entry */
+
+ /* _CRAY2 code from Hal Peterson <hrp@cray.com>, Cray Research, Inc. */
+#ifdef _CRAY2
+ /*
+ * Interpose a process between expect and the spawned child to
+ * keep the slave side of the pty open to allow time for expect
+ * to read the last output. This is a workaround for an apparent
+ * bug in the Unicos pty driver on Cray-2's under Unicos 6.0 (at
+ * least).
+ */
+ if ((pid = fork()) == -1) {
+ restore_error_fd
+ fprintf(stderr,"second fork: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+
+ if (pid) {
+ /* Intermediate process. */
+ int status;
+ int timeout;
+ char *t;
+
+ /* How long should we wait? */
+ timeout = exp_pty_timeout;
+
+ /* Let the spawned process run to completion. */
+ while (wait(&status) < 0 && errno == EINTR)
+ /* empty body */;
+
+ /* Wait for the pty to clear. */
+ sleep(timeout);
+
+ /* Duplicate the spawned process's status. */
+ if (WIFSIGNALED(status))
+ kill(getpid(), WTERMSIG(status));
+
+ /* The kill may not have worked, but this will. */
+ exit(WEXITSTATUS(status));
+ }
+#endif /* _CRAY2 */
+#endif /* CRAY */
+
+ if (exp_console) {
+#ifdef SRIOCSREDIR
+ int fd;
+
+ if ((fd = open("/dev/console", O_RDONLY)) == -1) {
+ restore_error_fd
+ fprintf(stderr, "spawn %s: cannot open console, check permissions of /dev/console\n",argv[0]);
+ exit(-1);
+ }
+ if (ioctl(fd, SRIOCSREDIR, 0) == -1) {
+ restore_error_fd
+ fprintf(stderr, "spawn %s: cannot redirect console, check permissions of /dev/console\n",argv[0]);
+ }
+ close(fd);
+#endif
+
+#ifdef TIOCCONS
+ int on = 1;
+ if (ioctl(0,TIOCCONS,(char *)&on) == -1) {
+ restore_error_fd
+ fprintf(stderr, "spawn %s: cannot open console, check permissions of /dev/console\n",argv[0]);
+ exit(-1);
+ }
+#endif /* TIOCCONS */
+ }
+
+ /* tell parent that we are done setting up pty */
+ /* The actual char sent back is irrelevant. */
+
+ /* debuglog("child: telling parent that pty is initialized\r\n");*/
+ cc = write(sync_fds[1]," ",1);
+ if (cc == -1) {
+ restore_error_fd
+ fprintf(stderr,"child: sync byte write: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+ close(sync_fds[1]);
+
+ /* wait for master to let us go on */
+ /* debuglog("child: waiting for go ahead from parent\r\n"); */
+
+/* close(master); /* force master-side close so we can read */
+ cc = read(sync2_fds[0],&sync_byte,1);
+ if (cc == -1) {
+ restore_error_fd
+ errorlog("child: sync byte read: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+ close(sync2_fds[0]);
+
+ /* debuglog("child: now unsynchronized from parent\r\n"); */
+
+ /* (possibly multiple) masters are closed automatically due to */
+ /* earlier fcntl(,,CLOSE_ON_EXEC); */
+
+ /* just in case, allow user to explicitly close other files */
+ if (exp_close_in_child) (*exp_close_in_child)();
+
+ /* allow user to do anything else to child */
+ if (exp_child_exec_prelude) (*exp_child_exec_prelude)();
+
+ (void) execvp(file,argv);
+ /* Unfortunately, by now we've closed fd's to stderr, logfile and
+ debugfile.
+ The only reasonable thing to do is to send back the error as
+ part of the program output. This will be picked up in an
+ expect or interact command.
+ */
+ fprintf(stderr,"execvp(%s): %s\n",file,Tcl_ErrnoMsg(errno));
+ exit(-1);
+ /*NOTREACHED*/
+}
+
+/* returns fd of master side of pty */
+/*VARARGS*/
+int
+exp_spawnl TCL_VARARGS_DEF(char *,arg1)
+/*exp_spawnl(va_alist)*/
+/*va_dcl*/
+{
+ va_list args; /* problematic line here */
+ int i;
+ char *arg, **argv;
+
+ arg = TCL_VARARGS_START(char *,arg1,args);
+ /*va_start(args);*/
+ for (i=1;;i++) {
+ arg = va_arg(args,char *);
+ if (!arg) break;
+ }
+ va_end(args);
+ if (i == 0) sysreturn(EINVAL);
+ if (!(argv = (char **)malloc((i+1)*sizeof(char *)))) sysreturn(ENOMEM);
+ argv[0] = TCL_VARARGS_START(char *,arg1,args);
+ /*va_start(args);*/
+ for (i=1;;i++) {
+ argv[i] = va_arg(args,char *);
+ if (!argv[i]) break;
+ }
+ i = exp_spawnv(argv[0],argv+1);
+ free((char *)argv);
+ return(i);
+}
+
+/* allow user-provided fd to be passed to expect funcs */
+int
+exp_spawnfd(fd)
+int fd;
+{
+ if (!fd_new(fd)) {
+ errno = ENOMEM;
+ return -1;
+ }
+ return fd;
+}
+
+/* remove nulls from s. Initially, the number of chars in s is c, */
+/* not strlen(s). This count does not include the trailing null. */
+/* returns number of nulls removed. */
+static int
+rm_nulls(s,c)
+char *s;
+int c;
+{
+ char *s2 = s; /* points to place in original string to put */
+ /* next non-null character */
+ int count = 0;
+ int i;
+
+ for (i=0;i<c;i++,s++) {
+ if (0 == *s) {
+ count++;
+ continue;
+ }
+ if (count) *s2 = *s;
+ s2++;
+ }
+ return(count);
+}
+
+static int i_read_errno;/* place to save errno, if i_read() == -1, so it
+ doesn't get overwritten before we get to read it */
+
+/*ARGSUSED*/
+static void
+sigalarm_handler(n)
+int n; /* signal number, unused by us */
+{
+#ifdef REARM_SIG
+ signal(SIGALRM,sigalarm_handler);
+#endif
+
+ longjmp(exp_readenv,1);
+}
+
+/* interruptable read */
+static int
+i_read(fd,fp,buffer,length,timeout)
+int fd;
+FILE *fp;
+char *buffer;
+int length;
+int timeout;
+{
+ int cc = -2;
+
+ /* since setjmp insists on returning 1 upon longjmp(,0), */
+ /* longjmp(,2 (EXP_RESTART)) instead. */
+
+ /* no need to set alarm if -1 (infinite) or 0 (poll with */
+ /* guaranteed data) */
+
+ if (timeout > 0) alarm(timeout);
+
+ /* restart read if setjmp returns 0 (first time) or 2 (EXP_RESTART). */
+ /* abort if setjmp returns 1 (EXP_ABORT). */
+ if (EXP_ABORT != setjmp(exp_readenv)) {
+ exp_reading = TRUE;
+ if (fd == -1) {
+ int c;
+ c = getc(fp);
+ if (c == EOF) {
+/*fprintf(stderr,"<<EOF>>",c);fflush(stderr);*/
+ if (feof(fp)) cc = 0;
+ else cc = -1;
+ } else {
+/*fprintf(stderr,"<<%c>>",c);fflush(stderr);*/
+ buffer[0] = c;
+ cc = 1;
+ }
+ } else {
+#ifndef HAVE_PTYTRAP
+ cc = read(fd,buffer,length);
+#else
+# include <sys/ptyio.h>
+
+ fd_set rdrs;
+ fd_set excep;
+
+ restart:
+ FD_ZERO(&rdrs);
+ FD_ZERO(&excep);
+ FD_SET(fd,&rdrs);
+ FD_SET(fd,&excep);
+ if (-1 == (cc = select(fd+1,
+ (SELECT_MASK_TYPE *)&rdrs,
+ (SELECT_MASK_TYPE *)0,
+ (SELECT_MASK_TYPE *)&excep,
+ (struct timeval *)0))) {
+ /* window refreshes trigger EINTR, ignore */
+ if (errno == EINTR) goto restart;
+ }
+ if (FD_ISSET(fd,&rdrs)) {
+ cc = read(fd,buffer,length);
+ } else if (FD_ISSET(fd,&excep)) {
+ struct request_info ioctl_info;
+ ioctl(fd,TIOCREQCHECK,&ioctl_info);
+ if (ioctl_info.request == TIOCCLOSE) {
+ cc = 0; /* indicate eof */
+ } else {
+ ioctl(fd, TIOCREQSET, &ioctl_info);
+ /* presumably, we trapped an open here */
+ goto restart;
+ }
+ }
+#endif /* HAVE_PTYTRAP */
+ }
+#if 0
+ /* can't get fread to return early! */
+ else {
+ if (!(cc = fread(buffer,1,length,fp))) {
+ if (ferror(fp)) cc = -1;
+ }
+ }
+#endif
+ i_read_errno = errno; /* errno can be overwritten by the */
+ /* time we return */
+ }
+ exp_reading = FALSE;
+
+ if (timeout > 0) alarm(0);
+ return(cc);
+}
+
+/* I tried really hard to make the following two functions share the code */
+/* that makes the ecase array, but I kept running into a brick wall when */
+/* passing var args into the funcs and then again into a make_cases func */
+/* I would very much appreciate it if someone showed me how to do it right */
+
+/* takes triplets of args, with a final "exp_last" arg */
+/* triplets are type, pattern, and then int to return */
+/* returns negative value if error (or EOF/timeout) occurs */
+/* some negative values can also have an associated errno */
+
+/* the key internal variables that this function depends on are:
+ exp_buffer
+ exp_buffer_end
+ exp_match_end
+*/
+static int
+expectv(fd,fp,ecases)
+int fd;
+FILE *fp;
+struct exp_case *ecases;
+{
+ int cc = 0; /* number of chars returned in a single read */
+ int buf_length; /* numbers of chars in exp_buffer */
+ int old_length; /* old buf_length */
+ int first_time = TRUE; /* force old buffer to be tested before */
+ /* additional reads */
+ int polled = 0; /* true if poll has caused read() to occur */
+
+ struct exp_case *ec; /* points to current ecase */
+
+ time_t current_time; /* current time (when we last looked)*/
+ time_t end_time; /* future time at which to give up */
+ int remtime; /* remaining time in timeout */
+
+ struct f *f;
+ int return_val;
+ int sys_error = 0;
+#define return_normally(x) {return_val = x; goto cleanup;}
+#define return_errno(x) {sys_error = x; goto cleanup;}
+
+ f = fdfp2f(fd,fp);
+ if (!f) return_errno(ENOMEM);
+
+ exp_buffer = f->buffer;
+ exp_buffer_end = f->buffer_end;
+ exp_match_end = f->match_end;
+
+ buf_length = exp_buffer_end - exp_match_end;
+ if (buf_length) {
+ /*
+ * take end of previous match to end of buffer
+ * and copy to beginning of buffer
+ */
+ memmove(exp_buffer,exp_match_end,buf_length);
+ }
+ exp_buffer_end = exp_buffer + buf_length;
+ *exp_buffer_end = '\0';
+
+ if (!ecases) return_errno(EINVAL);
+
+ /* compile if necessary */
+ for (ec=ecases;ec->type != exp_end;ec++) {
+ if ((ec->type == exp_regexp) && !ec->re) {
+ TclRegError((char *)0);
+ if (!(ec->re = TclRegComp(ec->pattern))) {
+ fprintf(stderr,"regular expression %s is bad: %s",ec->pattern,TclGetRegError());
+ return_errno(EINVAL);
+ }
+ }
+ }
+
+ /* get the latest buffer size. Double the user input for two */
+ /* reasons. 1) Need twice the space in case the match */
+ /* straddles two bufferfuls, 2) easier to hack the division by */
+ /* two when shifting the buffers later on */
+
+ bufsiz = 2*exp_match_max;
+ if (f->msize != bufsiz) {
+ /* if truncated, forget about some data */
+ if (buf_length > bufsiz) {
+ /* copy end of buffer down */
+
+ /* copy one less than what buffer can hold to avoid */
+ /* triggering buffer-full handling code below */
+ /* which will immediately dump the first half */
+ /* of the buffer */
+ memmove(exp_buffer,exp_buffer+(buf_length - bufsiz)+1,
+ bufsiz-1);
+ buf_length = bufsiz-1;
+ }
+ exp_buffer = realloc(exp_buffer,bufsiz+1);
+ if (!exp_buffer) return_errno(ENOMEM);
+ exp_buffer[buf_length] = '\0';
+ exp_buffer_end = exp_buffer + buf_length;
+ f->msize = bufsiz;
+ }
+
+ /* some systems (i.e., Solaris) require fp be flushed when switching */
+ /* directions - do this again afterwards */
+ if (fd == -1) fflush(fp);
+
+ if (exp_timeout != -1) signal(SIGALRM,sigalarm_handler);
+
+ /* remtime and current_time updated at bottom of loop */
+ remtime = exp_timeout;
+
+ time(&current_time);
+ end_time = current_time + remtime;
+
+ for (;;) {
+ /* when buffer fills, copy second half over first and */
+ /* continue, so we can do matches over multiple buffers */
+ if (buf_length == bufsiz) {
+ int first_half, second_half;
+
+ if (exp_full_buffer) {
+ debuglog("expect: full buffer\r\n");
+ exp_match = exp_buffer;
+ exp_match_end = exp_buffer + buf_length;
+ exp_buffer_end = exp_match_end;
+ return_normally(EXP_FULLBUFFER);
+ }
+ first_half = bufsiz/2;
+ second_half = bufsiz - first_half;
+
+ memcpy(exp_buffer,exp_buffer+first_half,second_half);
+ buf_length = second_half;
+ exp_buffer_end = exp_buffer + second_half;
+ }
+
+ /*
+ * always check first if pattern is already in buffer
+ */
+ if (first_time) {
+ first_time = FALSE;
+ goto after_read;
+ }
+
+ /*
+ * check for timeout
+ */
+ if ((exp_timeout >= 0) && ((remtime < 0) || polled)) {
+ debuglog("expect: timeout\r\n");
+ exp_match_end = exp_buffer;
+ return_normally(EXP_TIMEOUT);
+ }
+
+ /*
+ * if timeout == 0, indicate a poll has
+ * occurred so that next time through loop causes timeout
+ */
+ if (exp_timeout == 0) {
+ polled = 1;
+ }
+
+ cc = i_read(fd,fp,
+ exp_buffer_end,
+ bufsiz - buf_length,
+ remtime);
+
+ if (cc == 0) {
+ debuglog("expect: eof\r\n");
+ return_normally(EXP_EOF); /* normal EOF */
+ } else if (cc == -1) { /* abnormal EOF */
+ /* ptys produce EIO upon EOF - sigh */
+ if (i_read_errno == EIO) {
+ /* convert to EOF indication */
+ debuglog("expect: eof\r\n");
+ return_normally(EXP_EOF);
+ }
+ debuglog("expect: error (errno = %d)\r\n",i_read_errno);
+ return_errno(i_read_errno);
+ } else if (cc == -2) {
+ debuglog("expect: timeout\r\n");
+ exp_match_end = exp_buffer;
+ return_normally(EXP_TIMEOUT);
+ }
+
+ old_length = buf_length;
+ buf_length += cc;
+ exp_buffer_end += buf_length;
+
+ if (logfile_all || (loguser && logfile)) {
+ fwrite(exp_buffer + old_length,1,cc,logfile);
+ }
+ if (loguser) fwrite(exp_buffer + old_length,1,cc,stdout);
+ if (debugfile) fwrite(exp_buffer + old_length,1,cc,debugfile);
+
+ /* if we wrote to any logs, flush them */
+ if (debugfile) fflush(debugfile);
+ if (loguser) {
+ fflush(stdout);
+ if (logfile) fflush(logfile);
+ }
+
+ /* remove nulls from input, so we can use C-style strings */
+ /* doing it here lets them be sent to the screen, just */
+ /* in case they are involved in formatting operations */
+ if (exp_remove_nulls) {
+ buf_length -= rm_nulls(exp_buffer + old_length, cc);
+ }
+ /* cc should be decremented as well, but since it will not */
+ /* be used before being set again, there is no need */
+ exp_buffer_end = exp_buffer + buf_length;
+ *exp_buffer_end = '\0';
+ exp_match_end = exp_buffer;
+
+ after_read:
+ debuglog("expect: does {%s} match ",exp_printify(exp_buffer));
+ /* pattern supplied */
+ for (ec=ecases;ec->type != exp_end;ec++) {
+ int matched = -1;
+
+ debuglog("{%s}? ",exp_printify(ec->pattern));
+ if (ec->type == exp_glob) {
+ int offset;
+ matched = Exp_StringMatch(exp_buffer,ec->pattern,&offset);
+ if (matched >= 0) {
+ exp_match = exp_buffer + offset;
+ exp_match_end = exp_match + matched;
+ }
+ } else if (ec->type == exp_exact) {
+ char *p = strstr(exp_buffer,ec->pattern);
+ if (p) {
+ matched = 1;
+ exp_match = p;
+ exp_match_end = p + strlen(ec->pattern);
+ }
+ } else if (ec->type == exp_null) {
+ char *p;
+
+ for (p=exp_buffer;p<exp_buffer_end;p++) {
+ if (*p == 0) {
+ matched = 1;
+ exp_match = p;
+ exp_match_end = p+1;
+ }
+ }
+ } else {
+ TclRegError((char *)0);
+ if (TclRegExec(ec->re,exp_buffer,exp_buffer)) {
+ matched = 1;
+ exp_match = ec->re->startp[0];
+ exp_match_end = ec->re->endp[0];
+ } else if (TclGetRegError()) {
+ fprintf(stderr,"r.e. match (pattern %s) failed: %s",ec->pattern,TclGetRegError());
+ }
+ }
+
+ if (matched != -1) {
+ debuglog("yes\nexp_buffer is {%s}\n",
+ exp_printify(exp_buffer));
+ return_normally(ec->value);
+ } else debuglog("no\n");
+ }
+
+ /*
+ * Update current time and remaining time.
+ * Don't bother if we are waiting forever or polling.
+ */
+ if (exp_timeout > 0) {
+ time(&current_time);
+ remtime = end_time - current_time;
+ }
+ }
+ cleanup:
+ f->buffer = exp_buffer;
+ f->buffer_end = exp_buffer_end;
+ f->match_end = exp_match_end;
+
+ /* some systems (i.e., Solaris) require fp be flushed when switching */
+ /* directions - do this before as well */
+ if (fd == -1) fflush(fp);
+
+ if (sys_error) {
+ errno = sys_error;
+ return -1;
+ }
+ return return_val;
+}
+
+int
+exp_fexpectv(fp,ecases)
+FILE *fp;
+struct exp_case *ecases;
+{
+ return(expectv(-1,fp,ecases));
+}
+
+int
+exp_expectv(fd,ecases)
+int fd;
+struct exp_case *ecases;
+{
+ return(expectv(fd,(FILE *)0,ecases));
+}
+
+/*VARARGS*/
+int
+exp_expectl TCL_VARARGS_DEF(int,arg1)
+/*exp_expectl(va_alist)*/
+/*va_dcl*/
+{
+ va_list args;
+ int fd;
+ struct exp_case *ec, *ecases;
+ int i;
+ enum exp_type type;
+
+ fd = TCL_VARARGS_START(int,arg1,args);
+ /* va_start(args);*/
+ /* fd = va_arg(args,int);*/
+ /* first just count the arg sets */
+ for (i=0;;i++) {
+ type = va_arg(args,enum exp_type);
+ if (type == exp_end) break;
+
+ /* Ultrix 4.2 compiler refuses enumerations comparison!? */
+ if ((int)type < 0 || (int)type >= (int)exp_bogus) {
+ fprintf(stderr,"bad type (set %d) in exp_expectl\n",i);
+ sysreturn(EINVAL);
+ }
+
+ va_arg(args,char *); /* COMPUTED BUT NOT USED */
+ if (type == exp_compiled) {
+ va_arg(args,regexp *); /* COMPUTED BUT NOT USED */
+ }
+ va_arg(args,int); /* COMPUTED BUT NOT USED*/
+ }
+ va_end(args);
+
+ if (!(ecases = (struct exp_case *)
+ malloc((1+i)*sizeof(struct exp_case))))
+ sysreturn(ENOMEM);
+
+ /* now set up the actual cases */
+ fd = TCL_VARARGS_START(int,arg1,args);
+ /*va_start(args);*/
+ /*va_arg(args,int);*/ /*COMPUTED BUT NOT USED*/
+ for (ec=ecases;;ec++) {
+ ec->type = va_arg(args,enum exp_type);
+ if (ec->type == exp_end) break;
+ ec->pattern = va_arg(args,char *);
+ if (ec->type == exp_compiled) {
+ ec->re = va_arg(args,regexp *);
+ } else {
+ ec->re = 0;
+ }
+ ec->value = va_arg(args,int);
+ }
+ va_end(args);
+ i = expectv(fd,(FILE *)0,ecases);
+
+ for (ec=ecases;ec->type != exp_end;ec++) {
+ /* free only if regexp and we compiled it for user */
+ if (ec->type == exp_regexp) {
+ free((char *)ec->re);
+ }
+ }
+ free((char *)ecases);
+ return(i);
+}
+
+int
+exp_fexpectl TCL_VARARGS_DEF(FILE *,arg1)
+/*exp_fexpectl(va_alist)*/
+/*va_dcl*/
+{
+ va_list args;
+ FILE *fp;
+ struct exp_case *ec, *ecases;
+ int i;
+ enum exp_type type;
+
+ fp = TCL_VARARGS_START(FILE *,arg1,args);
+ /*va_start(args);*/
+ /*fp = va_arg(args,FILE *);*/
+ /* first just count the arg-pairs */
+ for (i=0;;i++) {
+ type = va_arg(args,enum exp_type);
+ if (type == exp_end) break;
+
+ /* Ultrix 4.2 compiler refuses enumerations comparison!? */
+ if ((int)type < 0 || (int)type >= (int)exp_bogus) {
+ fprintf(stderr,"bad type (set %d) in exp_expectl\n",i);
+ sysreturn(EINVAL);
+ }
+
+ va_arg(args,char *); /* COMPUTED BUT NOT USED */
+ if (type == exp_compiled) {
+ va_arg(args,regexp *); /* COMPUTED BUT NOT USED */
+ }
+ va_arg(args,int); /* COMPUTED BUT NOT USED*/
+ }
+ va_end(args);
+
+ if (!(ecases = (struct exp_case *)
+ malloc((1+i)*sizeof(struct exp_case))))
+ sysreturn(ENOMEM);
+
+#if 0
+ va_start(args);
+ va_arg(args,FILE *); /*COMPUTED, BUT NOT USED*/
+#endif
+ (void) TCL_VARARGS_START(FILE *,arg1,args);
+
+ for (ec=ecases;;ec++) {
+ ec->type = va_arg(args,enum exp_type);
+ if (ec->type == exp_end) break;
+ ec->pattern = va_arg(args,char *);
+ if (ec->type == exp_compiled) {
+ ec->re = va_arg(args,regexp *);
+ } else {
+ ec->re = 0;
+ }
+ ec->value = va_arg(args,int);
+ }
+ va_end(args);
+ i = expectv(-1,fp,ecases);
+
+ for (ec=ecases;ec->type != exp_end;ec++) {
+ /* free only if regexp and we compiled it for user */
+ if (ec->type == exp_regexp) {
+ free((char *)ec->re);
+ }
+ }
+ free((char *)ecases);
+ return(i);
+}
+
+/* like popen(3) but works in both directions */
+FILE *
+exp_popen(program)
+char *program;
+{
+ FILE *fp;
+ int ec;
+
+ if (0 > (ec = exp_spawnl("sh","sh","-c",program,(char *)0))) return(0);
+ if (!(fp = fdopen(ec,"r+"))) return(0);
+ setbuf(fp,(char *)0);
+ return(fp);
+}
+
+int
+exp_disconnect()
+{
+ int ttyfd;
+
+#ifndef EALREADY
+#define EALREADY 37
+#endif
+
+ /* presumably, no stderr, so don't bother with error message */
+ if (exp_disconnected) sysreturn(EALREADY);
+ exp_disconnected = TRUE;
+
+ freopen("/dev/null","r",stdin);
+ freopen("/dev/null","w",stdout);
+ freopen("/dev/null","w",stderr);
+
+#ifdef POSIX
+ setsid();
+#else
+#ifdef SYSV3
+ /* put process in our own pgrp, and lose controlling terminal */
+ setpgrp();
+ signal(SIGHUP,SIG_IGN);
+ if (fork()) exit(0); /* first child exits (as per Stevens, */
+ /* UNIX Network Programming, p. 79-80) */
+ /* second child process continues as daemon */
+#else /* !SYSV3 */
+#ifdef MIPS_BSD
+ /* required on BSD side of MIPS OS <jmsellen@watdragon.waterloo.edu> */
+# include <sysv/sys.s>
+ syscall(SYS_setpgrp);
+#endif
+ setpgrp(0,getpid()); /* put process in our own pgrp */
+/* Pyramid lacks this defn */
+#ifdef TIOCNOTTY
+ ttyfd = open("/dev/tty", O_RDWR);
+ if (ttyfd >= 0) {
+ /* zap controlling terminal if we had one */
+ (void) ioctl(ttyfd, TIOCNOTTY, (char *)0);
+ (void) close(ttyfd);
+ }
+#endif /* TIOCNOTTY */
+#endif /* SYSV3 */
+#endif /* POSIX */
+ return(0);
+}
diff --git a/expect/exp_closetcl.c b/expect/exp_closetcl.c
new file mode 100644
index 00000000000..f219ae47d64
--- /dev/null
+++ b/expect/exp_closetcl.c
@@ -0,0 +1,22 @@
+/* exp_closetcl.c - close tcl files */
+
+/* isolated in it's own file since it has hooks into Tcl and exp_clib user */
+/* might like to avoid dragging it in */
+
+#include "expect_cf.h"
+#include "tclInt.h"
+
+void (*exp_close_in_child)() = 0;
+
+void
+exp_close_tcl_files() {
+ int i;
+
+ /* So much for close-on-exec. Tcl doesn't mark its files that way */
+ /* everything has to be closed explicitly. */
+
+#if 0
+/* Not necessary with Tcl 7.5? */
+ for (i=3; i<tclNumFiles;i++) close(i);
+#endif
+}
diff --git a/expect/exp_command.c b/expect/exp_command.c
new file mode 100644
index 00000000000..b0511909809
--- /dev/null
+++ b/expect/exp_command.c
@@ -0,0 +1,3709 @@
+/* exp_command.c - the bulk of the Expect commands
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include "expect_cf.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+/*#include <sys/time.h> seems to not be present on SVR3 systems */
+/* and it's not used anyway as far as I can tell */
+
+/* AIX insists that stropts.h be included before ioctl.h, because both */
+/* define _IO but only ioctl.h checks first. Oddly, they seem to be */
+/* defined differently! */
+#ifdef HAVE_STROPTS_H
+# include <sys/stropts.h>
+#endif
+#include <sys/ioctl.h>
+
+#ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#else
+# include <fcntl.h>
+#endif
+#include <sys/file.h>
+#include "exp_tty.h"
+
+#ifdef HAVE_SYS_WAIT_H
+ /* ISC doesn't def WNOHANG unless _POSIX_SOURCE is def'ed */
+# ifdef WNOHANG_REQUIRES_POSIX_SOURCE
+# define _POSIX_SOURCE
+# endif
+# include <sys/wait.h>
+# ifdef WNOHANG_REQUIRES_POSIX_SOURCE
+# undef _POSIX_SOURCE
+# endif
+#endif
+
+#include <errno.h>
+#include <signal.h>
+
+#if defined(SIGCLD) && !defined(SIGCHLD)
+#define SIGCHLD SIGCLD
+#endif
+
+/* Use _NSIG if NSIG not present */
+#ifndef NSIG
+#ifdef _NSIG
+#define NSIG _NSIG
+#endif
+#endif
+
+#ifdef HAVE_PTYTRAP
+#include <sys/ptyio.h>
+#endif
+
+#ifdef CRAY
+# ifndef TCSETCTTY
+# if defined(HAVE_TERMIOS)
+# include <termios.h>
+# else
+# include <termio.h>
+# endif
+# endif
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <math.h> /* for log/pow computation in send -h */
+#include <ctype.h> /* all this for ispunct! */
+
+#include "tclInt.h" /* need OpenFile */
+/*#include <varargs.h> tclInt.h drags in varargs.h. Since Pyramid */
+/* objects to including varargs.h twice, just */
+/* omit this one. */
+
+#include "tcl.h"
+#include "string.h"
+#include "expect_tcl.h"
+#include "exp_rename.h"
+#include "exp_prog.h"
+#include "exp_command.h"
+#include "exp_log.h"
+#include "exp_event.h"
+#include "exp_pty.h"
+#ifdef TCL_DEBUGGER
+#include "Dbg.h"
+#endif
+
+#define SPAWN_ID_VARNAME "spawn_id"
+
+int getptymaster();
+int getptyslave();
+
+int exp_forked = FALSE; /* whether we are child process */
+
+/* the following are just reserved addresses, to be used as ClientData */
+/* args to be used to tell commands how they were called. */
+/* The actual values won't be used, only the addresses, but I give them */
+/* values out of my irrational fear the compiler might collapse them all. */
+static int sendCD_error = 2; /* called as send_error */
+static int sendCD_user = 3; /* called as send_user */
+static int sendCD_proc = 4; /* called as send or send_spawn */
+static int sendCD_tty = 6; /* called as send_tty */
+
+struct exp_f *exp_fs = 0; /* process array (indexed by spawn_id's) */
+int exp_fd_max = -1; /* highest fd */
+
+/*
+ * expect_key is just a source for generating a unique stamp. As each
+ * expect/interact command begins, it generates a new key and marks all
+ * the spawn ids of interest with it. Then, if someone comes along and
+ * marks them with yet a newer key, the old command will recognize this
+ * reexamine the state of the spawned process.
+ */
+int expect_key = 0;
+
+/*
+ * exp_configure_count is incremented whenever a spawned process is closed
+ * or an indirect list is modified. This forces any (stack of) expect or
+ * interact commands to reexamine the state of the world and adjust
+ * accordingly.
+ */
+int exp_configure_count = 0;
+
+/* this message is required because fopen sometimes fails to set errno */
+/* Apparently, it "does the user a favor" and doesn't even call open */
+/* if the file name is bizarre enough. This means we can't handle fopen */
+/* with the obvious trivial logic. */
+static char *open_failed = "could not open - odd file name?";
+
+#ifdef HAVE_PTYTRAP
+/* slaveNames provides a mapping from the pty slave names to our */
+/* spawn id entry. This is needed only on HPs for stty, sigh. */
+static Tcl_HashTable slaveNames;
+#endif /* HAVE_PTYTRAP */
+
+#ifdef FULLTRAPS
+static void
+init_traps(traps)
+RETSIGTYPE (*traps[])();
+{
+ int i;
+
+ for (i=1;i<NSIG;i++) {
+ traps[i] = SIG_ERR;
+ }
+}
+#endif
+
+/* Do not terminate format strings with \n!!! */
+/*VARARGS*/
+void
+exp_error TCL_VARARGS_DEF(Tcl_Interp *,arg1)
+/*exp_error(va_alist)*/
+/*va_dcl*/
+{
+ Tcl_Interp *interp;
+ char *fmt;
+ va_list args;
+
+ interp = TCL_VARARGS_START(Tcl_Interp *,arg1,args);
+ /*va_start(args);*/
+ /*interp = va_arg(args,Tcl_Interp *);*/
+ fmt = va_arg(args,char *);
+ vsprintf(interp->result,fmt,args);
+ va_end(args);
+}
+
+/* returns handle if fd is usable, 0 if not */
+struct exp_f *
+exp_fd2f(interp,fd,opened,adjust,msg)
+Tcl_Interp *interp;
+int fd;
+int opened; /* check not closed */
+int adjust; /* adjust buffer sizes */
+char *msg;
+{
+ if (fd >= 0 && fd <= exp_fd_max && (exp_fs[fd].valid)) {
+ struct exp_f *f = exp_fs + fd;
+
+ /* following is a little tricky, do not be tempted do the */
+ /* 'usual' boolean simplification */
+ if ((!opened) || !f->user_closed) {
+ if (adjust) exp_adjust(f);
+ return f;
+ }
+ }
+
+ exp_error(interp,"%s: invalid spawn id (%d)",msg,fd);
+ return(0);
+}
+
+#if 0
+/* following routine is not current used, but might be later */
+/* returns fd or -1 if no such entry */
+static int
+pid_to_fd(pid)
+int pid;
+{
+ int fd;
+
+ for (fd=0;fd<=exp_fd_max;fd++) {
+ if (exp_fs[fd].pid == pid) return(fd);
+ }
+ return 0;
+}
+#endif
+
+/* Tcl needs commands in writable space */
+static char close_cmd[] = "close";
+
+/* zero out the wait status field */
+static void
+exp_wait_zero(status)
+WAIT_STATUS_TYPE *status;
+{
+ int i;
+
+ for (i=0;i<sizeof(WAIT_STATUS_TYPE);i++) {
+ ((char *)status)[i] = 0;
+ }
+}
+
+/* prevent an fd from being allocated */
+void
+exp_busy(fd)
+int fd;
+{
+ int x = open("/dev/null",0);
+ if (x != fd) {
+ fcntl(x,F_DUPFD,fd);
+ close(x);
+ }
+ exp_close_on_exec(fd);
+}
+
+/* called just before an exp_f entry is about to be invalidated */
+void
+exp_f_prep_for_invalidation(interp,f)
+Tcl_Interp *interp;
+struct exp_f *f;
+{
+ int fd = f - exp_fs;
+
+ exp_ecmd_remove_fd_direct_and_indirect(interp,fd);
+
+ exp_configure_count++;
+
+ if (f->buffer) {
+ ckfree(f->buffer);
+ f->buffer = 0;
+ f->msize = 0;
+ f->size = 0;
+ f->printed = 0;
+ f->echoed = 0;
+ if (f->fg_armed) {
+ exp_event_disarm(f-exp_fs);
+ f->fg_armed = FALSE;
+ }
+ ckfree(f->lower);
+ }
+ f->fg_armed = FALSE;
+}
+
+/*ARGSUSED*/
+void
+exp_trap_on(master)
+int master;
+{
+#ifdef HAVE_PTYTRAP
+ if (master == -1) return;
+ exp_slave_control(master,1);
+#endif /* HAVE_PTYTRAP */
+}
+
+int
+exp_trap_off(name)
+char *name;
+{
+#ifdef HAVE_PTYTRAP
+ int master;
+ struct exp_f *f;
+ int enable = 0;
+
+ Tcl_HashEntry *entry = Tcl_FindHashEntry(&slaveNames,name);
+ if (!entry) {
+ debuglog("exp_trap_off: no entry found for %s\n",name);
+ return -1;
+ }
+
+ f = (struct exp_f *)Tcl_GetHashValue(entry);
+ master = f - exp_fs;
+
+ exp_slave_control(master,0);
+
+ return master;
+#else
+ return name[0]; /* pacify lint, use arg and return something */
+#endif
+}
+
+/*ARGSUSED*/
+void
+sys_close(fd,f)
+int fd;
+struct exp_f *f;
+{
+ /* Ignore close errors. Some systems are really odd and */
+ /* return errors for no evident reason. Anyway, receiving */
+ /* an error upon pty-close doesn't mean anything anyway as */
+ /* far as I know. */
+ close(fd);
+ f->sys_closed = TRUE;
+
+#ifdef HAVE_PTYTRAP
+ if (f->slave_name) {
+ Tcl_HashEntry *entry;
+
+ entry = Tcl_FindHashEntry(&slaveNames,f->slave_name);
+ Tcl_DeleteHashEntry(entry);
+
+ ckfree(f->slave_name);
+ f->slave_name = 0;
+ }
+#endif
+}
+
+/* given a Tcl file identifier, close it */
+static void
+close_tcl_file(interp,file_id)
+Tcl_Interp *interp;
+char *file_id;
+{
+ Tcl_VarEval(interp,"close ",file_id,(char *)0);
+
+#if 0 /* old Tcl 7.6 code */
+ char *argv[3];
+ Tcl_CmdInfo info;
+
+ argv[0] = close_cmd;
+ argv[1] = file_id;
+ argv[2] = 0;
+
+ Tcl_ResetResult(interp);
+ Tcl_GetCommandInfo(interp,"close",&info);
+ if (0 == Tcl_GetCommandInfo(interp,"close",&info)) {
+ info.clientData = 0;
+ }
+ (void) Tcl_CloseCmd(info.clientData,interp,2,argv);
+#endif
+}
+
+
+/* close all connections
+The kernel would actually do this by default, however Tcl is going to
+come along later and try to reap its exec'd processes. If we have
+inherited any via spawn -open, Tcl can hang if we don't close the
+connections first.
+*/
+
+void
+exp_close_all(interp)
+Tcl_Interp *interp;
+{
+ int fd;
+
+ for (fd=0;fd<=exp_fd_max;fd++) {
+ if (exp_fs[fd].valid) {
+ exp_close(interp,fd);
+ }
+ }
+}
+
+int
+exp_close(interp,fd)
+Tcl_Interp *interp;
+int fd;
+{
+ struct exp_f *f = exp_fd2f(interp,fd,1,0,"close");
+ if (!f) return(TCL_ERROR);
+
+ f->user_closed = TRUE;
+
+ if (f->slave_fd != EXP_NOFD) close(f->slave_fd);
+#if 0
+ if (f->tcl_handle) {
+ ckfree(f->tcl_handle);
+ if ((f - exp_fs) != f->tcl_output) close(f->tcl_output);
+ }
+#endif
+ sys_close(fd,f);
+
+ if (f->tcl_handle) {
+ if ((f - exp_fs) != f->tcl_output) close(f->tcl_output);
+
+ if (!f->leaveopen) {
+ /*
+ * Ignore errors from close; they report things like
+ * broken pipeline, etc, which don't affect our
+ * subsequent handling.
+ */
+
+ close_tcl_file(interp,f->tcl_handle);
+
+ ckfree(f->tcl_handle);
+ f->tcl_handle = 0;
+ }
+ }
+
+ exp_f_prep_for_invalidation(interp,f);
+
+ if (f->user_waited) {
+ f->valid = FALSE;
+ } else {
+ exp_busy(fd);
+ f->sys_closed = FALSE;
+ }
+
+ return(TCL_OK);
+}
+
+static struct exp_f *
+fd_new(fd,pid)
+int fd;
+int pid;
+{
+ int i, low;
+ struct exp_f *newfs; /* temporary, so we don't lose old exp_fs */
+
+ /* resize table if nec */
+ if (fd > exp_fd_max) {
+ if (!exp_fs) { /* no fd's yet allocated */
+ newfs = (struct exp_f *)ckalloc(sizeof(struct exp_f)*(fd+1));
+ low = 0;
+ } else { /* enlarge fd table */
+ newfs = (struct exp_f *)ckrealloc((char *)exp_fs,sizeof(struct exp_f)*(fd+1));
+ low = exp_fd_max+1;
+ }
+ exp_fs = newfs;
+ exp_fd_max = fd;
+ for (i = low; i <= exp_fd_max; i++) { /* init new fd entries */
+ exp_fs[i].valid = FALSE;
+ exp_fs[i].fd_ptr = (int *)ckalloc(sizeof(int));
+ *exp_fs[i].fd_ptr = i;
+
+/* exp_fs[i].ptr = (struct exp_f **)ckalloc(sizeof(struct exp_fs *));*/
+
+ }
+
+#if 0
+ for (i = 0; i <= exp_fd_max; i++) { /* update all indirect ptrs */
+ *exp_fs[i].ptr = exp_fs + i;
+ }
+#endif
+ }
+
+ /* this could happen if user does "spawn -open stdin" I suppose */
+ if (exp_fs[fd].valid) return exp_fs+fd;
+
+ /* close down old table entry if nec */
+ exp_fs[fd].pid = pid;
+ exp_fs[fd].size = 0;
+ exp_fs[fd].msize = 0;
+ exp_fs[fd].buffer = 0;
+ exp_fs[fd].printed = 0;
+ exp_fs[fd].echoed = 0;
+ exp_fs[fd].rm_nulls = exp_default_rm_nulls;
+ exp_fs[fd].parity = exp_default_parity;
+ exp_fs[fd].key = expect_key++;
+ exp_fs[fd].force_read = FALSE;
+ exp_fs[fd].fg_armed = FALSE;
+#if TCL_MAJOR_VERSION < 8
+ /* Master must be inited each time because Tcl could have alloc'd */
+ /* this fd and shut it down (deallocating the FileHandle) behind */
+ /* our backs */
+ exp_fs[fd].Master = Tcl_GetFile((ClientData)fd,TCL_UNIX_FD);
+ exp_fs[fd].MasterOutput = 0;
+ exp_fs[fd].Slave = 0;
+#endif /* TCL_MAJOR_VERSION < 8 */
+#ifdef __CYGWIN32__
+ exp_fs[fd].channel = NULL;
+ exp_fs[fd].fileproc = NULL;
+#endif
+ exp_fs[fd].tcl_handle = 0;
+ exp_fs[fd].slave_fd = EXP_NOFD;
+#ifdef HAVE_PTYTRAP
+ exp_fs[fd].slave_name = 0;
+#endif /* HAVE_PTYTRAP */
+ exp_fs[fd].umsize = exp_default_match_max;
+ exp_fs[fd].valid = TRUE;
+ exp_fs[fd].user_closed = FALSE;
+ exp_fs[fd].sys_closed = FALSE;
+ exp_fs[fd].user_waited = FALSE;
+ exp_fs[fd].sys_waited = FALSE;
+ exp_fs[fd].bg_interp = 0;
+ exp_fs[fd].bg_status = unarmed;
+ exp_fs[fd].bg_ecount = 0;
+
+ return exp_fs+fd;
+}
+
+#if 0
+void
+exp_global_init(eg,duration,location)
+struct expect_global *eg;
+int duration;
+int location;
+{
+ eg->ecases = 0;
+ eg->ecount = 0;
+ eg->i_list = 0;
+ eg->duration = duration;
+ eg->location = location;
+}
+#endif
+
+void
+exp_init_spawn_id_vars(interp)
+Tcl_Interp *interp;
+{
+ Tcl_SetVar(interp,"user_spawn_id",EXP_SPAWN_ID_USER_LIT,0);
+ Tcl_SetVar(interp,"error_spawn_id",EXP_SPAWN_ID_ERROR_LIT,0);
+
+ /* note that the user_spawn_id is NOT /dev/tty which could */
+ /* (at least in theory anyway) be later re-opened on a different */
+ /* fd, while stdin might have been redirected away from /dev/tty */
+
+ if (exp_dev_tty != -1) {
+ char dev_tty_str[10];
+ sprintf(dev_tty_str,"%d",exp_dev_tty);
+ Tcl_SetVar(interp,"tty_spawn_id",dev_tty_str,0);
+ }
+}
+
+void
+exp_init_spawn_ids()
+{
+ /* note whether 0,1,2 are connected to a terminal so that if we */
+ /* disconnect, we can shut these down. We would really like to */
+ /* test if 0,1,2 are our controlling tty, but I don't know any */
+ /* way to do that portably. Anyway, the likelihood of anyone */
+ /* disconnecting after redirecting to a non-controlling tty is */
+ /* virtually zero. */
+
+ fd_new(0,isatty(0)?exp_getpid:EXP_NOPID);
+ fd_new(1,isatty(1)?exp_getpid:EXP_NOPID);
+ fd_new(2,isatty(2)?exp_getpid:EXP_NOPID);
+
+ if (exp_dev_tty != -1) {
+ fd_new(exp_dev_tty,exp_getpid);
+ }
+
+ /* really should be in interpreter() but silly to do on every call */
+ exp_adjust(&exp_fs[0]);
+}
+
+void
+exp_close_on_exec(fd)
+int fd;
+{
+ (void) fcntl(fd,F_SETFD,1);
+}
+
+#define STTY_INIT "stty_init"
+
+#if 0
+static void
+show_pgrp(fd,string)
+int fd;
+char *string;
+{
+ int pgrp;
+
+ fprintf(stderr,"getting pgrp for %s\n",string);
+ if (-1 == ioctl(fd,TIOCGETPGRP,&pgrp)) perror("TIOCGETPGRP");
+ else fprintf(stderr,"%s pgrp = %d\n",string,pgrp);
+ if (-1 == ioctl(fd,TIOCGPGRP,&pgrp)) perror("TIOCGPGRP");
+ else fprintf(stderr,"%s pgrp = %d\n",string,pgrp);
+ if (-1 == tcgetpgrp(fd,pgrp)) perror("tcgetpgrp");
+ else fprintf(stderr,"%s pgrp = %d\n",string,pgrp);
+}
+
+static void
+set_pgrp(fd)
+int fd;
+{
+ int pgrp = getpgrp(0);
+ if (-1 == ioctl(fd,TIOCSETPGRP,&pgrp)) perror("TIOCSETPGRP");
+ if (-1 == ioctl(fd,TIOCSPGRP,&pgrp)) perror("TIOCSPGRP");
+ if (-1 == tcsetpgrp(fd,pgrp)) perror("tcsetpgrp");
+}
+#endif
+
+/*ARGSUSED*/
+static void
+set_slave_name(f,name)
+struct exp_f *f;
+char *name;
+{
+#ifdef HAVE_PTYTRAP
+ int newptr;
+ Tcl_HashEntry *entry;
+
+ /* save slave name */
+ f->slave_name = ckalloc(strlen(exp_pty_slave_name)+1);
+ strcpy(f->slave_name,exp_pty_slave_name);
+
+ entry = Tcl_CreateHashEntry(&slaveNames,exp_pty_slave_name,&newptr);
+ Tcl_SetHashValue(entry,(ClientData)f);
+#endif /* HAVE_PTYTRAP */
+}
+
+#ifdef __CYGWIN32__
+/* Sometimes, the win32 version of expect passes a windows handle to
+ dup(), which normally only takes file descriptors. We check for
+ that with this wrapper. DJ */
+#include <windows.h>
+static int
+cygwin_pipe_dup (int oldfd)
+{
+ int rv = dup(oldfd);
+ if (rv != -1) /* cool */
+ return rv;
+ /* Oops, check for a handle */
+ if (GetFileType((HANDLE)oldfd) == FILE_TYPE_PIPE)
+ {
+ if (DuplicateHandle(GetCurrentProcess(),
+ (HANDLE)oldfd,
+ GetCurrentProcess(),
+ (HANDLE *)&rv,
+ 0, 0,
+ DUPLICATE_SAME_ACCESS))
+ {
+ int fd = cygwin32_attach_handle_to_fd ("/dev/piped",
+ -1, rv,
+ 1, O_RDWR);
+ if (fd >= 0)
+ return fd;
+ }
+ }
+ return -1;
+}
+#endif
+
+/* arguments are passed verbatim to execvp() */
+/*ARGSUSED*/
+static int
+Exp_SpawnCmd(clientData,interp,argc,argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int slave;
+ int pid;
+ char **a;
+ /* tell Saber to ignore non-use of ttyfd */
+ /*SUPPRESS 591*/
+ int errorfd; /* place to stash fileno(stderr) in child */
+ /* while we're setting up new stderr */
+ int ttyfd;
+ int master;
+ int write_master; /* write fd of Tcl-opened files */
+ int ttyinit = TRUE;
+ int ttycopy = TRUE;
+ int echo = TRUE;
+ int console = FALSE;
+ int pty_only = FALSE;
+
+#ifdef FULLTRAPS
+ /* Allow user to reset signals in child */
+ /* The following array contains indicates */
+ /* whether sig should be DFL or IGN */
+ /* ERR is used to indicate no initialization */
+ RETSIGTYPE (*traps[NSIG])();
+#endif
+ int ignore[NSIG]; /* if true, signal in child is ignored */
+ /* if false, signal gets default behavior */
+ int i; /* trusty overused temporary */
+
+ char *argv0 = argv[0];
+ char *openarg = 0;
+ int leaveopen = FALSE;
+ FILE *readfilePtr;
+ FILE *writefilePtr;
+ int rc, wc;
+ char *stty_init;
+ int slave_write_ioctls = 1;
+ /* by default, slave will be write-ioctled this many times */
+ int slave_opens = 3;
+ /* by default, slave will be opened this many times */
+ /* first comes from initial allocation */
+ /* second comes from stty */
+ /* third is our own signal that stty is done */
+
+ int sync_fds[2];
+ int sync2_fds[2];
+ int status_pipe[2];
+ int child_errno;
+ char sync_byte;
+
+ char buf[4]; /* enough space for a string literal */
+ /* representing a file descriptor */
+ Tcl_DString dstring;
+ Tcl_DStringInit(&dstring);
+
+#ifdef FULLTRAPS
+ init_traps(&traps);
+#endif
+ /* don't ignore any signals in child by default */
+ for (i=1;i<NSIG;i++) {
+ ignore[i] = FALSE;
+ }
+
+ argc--; argv++;
+
+ for (;argc>0;argc--,argv++) {
+ if (streq(*argv,"-nottyinit")) {
+ ttyinit = FALSE;
+ slave_write_ioctls--;
+ slave_opens--;
+ } else if (streq(*argv,"-nottycopy")) {
+ ttycopy = FALSE;
+ } else if (streq(*argv,"-noecho")) {
+ echo = FALSE;
+ } else if (streq(*argv,"-console")) {
+ console = TRUE;
+ } else if (streq(*argv,"-pty")) {
+ pty_only = TRUE;
+ } else if (streq(*argv,"-open")) {
+ if (argc < 2) {
+ exp_error(interp,"usage: -open file-identifier");
+ return TCL_ERROR;
+ }
+ openarg = argv[1];
+ argc--; argv++;
+ } else if (streq(*argv,"-leaveopen")) {
+ if (argc < 2) {
+ exp_error(interp,"usage: -open file-identifier");
+ return TCL_ERROR;
+ }
+ openarg = argv[1];
+ leaveopen = TRUE;
+ argc--; argv++;
+ } else if (streq(*argv,"-ignore")) {
+ int sig;
+
+ if (argc < 2) {
+ exp_error(interp,"usage: -ignore signal");
+ return TCL_ERROR;
+ }
+ sig = exp_string_to_signal(interp,argv[1]);
+ if (sig == -1) {
+ exp_error(interp,"usage: -ignore %s: unknown signal name",argv[1]);
+ return TCL_ERROR;
+ }
+ ignore[sig] = TRUE;
+ argc--; argv++;
+#ifdef FULLTRAPS
+ } else if (streq(*argv,"-trap")) {
+ /* argv[1] is action */
+ /* argv[2] is list of signals */
+
+ RETSIGTYPE (*sig_handler)();
+ int n; /* number of signals in list */
+ char **list; /* list of signals */
+
+ if (argc < 3) {
+ exp_error(interp,"usage: -trap siglist SIG_DFL or SIG_IGN");
+ return TCL_ERROR;
+ }
+
+ if (0 == strcmp(argv[2],"SIG_DFL")) {
+ sig_handler = SIG_DFL;
+ } else if (0 == strcmp(argv[2],"SIG_IGN")) {
+ sig_handler = SIG_IGN;
+ } else {
+ exp_error(interp,"usage: -trap siglist SIG_DFL or SIG_IGN");
+ return TCL_ERROR;
+ }
+
+ if (TCL_OK != Tcl_SplitList(interp,argv[1],&n,&list)) {
+ errorlog("%s\r\n",interp->result);
+ exp_error(interp,"usage: -trap {siglist} ...");
+ return TCL_ERROR;
+ }
+ for (i=0;i<n;i++) {
+ int sig = exp_string_to_signal(interp,list[i]);
+ if (sig == -1) {
+ ckfree((char *)&list);
+ return TCL_ERROR;
+ }
+ traps[sig] = sig_handler;
+ }
+ ckfree((char *)&list);
+
+ argc--; argv++;
+ argc--; argv++;
+#endif /*FULLTRAPS*/
+ } else break;
+ }
+
+ if (openarg && (argc != 0)) {
+ exp_error(interp,"usage: -[leave]open [fileXX]");
+ return TCL_ERROR;
+ }
+
+ if (!pty_only && !openarg && (argc == 0)) {
+ exp_error(interp,"usage: spawn [spawn-args] program [program-args]");
+ return(TCL_ERROR);
+ }
+
+ stty_init = exp_get_var(interp,STTY_INIT);
+ if (stty_init) {
+ slave_write_ioctls++;
+ slave_opens++;
+ }
+
+/* any extraneous ioctl's that occur in slave must be accounted for
+when trapping, see below in child half of fork */
+#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300)
+ slave_write_ioctls++;
+ slave_opens++;
+#endif
+
+ exp_pty_slave_name = 0;
+
+ Tcl_ReapDetachedProcs();
+
+ if (!openarg) {
+ if (echo) {
+ exp_log(0,"%s ",argv0);
+ for (a = argv;*a;a++) {
+ exp_log(0,"%s ",*a);
+ }
+ exp_nflog("\r\n",0);
+ }
+
+ if (0 > (master = getptymaster())) {
+ /*
+ * failed to allocate pty, try and figure out why
+ * so we can suggest to user what to do about it.
+ */
+
+ int count;
+ int testfd;
+
+ if (exp_pty_error) {
+ exp_error(interp,"%s",exp_pty_error);
+ return TCL_ERROR;
+ }
+
+ count = 0;
+ for (i=3;i<=exp_fd_max;i++) {
+ count += exp_fs[i].valid;
+ }
+ if (count > 10) {
+ exp_error(interp,"The system only has a finite number of ptys and you have many of them in use. The usual reason for this is that you forgot (or didn't know) to call \"wait\" after closing each of them.");
+ return TCL_ERROR;
+ }
+
+ testfd = open("/",0);
+ close(testfd);
+
+ if (testfd != -1) {
+ exp_error(interp,"The system has no more ptys. Ask your system administrator to create more.");
+ } else {
+ exp_error(interp,"- You have too many files are open. Close some files or increase your per-process descriptor limit.");
+ }
+ return(TCL_ERROR);
+ }
+#ifdef PTYTRAP_DIES
+ if (!pty_only) exp_slave_control(master,1);
+#endif /* PTYTRAP_DIES */
+
+#define SPAWN_OUT "spawn_out"
+ Tcl_SetVar2(interp,SPAWN_OUT,"slave,name",exp_pty_slave_name,0);
+ } else {
+ Tcl_Channel chan;
+ int mode;
+#if TCL_MAJOR_VERSION < 8
+ Tcl_File tclReadFile, tclWriteFile;
+#endif /* TCL_MAJOR_VERSION < 8 */
+ /* CYGNUS LOCAL 64bit/law */
+ /* These must be both wide enough and aligned enough for
+ the TCL code to store a pointer into them! */
+ void *rfd, *wfd;
+ /* END CYGNUS LOCAL */
+
+ if (echo) exp_log(0,"%s [open ...]\r\n",argv0);
+
+#if TCL7_4
+ rc = Tcl_GetOpenFile(interp,openarg,0,1,&readfilePtr);
+ wc = Tcl_GetOpenFile(interp,openarg,1,1,&writefilePtr);
+
+ /* fail only if both descriptors are bad */
+ if (rc == TCL_ERROR && wc == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+
+ master = fileno((rc == TCL_OK)?readfilePtr:writefilePtr);
+
+ /* make a new copy of file descriptor */
+ if (-1 == (write_master = master = dup(master))) {
+ exp_error(interp,"fdopen: %s",Tcl_PosixError(interp));
+ return TCL_ERROR;
+ }
+
+ /* if writefilePtr is different, dup that too */
+ if ((rc == TCL_OK) && (wc == TCL_OK) && (fileno(writefilePtr) != fileno(readfilePtr))) {
+ if (-1 == (write_master = dup(fileno(writefilePtr)))) {
+ exp_error(interp,"fdopen: %s",Tcl_PosixError(interp));
+ return TCL_ERROR;
+ }
+ exp_close_on_exec(write_master);
+ }
+
+#endif
+ if (!(chan = Tcl_GetChannel(interp,openarg,&mode))) {
+ return TCL_ERROR;
+ }
+ if (!mode) {
+ exp_error(interp,"channel is neither readable nor writable");
+ return TCL_ERROR;
+ }
+ if (mode & TCL_READABLE) {
+#if TCL_MAJOR_VERSION < 8
+ tclReadFile = Tcl_GetChannelFile(chan, TCL_READABLE);
+ rfd = (int)Tcl_GetFileInfo(tclReadFile, (int *)0);
+#else
+ if (TCL_ERROR == Tcl_GetChannelHandle(chan, TCL_READABLE, (ClientData) &rfd)) {
+ return TCL_ERROR;
+ }
+#endif /* TCL_MAJOR_VERSION < 8 */
+ }
+ if (mode & TCL_WRITABLE) {
+#if TCL_MAJOR_VERSION < 8
+ tclWriteFile = Tcl_GetChannelFile(chan, TCL_WRITABLE);
+ wfd = (int)Tcl_GetFileInfo(tclWriteFile, (int *)0);
+#else
+ if (TCL_ERROR == Tcl_GetChannelHandle(chan, TCL_WRITABLE, (ClientData) &wfd)) {
+ return TCL_ERROR;
+ }
+#endif /* TCL_MAJOR_VERSION < 8 */
+ }
+
+ master = ((mode & TCL_READABLE)?rfd:wfd);
+
+ /* make a new copy of file descriptor */
+#ifdef __CYGWIN32__
+ if (-1 == (write_master = master = cygwin_pipe_dup(master))) {
+#else
+ if (-1 == (write_master = master = dup(master))) {
+#endif
+ exp_error(interp,"fdopen: %s",Tcl_PosixError(interp));
+ return TCL_ERROR;
+ }
+
+ /* if writefilePtr is different, dup that too */
+ if ((mode & TCL_READABLE) && (mode & TCL_WRITABLE) && (wfd != rfd)) {
+ if (-1 == (write_master = dup(wfd))) {
+ exp_error(interp,"fdopen: %s",Tcl_PosixError(interp));
+ return TCL_ERROR;
+ }
+ exp_close_on_exec(write_master);
+ }
+
+ /*
+ * It would be convenient now to tell Tcl to close its
+ * file descriptor. Alas, if involved in a pipeline, Tcl
+ * will be unable to complete a wait on the process.
+ * So simply remember that we meant to close it. We will
+ * do so later in our own close routine.
+ */
+ }
+
+ /* much easier to set this, than remember all masters */
+ exp_close_on_exec(master);
+
+ if (openarg || pty_only) {
+ struct exp_f *f;
+
+ f = fd_new(master,EXP_NOPID);
+
+ if (openarg) {
+ /* save file# handle */
+ f->tcl_handle = ckalloc(strlen(openarg)+1);
+ strcpy(f->tcl_handle,openarg);
+
+ f->tcl_output = write_master;
+#if 0
+ /* save fd handle for output */
+ if (wc == TCL_OK) {
+/* f->tcl_output = fileno(writefilePtr);*/
+ f->tcl_output = write_master;
+ } else {
+ /* if we actually try to write to it at some */
+ /* time in the future, then this will cause */
+ /* an error */
+ f->tcl_output = master;
+ }
+#endif
+
+ f->leaveopen = leaveopen;
+ }
+
+ if (exp_pty_slave_name) set_slave_name(f,exp_pty_slave_name);
+
+ /* make it appear as if process has been waited for */
+ f->sys_waited = TRUE;
+ exp_wait_zero(&f->wait);
+
+ /* tell user id of new process */
+ sprintf(buf,"%d",master);
+ Tcl_SetVar(interp,SPAWN_ID_VARNAME,buf,0);
+
+ if (!openarg) {
+ char value[20];
+ int dummyfd1, dummyfd2;
+
+ /*
+ * open the slave side in the same process to support
+ * the -pty flag.
+ */
+
+ /* Start by working around a bug in Tcl's exec.
+ It closes all the file descriptors from 3 to it's
+ own fd_max which inappropriately closes our slave
+ fd. To avoid this, open several dummy fds. Then
+ exec's fds will fall below ours.
+ Note that if you do something like pre-allocating
+ a bunch before using them or generating a pipeline,
+ then this code won't help.
+ Instead you'll need to add the right number of
+ explicit Tcl open's of /dev/null.
+ The right solution is fix Tcl's exec so it is not
+ so cavalier.
+ */
+
+ dummyfd1 = open("/dev/null",0);
+ dummyfd2 = open("/dev/null",0);
+
+ if (0 > (f->slave_fd = getptyslave(ttycopy,ttyinit,
+ stty_init))) {
+ exp_error(interp,"open(slave pty): %s\r\n",Tcl_PosixError(interp));
+ return TCL_ERROR;
+ }
+
+ close(dummyfd1);
+ close(dummyfd2);
+
+ exp_slave_control(master,1);
+
+ sprintf(value,"%d",f->slave_fd);
+ Tcl_SetVar2(interp,SPAWN_OUT,"slave,fd",value,0);
+ }
+ sprintf(interp->result,"%d",EXP_NOPID);
+ debuglog("spawn: returns {%s}\r\n",interp->result);
+
+ return TCL_OK;
+ }
+
+ if (NULL == (argv[0] = Tcl_TildeSubst(interp,argv[0],&dstring))) {
+ goto parent_error;
+ }
+
+ if (-1 == pipe(sync_fds)) {
+ exp_error(interp,"too many programs spawned? could not create pipe: %s",Tcl_PosixError(interp));
+ goto parent_error;
+ }
+
+ if (-1 == pipe(sync2_fds)) {
+ close(sync_fds[0]);
+ close(sync_fds[1]);
+ exp_error(interp,"too many programs spawned? could not create pipe: %s",Tcl_PosixError(interp));
+ goto parent_error;
+ }
+
+ if (-1 == pipe(status_pipe)) {
+ close(sync_fds[0]);
+ close(sync_fds[1]);
+ close(sync2_fds[0]);
+ close(sync2_fds[1]);
+ }
+
+ if ((pid = fork()) == -1) {
+ exp_error(interp,"fork: %s",Tcl_PosixError(interp));
+ goto parent_error;
+ }
+
+ if (pid) { /* parent */
+ struct exp_f *f;
+
+ close(sync_fds[1]);
+ close(sync2_fds[0]);
+ close(status_pipe[1]);
+
+ f = fd_new(master,pid);
+
+ if (exp_pty_slave_name) set_slave_name(f,exp_pty_slave_name);
+
+#ifdef CRAY
+ setptypid(pid);
+#endif
+
+
+#if PTYTRAP_DIES
+#ifdef HAVE_PTYTRAP
+
+ while (slave_opens) {
+ int cc;
+ cc = exp_wait_for_slave_open(master);
+#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300)
+ if (cc == TIOCSCTTY) slave_opens = 0;
+#endif
+ if (cc == TIOCOPEN) slave_opens--;
+ if (cc == -1) {
+ exp_error(interp,"failed to trap slave pty");
+ goto parent_error;
+ }
+ }
+
+#if 0
+ /* trap initial ioctls in a feeble attempt to not block */
+ /* the initially. If the process itself ioctls */
+ /* /dev/tty, such blocks will be trapped later */
+ /* during normal event processing */
+
+ /* initial slave ioctl */
+ while (slave_write_ioctls) {
+ int cc;
+
+ cc = exp_wait_for_slave_open(master);
+#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300)
+ if (cc == TIOCSCTTY) slave_write_ioctls = 0;
+#endif
+ if (cc & IOC_IN) slave_write_ioctls--;
+ else if (cc == -1) {
+ exp_error(interp,"failed to trap slave pty");
+ goto parent_error;
+ }
+ }
+#endif /*0*/
+
+#endif /* HAVE_PTYTRAP */
+#endif /* PTYTRAP_DIES */
+
+ /*
+ * wait for slave to initialize pty before allowing
+ * user to send to it
+ */
+
+ debuglog("parent: waiting for sync byte\r\n");
+ while (((rc = read(sync_fds[0],&sync_byte,1)) < 0) && (errno == EINTR)) {
+ /* empty */;
+ }
+ if (rc == -1) {
+ errorlog("parent: sync byte read: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+
+ /* turn on detection of eof */
+ exp_slave_control(master,1);
+
+ /*
+ * tell slave to go on now now that we have initialized pty
+ */
+
+ debuglog("parent: telling child to go ahead\r\n");
+ wc = write(sync2_fds[1]," ",1);
+ if (wc == -1) {
+ errorlog("parent: sync byte write: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+
+ debuglog("parent: now unsynchronized from child\r\n");
+ close(sync_fds[0]);
+ close(sync2_fds[1]);
+
+ /* see if child's exec worked */
+ retry:
+ switch (read(status_pipe[0],&child_errno,sizeof child_errno)) {
+ case -1:
+ if (errno == EINTR) goto retry;
+ /* well it's not really the child's errno */
+ /* but it can be treated that way */
+ child_errno = errno;
+ break;
+ case 0:
+ /* child's exec succeeded */
+ child_errno = 0;
+ break;
+ default:
+ /* child's exec failed; err contains exec's errno */
+ waitpid(pid, NULL, 0);
+ /* in order to get Tcl to set errorcode, we must */
+ /* hand set errno */
+ errno = child_errno;
+ exp_error(interp, "couldn't execute \"%s\": %s",
+ argv[0],Tcl_PosixError(interp));
+ goto parent_error;
+ }
+ close(status_pipe[0]);
+
+
+ /* tell user id of new process */
+ sprintf(buf,"%d",master);
+ Tcl_SetVar(interp,SPAWN_ID_VARNAME,buf,0);
+
+ sprintf(interp->result,"%d",pid);
+ debuglog("spawn: returns {%s}\r\n",interp->result);
+
+ Tcl_DStringFree(&dstring);
+ return(TCL_OK);
+parent_error:
+ Tcl_DStringFree(&dstring);
+ return TCL_ERROR;
+ }
+
+ /* child process - do not return from here! all errors must exit() */
+
+ close(sync_fds[0]);
+ close(sync2_fds[1]);
+ close(status_pipe[0]);
+ exp_close_on_exec(status_pipe[1]);
+
+ if (exp_dev_tty != -1) {
+ close(exp_dev_tty);
+ exp_dev_tty = -1;
+ }
+
+#ifdef CRAY
+ (void) close(master);
+#endif
+
+/* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */
+/* is called. setpgrp works though. */
+#if defined(POSIX) && !defined(ultrix)
+#define DO_SETSID
+#endif
+#ifdef __convex__
+#define DO_SETSID
+#endif
+
+#ifdef DO_SETSID
+ setsid();
+#else
+#ifdef SYSV3
+#ifndef CRAY
+ setpgrp();
+#endif /* CRAY */
+#else /* !SYSV3 */
+#ifdef MIPS_BSD
+ /* required on BSD side of MIPS OS <jmsellen@watdragon.waterloo.edu> */
+# include <sysv/sys.s>
+ syscall(SYS_setpgrp);
+#endif
+ setpgrp(0,0);
+/* setpgrp(0,getpid());*/ /* make a new pgrp leader */
+
+/* Pyramid lacks this defn */
+#ifdef TIOCNOTTY
+ ttyfd = open("/dev/tty", O_RDWR);
+ if (ttyfd >= 0) {
+ (void) ioctl(ttyfd, TIOCNOTTY, (char *)0);
+ (void) close(ttyfd);
+ }
+#endif /* TIOCNOTTY */
+
+#endif /* SYSV3 */
+#endif /* DO_SETSID */
+
+ /* save stderr elsewhere to avoid BSD4.4 bogosity that warns */
+ /* if stty finds dev(stderr) != dev(stdout) */
+
+ /* save error fd while we're setting up new one */
+ errorfd = fcntl(2,F_DUPFD,3);
+ /* and here is the macro to restore it */
+#define restore_error_fd {close(2);fcntl(errorfd,F_DUPFD,2);}
+
+ close(0);
+ close(1);
+ close(2);
+
+ /* since we closed fd 0, open of pty slave must return fd 0 */
+
+ /* since getptyslave may have to run stty, (some of which work on fd */
+ /* 0 and some of which work on 1) do the dup's inside getptyslave. */
+
+ if (0 > (slave = getptyslave(ttycopy,ttyinit,stty_init))) {
+ restore_error_fd
+ errorlog("open(slave pty): %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+ /* sanity check */
+ if (slave != 0) {
+ restore_error_fd
+ errorlog("getptyslave: slave = %d but expected 0\n",slave);
+ exit(-1);
+ }
+
+/* The test for hpux may have to be more specific. In particular, the */
+/* code should be skipped on the hp9000s300 and hp9000s720 (but there */
+/* is no documented define for the 720!) */
+
+/*#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hpux)*/
+#if defined(TIOCSCTTY) && !defined(sun) && !defined(hpux)
+ /* 4.3+BSD way to acquire controlling terminal */
+ /* according to Stevens - Adv. Prog..., p 642 */
+ /* Oops, it appears that the CIBAUD is on Linux also */
+ /* so let's try without... */
+#ifdef __QNX__
+ if (tcsetct(0, getpid()) == -1) {
+#else
+ if (ioctl(0,TIOCSCTTY,(char *)0) < 0) {
+#endif
+ restore_error_fd
+ errorlog("failed to get controlling terminal using TIOCSCTTY");
+ exit(-1);
+ }
+#endif
+
+#ifdef CRAY
+ (void) setsid();
+ (void) ioctl(0,TCSETCTTY,0);
+ (void) close(0);
+ if (open("/dev/tty", O_RDWR) < 0) {
+ restore_error_fd
+ errorlog("open(/dev/tty): %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+ (void) close(1);
+ (void) close(2);
+ (void) dup(0);
+ (void) dup(0);
+ setptyutmp(); /* create a utmp entry */
+
+ /* _CRAY2 code from Hal Peterson <hrp@cray.com>, Cray Research, Inc. */
+#ifdef _CRAY2
+ /*
+ * Interpose a process between expect and the spawned child to
+ * keep the slave side of the pty open to allow time for expect
+ * to read the last output. This is a workaround for an apparent
+ * bug in the Unicos pty driver on Cray-2's under Unicos 6.0 (at
+ * least).
+ */
+ if ((pid = fork()) == -1) {
+ restore_error_fd
+ errorlog("second fork: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+
+ if (pid) {
+ /* Intermediate process. */
+ int status;
+ int timeout;
+ char *t;
+
+ /* How long should we wait? */
+ if (t = exp_get_var(interp,"pty_timeout"))
+ timeout = atoi(t);
+ else if (t = exp_get_var(interp,"timeout"))
+ timeout = atoi(t)/2;
+ else
+ timeout = 5;
+
+ /* Let the spawned process run to completion. */
+ while (wait(&status) < 0 && errno == EINTR)
+ /* empty body */;
+
+ /* Wait for the pty to clear. */
+ sleep(timeout);
+
+ /* Duplicate the spawned process's status. */
+ if (WIFSIGNALED(status))
+ kill(getpid(), WTERMSIG(status));
+
+ /* The kill may not have worked, but this will. */
+ exit(WEXITSTATUS(status));
+ }
+#endif /* _CRAY2 */
+#endif /* CRAY */
+
+ if (console) exp_console_set();
+
+#ifdef FULLTRAPS
+ for (i=1;i<NSIG;i++) {
+ if (traps[i] != SIG_ERR) {
+ signal(i,traps[i]);
+ }
+ }
+#endif /* FULLTRAPS */
+
+ for (i=1;i<NSIG;i++) {
+ signal(i,ignore[i]?SIG_IGN:SIG_DFL);
+ }
+
+#if 0
+ /* avoid fflush of cmdfile since this screws up the parents seek ptr */
+ /* There is no portable way to fclose a shared read-stream!!!! */
+ if (exp_cmdfile && (exp_cmdfile != stdin))
+ (void) close(fileno(exp_cmdfile));
+ if (logfile) (void) fclose(logfile);
+ if (debugfile) (void) fclose(debugfile);
+#endif
+ /* (possibly multiple) masters are closed automatically due to */
+ /* earlier fcntl(,,CLOSE_ON_EXEC); */
+
+ /* tell parent that we are done setting up pty */
+ /* The actual char sent back is irrelevant. */
+
+ /* debuglog("child: telling parent that pty is initialized\r\n");*/
+ wc = write(sync_fds[1]," ",1);
+ if (wc == -1) {
+ restore_error_fd
+ errorlog("child: sync byte write: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+ close(sync_fds[1]);
+
+ /* wait for master to let us go on */
+ /* debuglog("child: waiting for go ahead from parent\r\n"); */
+
+/* close(master); /* force master-side close so we can read */
+
+ while (((rc = read(sync2_fds[0],&sync_byte,1)) < 0) && (errno == EINTR)) {
+ /* empty */;
+ }
+
+ if (rc == -1) {
+ restore_error_fd
+ errorlog("child: sync byte read: %s\r\n",Tcl_ErrnoMsg(errno));
+ exit(-1);
+ }
+ close(sync2_fds[0]);
+
+ /* debuglog("child: now unsynchronized from parent\r\n"); */
+
+ /* So much for close-on-exec. Tcl doesn't mark its files that way */
+ /* everything has to be closed explicitly. */
+ if (exp_close_in_child) (*exp_close_in_child)();
+
+ (void) execvp(argv[0],argv);
+#if 0
+ /* Unfortunately, by now we've closed fd's to stderr, logfile and
+ debugfile.
+ The only reasonable thing to do is to send back the error as
+ part of the program output. This will be picked up in an
+ expect or interact command.
+ */
+ errorlog("%s: %s\r\n",argv[0],Tcl_ErrnoMsg(errno));
+#endif
+ /* if exec failed, communicate the reason back to the parent */
+ write(status_pipe[1], &errno, sizeof errno);
+ exit(-1);
+ /*NOTREACHED*/
+}
+
+/*ARGSUSED*/
+static int
+Exp_ExpPidCmd(clientData,interp,argc,argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ struct exp_f *f;
+ int m = -1;
+
+ argc--; argv++;
+
+ for (;argc>0;argc--,argv++) {
+ if (streq(*argv,"-i")) {
+ argc--; argv++;
+ if (!*argv) goto usage;
+ m = atoi(*argv);
+ } else goto usage;
+ }
+
+ if (m == -1) {
+ if (exp_update_master(interp,&m,0,0) == 0) return TCL_ERROR;
+ }
+
+ if (0 == (f = exp_fd2f(interp,m,1,0,"exp_pid"))) return TCL_ERROR;
+
+ sprintf(interp->result,"%d",f->pid);
+ return TCL_OK;
+ usage:
+ exp_error(interp,"usage: -i spawn_id");
+ return TCL_ERROR;
+}
+
+/*ARGSUSED*/
+static int
+Exp_GetpidDeprecatedCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ debuglog("getpid is deprecated, use pid\r\n");
+ sprintf(interp->result,"%d",getpid());
+ return(TCL_OK);
+}
+
+/* returns current master (via out-parameter) */
+/* returns f or 0, but note that since exp_fd2f calls tcl_error, this */
+/* may be immediately followed by a "return(TCL_ERROR)"!!! */
+struct exp_f *
+exp_update_master(interp,m,opened,adjust)
+Tcl_Interp *interp;
+int *m;
+int opened;
+int adjust;
+{
+ char *s = exp_get_var(interp,SPAWN_ID_VARNAME);
+ *m = (s?atoi(s):EXP_SPAWN_ID_USER);
+ return(exp_fd2f(interp,*m,opened,adjust,(s?s:EXP_SPAWN_ID_USER_LIT)));
+}
+
+/*ARGSUSED*/
+static int
+Exp_SleepCmd(clientData,interp,argc,argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ argc--; argv++;
+
+ if (argc != 1) {
+ exp_error(interp,"must have one arg: seconds");
+ return TCL_ERROR;
+ }
+
+ return(exp_dsleep(interp,(double)atof(*argv)));
+}
+
+/* write exactly this many bytes, i.e. retry partial writes */
+/* returns 0 for success, -1 for failure */
+static int
+exact_write(fd,buffer,rembytes)
+int fd;
+char *buffer;
+int rembytes;
+{
+ int cc;
+
+ while (rembytes) {
+ if (-1 == (cc = write(fd,buffer,rembytes))) return(-1);
+ if (0 == cc) {
+ /* This shouldn't happen but I'm told that it does */
+ /* nonetheless (at least on SunOS 4.1.3). Since */
+ /* this is not a documented return value, the most */
+ /* reasonable thing is to complain here and retry */
+ /* in the hopes that is some transient condition. */
+ sleep(1);
+ exp_debuglog("write() failed to write anything but returned - sleeping and retrying...\n");
+ }
+
+ buffer += cc;
+ rembytes -= cc;
+ }
+ return(0);
+}
+
+struct slow_arg {
+ int size;
+ double time;
+};
+
+/* returns 0 for success, -1 for failure */
+static int
+get_slow_args(interp,x)
+Tcl_Interp *interp;
+struct slow_arg *x;
+{
+ int sc; /* return from scanf */
+ char *s = exp_get_var(interp,"send_slow");
+ if (!s) {
+ exp_error(interp,"send -s: send_slow has no value");
+ return(-1);
+ }
+ if (2 != (sc = sscanf(s,"%d %lf",&x->size,&x->time))) {
+ exp_error(interp,"send -s: found %d value(s) in send_slow but need 2",sc);
+ return(-1);
+ }
+ if (x->size <= 0) {
+ exp_error(interp,"send -s: size (%d) in send_slow must be positive", x->size);
+ return(-1);
+ }
+ if (x->time <= 0) {
+ exp_error(interp,"send -s: time (%f) in send_slow must be larger",x->time);
+ return(-1);
+ }
+ return(0);
+}
+
+/* returns 0 for success, -1 for failure, pos. for Tcl return value */
+static int
+slow_write(interp,fd,buffer,rembytes,arg)
+Tcl_Interp *interp;
+int fd;
+char *buffer;
+int rembytes;
+struct slow_arg *arg;
+{
+ int rc;
+
+ while (rembytes > 0) {
+ int len;
+
+ len = (arg->size<rembytes?arg->size:rembytes);
+ if (0 > exact_write(fd,buffer,len)) return(-1);
+ rembytes -= arg->size;
+ buffer += arg->size;
+
+ /* skip sleep after last write */
+ if (rembytes > 0) {
+ rc = exp_dsleep(interp,arg->time);
+ if (rc>0) return rc;
+ }
+ }
+ return(0);
+}
+
+struct human_arg {
+ float alpha; /* average interarrival time in seconds */
+ float alpha_eow; /* as above but for eow transitions */
+ float c; /* shape */
+ float min, max;
+};
+
+/* returns -1 if error, 0 if success */
+static int
+get_human_args(interp,x)
+Tcl_Interp *interp;
+struct human_arg *x;
+{
+ int sc; /* return from scanf */
+ char *s = exp_get_var(interp,"send_human");
+
+ if (!s) {
+ exp_error(interp,"send -h: send_human has no value");
+ return(-1);
+ }
+ if (5 != (sc = sscanf(s,"%f %f %f %f %f",
+ &x->alpha,&x->alpha_eow,&x->c,&x->min,&x->max))) {
+ if (sc == EOF) sc = 0; /* make up for overloaded return */
+ exp_error(interp,"send -h: found %d value(s) in send_human but need 5",sc);
+ return(-1);
+ }
+ if (x->alpha < 0 || x->alpha_eow < 0) {
+ exp_error(interp,"send -h: average interarrival times (%f %f) must be non-negative in send_human", x->alpha,x->alpha_eow);
+ return(-1);
+ }
+ if (x->c <= 0) {
+ exp_error(interp,"send -h: variability (%f) in send_human must be positive",x->c);
+ return(-1);
+ }
+ x->c = 1/x->c;
+
+ if (x->min < 0) {
+ exp_error(interp,"send -h: minimum (%f) in send_human must be non-negative",x->min);
+ return(-1);
+ }
+ if (x->max < 0) {
+ exp_error(interp,"send -h: maximum (%f) in send_human must be non-negative",x->max);
+ return(-1);
+ }
+ if (x->max < x->min) {
+ exp_error(interp,"send -h: maximum (%f) must be >= minimum (%f) in send_human",x->max,x->min);
+ return(-1);
+ }
+ return(0);
+}
+
+/* Compute random numbers from 0 to 1, for expect's send -h */
+/* This implementation sacrifices beauty for portability */
+static float
+unit_random()
+{
+ /* current implementation is pathetic but works */
+ /* 99991 is largest prime in my CRC - can't hurt, eh? */
+ return((float)(1+(rand()%99991))/99991.0);
+}
+
+void
+exp_init_unit_random()
+{
+ srand(getpid());
+}
+
+/* This function is my implementation of the Weibull distribution. */
+/* I've added a max time and an "alpha_eow" that captures the slight */
+/* but noticable change in human typists when hitting end-of-word */
+/* transitions. */
+/* returns 0 for success, -1 for failure, pos. for Tcl return value */
+static int
+human_write(interp,fd,buffer,arg)
+Tcl_Interp *interp;
+int fd;
+char *buffer;
+struct human_arg *arg;
+{
+ char *sp;
+ float t;
+ float alpha;
+ int wc;
+ int in_word = TRUE;
+
+ debuglog("human_write: avg_arr=%f/%f 1/shape=%f min=%f max=%f\r\n",
+ arg->alpha,arg->alpha_eow,arg->c,arg->min,arg->max);
+
+ for (sp = buffer;*sp;sp++) {
+ /* use the end-of-word alpha at eow transitions */
+ if (in_word && (ispunct(*sp) || isspace(*sp)))
+ alpha = arg->alpha_eow;
+ else alpha = arg->alpha;
+ in_word = !(ispunct(*sp) || isspace(*sp));
+
+ t = alpha * pow(-log((double)unit_random()),arg->c);
+
+ /* enforce min and max times */
+ if (t<arg->min) t = arg->min;
+ else if (t>arg->max) t = arg->max;
+
+/*fprintf(stderr,"\nwriting <%c> but first sleep %f seconds\n",*sp,t);*/
+ /* skip sleep before writing first character */
+ if (sp != buffer) {
+ wc = exp_dsleep(interp,(double)t);
+ if (wc > 0) return wc;
+ }
+
+ wc = write(fd,sp,1);
+ if (0 > wc) return(wc);
+ }
+ return(0);
+}
+
+struct exp_i *exp_i_pool = 0;
+struct exp_fd_list *exp_fd_list_pool = 0;
+
+#define EXP_I_INIT_COUNT 10
+#define EXP_FD_INIT_COUNT 10
+
+struct exp_i *
+exp_new_i()
+{
+ int n;
+ struct exp_i *i;
+
+ if (!exp_i_pool) {
+ /* none avail, generate some new ones */
+ exp_i_pool = i = (struct exp_i *)ckalloc(
+ EXP_I_INIT_COUNT * sizeof(struct exp_i));
+ for (n=0;n<EXP_I_INIT_COUNT-1;n++,i++) {
+ i->next = i+1;
+ }
+ i->next = 0;
+ }
+
+ /* now that we've made some, unlink one and give to user */
+
+ i = exp_i_pool;
+ exp_i_pool = exp_i_pool->next;
+ i->value = 0;
+ i->variable = 0;
+ i->fd_list = 0;
+ i->ecount = 0;
+ i->next = 0;
+ return i;
+}
+
+struct exp_fd_list *
+exp_new_fd(val)
+int val;
+{
+ int n;
+ struct exp_fd_list *fd;
+
+ if (!exp_fd_list_pool) {
+ /* none avail, generate some new ones */
+ exp_fd_list_pool = fd = (struct exp_fd_list *)ckalloc(
+ EXP_FD_INIT_COUNT * sizeof(struct exp_fd_list));
+ for (n=0;n<EXP_FD_INIT_COUNT-1;n++,fd++) {
+ fd->next = fd+1;
+ }
+ fd->next = 0;
+ }
+
+ /* now that we've made some, unlink one and give to user */
+
+ fd = exp_fd_list_pool;
+ exp_fd_list_pool = exp_fd_list_pool->next;
+ fd->fd = val;
+ /* fd->next is assumed to be changed by caller */
+ return fd;
+}
+
+void
+exp_free_fd(fd_first)
+struct exp_fd_list *fd_first;
+{
+ struct exp_fd_list *fd, *penultimate;
+
+ if (!fd_first) return;
+
+ /* link entire chain back in at once by first finding last pointer */
+ /* making that point back to pool, and then resetting pool to this */
+
+ /* run to end */
+ for (fd = fd_first;fd;fd=fd->next) {
+ penultimate = fd;
+ }
+ penultimate->next = exp_fd_list_pool;
+ exp_fd_list_pool = fd_first;
+}
+
+/* free a single fd */
+void
+exp_free_fd_single(fd)
+struct exp_fd_list *fd;
+{
+ fd->next = exp_fd_list_pool;
+ exp_fd_list_pool = fd;
+}
+
+void
+exp_free_i(interp,i,updateproc)
+Tcl_Interp *interp;
+struct exp_i *i;
+Tcl_VarTraceProc *updateproc; /* proc to invoke if indirect is written */
+{
+ if (i->next) exp_free_i(interp,i->next,updateproc);
+
+ exp_free_fd(i->fd_list);
+
+ if (i->direct == EXP_INDIRECT) {
+ Tcl_UntraceVar(interp,i->variable,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES,
+ updateproc,(ClientData)i);
+ }
+
+ /* here's the long form
+ if duration & direct free(var) free(val)
+ PERM DIR 1
+ PERM INDIR 1 1
+ TMP DIR
+ TMP INDIR 1
+ Also if i->variable was a bogus variable name, i->value might not be
+ set, so test i->value to protect this
+ TMP in this case does NOT mean from the "expect" command. Rather
+ it means "an implicit spawn id from any expect or expect_XXX
+ command". In other words, there was no variable name provided.
+ */
+ if (i->value
+ && (((i->direct == EXP_DIRECT) && (i->duration == EXP_PERMANENT))
+ || ((i->direct == EXP_INDIRECT) && (i->duration == EXP_TEMPORARY)))) {
+ ckfree(i->value);
+ } else if (i->duration == EXP_PERMANENT) {
+ if (i->value) ckfree(i->value);
+ if (i->variable) ckfree(i->variable);
+ }
+
+ i->next = exp_i_pool;
+ exp_i_pool = i;
+}
+
+/* generate a descriptor for a "-i" flag */
+/* cannot fail */
+struct exp_i *
+exp_new_i_complex(interp,arg,duration,updateproc)
+Tcl_Interp *interp;
+char *arg; /* spawn id list or a variable containing a list */
+int duration; /* if we have to copy the args */
+ /* should only need do this in expect_before/after */
+Tcl_VarTraceProc *updateproc; /* proc to invoke if indirect is written */
+{
+ struct exp_i *i;
+ char **stringp;
+
+ i = exp_new_i();
+
+ i->direct = (isdigit(arg[0]) || (arg[0] == '-'))?EXP_DIRECT:EXP_INDIRECT;
+ if (i->direct == EXP_DIRECT) {
+ stringp = &i->value;
+ } else {
+ stringp = &i->variable;
+ }
+
+ i->duration = duration;
+ if (duration == EXP_PERMANENT) {
+ *stringp = ckalloc(strlen(arg)+1);
+ strcpy(*stringp,arg);
+ } else {
+ *stringp = arg;
+ }
+
+ i->fd_list = 0;
+ exp_i_update(interp,i);
+
+ /* if indirect, ask Tcl to tell us when variable is modified */
+
+ if (i->direct == EXP_INDIRECT) {
+ Tcl_TraceVar(interp, i->variable,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES,
+ updateproc, (ClientData) i);
+ }
+
+ return i;
+}
+
+void
+exp_i_add_fd(i,fd)
+struct exp_i *i;
+int fd;
+{
+ struct exp_fd_list *new_fd;
+
+ new_fd = exp_new_fd(fd);
+ new_fd->next = i->fd_list;
+ i->fd_list = new_fd;
+}
+
+/* this routine assumes i->fd is meaningful */
+void
+exp_i_parse_fds(i)
+struct exp_i *i;
+{
+ char *p = i->value;
+
+ /* reparse it */
+ while (1) {
+ int m;
+ int negative = 0;
+ int valid_spawn_id = 0;
+
+ m = 0;
+ while (isspace(*p)) p++;
+ for (;;p++) {
+ if (*p == '-') negative = 1;
+ else if (isdigit(*p)) {
+ m = m*10 + (*p-'0');
+ valid_spawn_id = 1;
+ } else if (*p == '\0' || isspace(*p)) break;
+ }
+
+ /* we either have a spawn_id or whitespace at end of string */
+
+ /* skip whitespace end-of-string */
+ if (!valid_spawn_id) break;
+
+ if (negative) m = -m;
+
+ exp_i_add_fd(i,m);
+ }
+}
+
+/* updates a single exp_i struct */
+void
+exp_i_update(interp,i)
+Tcl_Interp *interp;
+struct exp_i *i;
+{
+ char *p; /* string representation of list of spawn ids */
+
+ if (i->direct == EXP_INDIRECT) {
+ p = Tcl_GetVar(interp,i->variable,TCL_GLOBAL_ONLY);
+ if (!p) {
+ p = "";
+ exp_debuglog("warning: indirect variable %s undefined",i->variable);
+ }
+
+ if (i->value) {
+ if (streq(p,i->value)) return;
+
+ /* replace new value with old */
+ ckfree(i->value);
+ }
+ i->value = ckalloc(strlen(p)+1);
+ strcpy(i->value,p);
+
+ exp_free_fd(i->fd_list);
+ i->fd_list = 0;
+ } else {
+ /* no free, because this should only be called on */
+ /* "direct" i's once */
+ i->fd_list = 0;
+ }
+ exp_i_parse_fds(i);
+}
+
+struct exp_i *
+exp_new_i_simple(fd,duration)
+int fd;
+int duration; /* if we have to copy the args */
+ /* should only need do this in expect_before/after */
+{
+ struct exp_i *i;
+
+ i = exp_new_i();
+
+ i->direct = EXP_DIRECT;
+ i->duration = duration;
+
+ exp_i_add_fd(i,fd);
+
+ return i;
+}
+
+/*ARGSUSED*/
+static int
+Exp_SendLogCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ char *string;
+ int len;
+
+ argv++;
+ argc--;
+
+ if (argc) {
+ if (streq(*argv,"--")) {
+ argc--; argv++;
+ }
+ }
+
+ if (argc != 1) {
+ exp_error(interp,"usage: send [args] string");
+ return TCL_ERROR;
+ }
+
+ string = *argv;
+
+ len = strlen(string);
+
+ if (debugfile) fwrite(string,1,len,debugfile);
+ if (logfile) fwrite(string,1,len,logfile);
+
+ return(TCL_OK);
+}
+
+
+/* I've rewritten this to be unbuffered. I did this so you could shove */
+/* large files through "send". If you are concerned about efficiency */
+/* you should quote all your send args to make them one single argument. */
+/*ARGSUSED*/
+static int
+Exp_SendCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int m = -1; /* spawn id (master) */
+ int rc; /* final result of this procedure */
+ struct human_arg human_args;
+ struct slow_arg slow_args;
+#define SEND_STYLE_STRING_MASK 0x07 /* mask to detect a real string arg */
+#define SEND_STYLE_PLAIN 0x01
+#define SEND_STYLE_HUMAN 0x02
+#define SEND_STYLE_SLOW 0x04
+#define SEND_STYLE_ZERO 0x10
+#define SEND_STYLE_BREAK 0x20
+ int send_style = SEND_STYLE_PLAIN;
+ int want_cooked = TRUE;
+ char *string; /* string to send */
+ int len; /* length of string to send */
+ int zeros; /* count of how many ascii zeros to send */
+
+ char *i_masters = 0;
+ struct exp_fd_list *fd;
+ struct exp_i *i;
+ char *arg;
+
+ argv++;
+ argc--;
+ while (argc) {
+ arg = *argv;
+ if (arg[0] != '-') break;
+ arg++;
+ if (exp_flageq1('-',arg)) { /* "--" */
+ argc--; argv++;
+ break;
+ } else if (exp_flageq1('i',arg)) { /* "-i" */
+ argc--; argv++;
+ if (argc==0) {
+ exp_error(interp,"usage: -i spawn_id");
+ return(TCL_ERROR);
+ }
+ i_masters = *argv;
+ argc--; argv++;
+ continue;
+ } else if (exp_flageq1('h',arg)) { /* "-h" */
+ argc--; argv++;
+ if (-1 == get_human_args(interp,&human_args))
+ return(TCL_ERROR);
+ send_style = SEND_STYLE_HUMAN;
+ continue;
+ } else if (exp_flageq1('s',arg)) { /* "-s" */
+ argc--; argv++;
+ if (-1 == get_slow_args(interp,&slow_args))
+ return(TCL_ERROR);
+ send_style = SEND_STYLE_SLOW;
+ continue;
+ } else if (exp_flageq("null",arg,1) || exp_flageq1('0',arg)) {
+ argc--; argv++; /* "-null" */
+ if (!*argv) zeros = 1;
+ else {
+ zeros = atoi(*argv);
+ argc--; argv++;
+ if (zeros < 1) return TCL_OK;
+ }
+ send_style = SEND_STYLE_ZERO;
+ string = "<zero(s)>";
+ continue;
+ } else if (exp_flageq("raw",arg,1)) { /* "-raw" */
+ argc--; argv++;
+ want_cooked = FALSE;
+ continue;
+ } else if (exp_flageq("break",arg,1)) { /* "-break" */
+ argc--; argv++;
+ send_style = SEND_STYLE_BREAK;
+ string = "<break>";
+ continue;
+ } else {
+ exp_error(interp,"usage: unrecognized flag <-%.80s>",arg);
+ return TCL_ERROR;
+ }
+ }
+
+ if (send_style & SEND_STYLE_STRING_MASK) {
+ if (argc != 1) {
+ exp_error(interp,"usage: send [args] string");
+ return TCL_ERROR;
+ }
+ string = *argv;
+ }
+ len = strlen(string);
+
+ if (clientData == &sendCD_user) m = 1;
+ else if (clientData == &sendCD_error) m = 2;
+ else if (clientData == &sendCD_tty) m = exp_dev_tty;
+ else if (!i_masters) {
+ /* we really do want to check if it is open */
+ /* but since stdin could be closed, we have to first */
+ /* get the fd and then convert it from 0 to 1 if necessary */
+ if (0 == exp_update_master(interp,&m,0,0))
+ return(TCL_ERROR);
+ }
+
+ /* if master != -1, then it holds desired master */
+ /* else i_masters does */
+
+ if (m != -1) {
+ i = exp_new_i_simple(m,EXP_TEMPORARY);
+ } else {
+ i = exp_new_i_complex(interp,i_masters,FALSE,(Tcl_VarTraceProc *)0);
+ }
+
+#define send_to_stderr (clientData == &sendCD_error)
+#define send_to_proc (clientData == &sendCD_proc)
+#define send_to_user ((clientData == &sendCD_user) || \
+ (clientData == &sendCD_tty))
+
+ if (send_to_proc) {
+ want_cooked = FALSE;
+ debuglog("send: sending \"%s\" to {",dprintify(string));
+ /* if closing brace doesn't appear, that's because an error */
+ /* was encountered before we could send it */
+ } else {
+ if (debugfile)
+ fwrite(string,1,len,debugfile);
+ if ((send_to_user && logfile_all) || logfile)
+ fwrite(string,1,len,logfile);
+ }
+
+ for (fd=i->fd_list;fd;fd=fd->next) {
+ m = fd->fd;
+
+ if (send_to_proc) {
+ debuglog(" %d ",m);
+ }
+
+ /* true if called as Send with user_spawn_id */
+ if (exp_is_stdinfd(m)) m = 1;
+
+ /* check validity of each - i.e., are they open */
+ if (0 == exp_fd2f(interp,m,1,0,"send")) {
+ rc = TCL_ERROR;
+ goto finish;
+ }
+ /* Check if Tcl is using a different fd for output */
+ if (exp_fs[m].tcl_handle) {
+ m = exp_fs[m].tcl_output;
+ }
+
+ if (want_cooked) string = exp_cook(string,&len);
+
+ switch (send_style) {
+ case SEND_STYLE_PLAIN:
+ rc = exact_write(m,string,len);
+ break;
+ case SEND_STYLE_SLOW:
+ rc = slow_write(interp,m,string,len,&slow_args);
+ break;
+ case SEND_STYLE_HUMAN:
+ rc = human_write(interp,m,string,&human_args);
+ break;
+ case SEND_STYLE_ZERO:
+ for (;zeros>0;zeros--) rc = write(m,"",1);
+ /* catching error on last write is sufficient */
+ rc = ((rc==1) ? 0 : -1); /* normal is 1 not 0 */
+ break;
+ case SEND_STYLE_BREAK:
+ exp_tty_break(interp,m);
+ rc = 0;
+ break;
+ }
+
+ if (rc != 0) {
+ if (rc == -1) {
+ exp_error(interp,"write(spawn_id=%d): %s",m,Tcl_PosixError(interp));
+ rc = TCL_ERROR;
+ }
+ goto finish;
+ }
+ }
+ if (send_to_proc) debuglog("}\r\n");
+
+ rc = TCL_OK;
+ finish:
+ exp_free_i(interp,i,(Tcl_VarTraceProc *)0);
+ return rc;
+}
+
+/*ARGSUSED*/
+static int
+Exp_LogFileCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ static Tcl_DString dstring;
+ static int first_time = TRUE;
+ static int current_append; /* true if currently appending */
+ static char *openarg = 0; /* Tcl file identifier from -open */
+ static int leaveopen = FALSE; /* true if -leaveopen was used */
+
+ int old_logfile_all = logfile_all;
+ FILE *old_logfile = logfile;
+ char *old_openarg = openarg;
+ int old_leaveopen = leaveopen;
+
+ int aflag = FALSE;
+ int append = TRUE;
+ char *filename = 0;
+ char *type;
+ FILE *writefilePtr;
+ int usage_error_occurred = FALSE;
+
+ openarg = 0;
+ leaveopen = FALSE;
+
+ if (first_time) {
+ Tcl_DStringInit(&dstring);
+ first_time = FALSE;
+ }
+
+
+#define usage_error if (0) ; else {\
+ usage_error_occurred = TRUE;\
+ goto error;\
+ }
+
+ /* when this function returns, we guarantee that if logfile_all */
+ /* is TRUE, then logfile is non-zero */
+
+ argv++;
+ argc--;
+ for (;argc>0;argc--,argv++) {
+ if (streq(*argv,"-open")) {
+ if (!argv[1]) usage_error;
+ openarg = ckalloc(strlen(argv[1])+1);
+ strcpy(openarg,argv[1]);
+ argc--; argv++;
+ } else if (streq(*argv,"-leaveopen")) {
+ if (!argv[1]) usage_error;
+ openarg = ckalloc(strlen(argv[1])+1);
+ strcpy(openarg,argv[1]);
+ leaveopen = TRUE;
+ argc--; argv++;
+ } else if (streq(*argv,"-a")) {
+ aflag = TRUE;
+ } else if (streq(*argv,"-info")) {
+ if (logfile) {
+ if (logfile_all) strcat(interp->result,"-a ");
+ if (!current_append) strcat(interp->result,"-noappend ");
+ strcat(interp->result,Tcl_DStringValue(&dstring));
+ }
+ return TCL_OK;
+ } else if (streq(*argv,"-noappend")) {
+ append = FALSE;
+ } else break;
+ }
+
+ if (argc == 1) {
+ filename = argv[0];
+ } else if (argc > 1) {
+ /* too many arguments */
+ usage_error
+ }
+
+ if (openarg && filename) {
+ usage_error
+ }
+ if (aflag && !(openarg || filename)) {
+ usage_error
+ }
+
+ logfile = 0;
+ logfile_all = aflag;
+
+ current_append = append;
+
+ type = (append?"a":"w");
+
+ if (filename) {
+ filename = Tcl_TildeSubst(interp,filename,&dstring);
+ if (filename == NULL) {
+ goto error;
+ } else {
+ /* Tcl_TildeSubst doesn't store into dstring */
+ /* if no ~, so force string into dstring */
+ /* this is only needed so that next time around */
+ /* we can get dstring for -info if necessary */
+ if (Tcl_DStringValue(&dstring)[0] == '\0') {
+ Tcl_DStringAppend(&dstring,filename,-1);
+ }
+ }
+
+ errno = 0;
+ if (NULL == (logfile = fopen(filename,type))) {
+ char *msg;
+
+ if (errno == 0) {
+ msg = open_failed;
+ } else {
+ msg = Tcl_PosixError(interp);
+ }
+ exp_error(interp,"%s: %s",filename,msg);
+ Tcl_DStringFree(&dstring);
+ goto error;
+ }
+ } else if (openarg) {
+ int cc;
+ int fd;
+ Tcl_Channel chan;
+ int mode;
+#if TCL_MAJOR_VERSION < 8
+ Tcl_File tclWriteFile;
+#endif /* TCL_MAJOR_VERSION < 8 */
+
+ Tcl_DStringTrunc(&dstring,0);
+
+#ifdef __CYGWIN32__
+ /* This doesn't work on cygwin32, because
+ Tcl_GetChannelHandle is likely to return a Windows
+ handle, and passing that to dup will fail. */
+ exp_error(interp,"log_file -open and -leaveopen not supported on
+ cygwin32");
+ return TCL_ERROR;
+#endif
+
+#if TCL7_4
+ cc = Tcl_GetOpenFile(interp,openarg,1,1,&writefilePtr);
+ if (cc == TCL_ERROR) goto error;
+
+ if (-1 == (fd = dup(fileno(writefilePtr)))) {
+ exp_error(interp,"dup: %s",Tcl_PosixError(interp));
+ goto error;
+ }
+#endif
+ if (!(chan = Tcl_GetChannel(interp,openarg,&mode))) {
+ return TCL_ERROR;
+ }
+ if (!(mode & TCL_WRITABLE)) {
+ exp_error(interp,"channel is not writable");
+ }
+#if TCL_MAJOR_VERSION < 8
+ tclWriteFile = Tcl_GetChannelFile(chan, TCL_WRITABLE);
+ fd = dup((int)Tcl_GetFileInfo(tclWriteFile, (int *)0));
+#else
+ if (TCL_ERROR == Tcl_GetChannelHandle(chan, TCL_WRITABLE, (ClientData) &fd)) {
+ goto error;
+ }
+ fd = dup(fd);
+#endif /* TCL_MAJOR_VERSION < 8 */
+ if (!(logfile = fdopen(fd,type))) {
+ exp_error(interp,"fdopen: %s",Tcl_PosixError(interp));
+ close(fd);
+ goto error;
+ }
+
+ if (leaveopen) {
+ Tcl_DStringAppend(&dstring,"-leaveopen ",-1);
+ } else {
+ Tcl_DStringAppend(&dstring,"-open ",-1);
+ }
+
+ Tcl_DStringAppend(&dstring,openarg,-1);
+
+ /*
+ * It would be convenient now to tell Tcl to close its
+ * file descriptor. Alas, if involved in a pipeline, Tcl
+ * will be unable to complete a wait on the process.
+ * So simply remember that we meant to close it. We will
+ * do so later in our own close routine.
+ */
+ }
+ if (logfile) {
+ setbuf(logfile,(char *)0);
+ exp_close_on_exec(fileno(logfile));
+ }
+
+ if (old_logfile) {
+ fclose(old_logfile);
+ }
+
+ if (old_openarg) {
+ if (!old_leaveopen) {
+ close_tcl_file(interp,old_openarg);
+ }
+ ckfree((char *)old_openarg);
+ }
+
+ return TCL_OK;
+
+ error:
+ if (old_logfile) {
+ logfile = old_logfile;
+ logfile_all = old_logfile_all;
+ }
+
+ if (openarg) ckfree(openarg);
+ openarg = old_openarg;
+ leaveopen = old_leaveopen;
+
+ if (usage_error_occurred) {
+ exp_error(interp,"usage: log_file [-info] [-noappend] [[-a] file] [-[leave]open [open ...]]");
+ }
+
+ return TCL_ERROR;
+}
+
+/*ARGSUSED*/
+static int
+Exp_LogUserCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int old_loguser = loguser;
+
+ if (argc == 0 || (argc == 2 && streq(argv[1],"-info"))) {
+ /* do nothing */
+ } else if (argc == 2) {
+ if (0 == atoi(argv[1])) loguser = FALSE;
+ else loguser = TRUE;
+ } else {
+ exp_error(interp,"usage: [-info|1|0]");
+ }
+
+ sprintf(interp->result,"%d",old_loguser);
+
+ return(TCL_OK);
+}
+
+#ifdef TCL_DEBUGGER
+/*ARGSUSED*/
+static int
+Exp_DebugCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int now = FALSE; /* soon if FALSE, now if TRUE */
+ int exp_tcl_debugger_was_available = exp_tcl_debugger_available;
+
+ if (argc > 3) goto usage;
+
+ if (argc == 1) {
+ sprintf(interp->result,"%d",exp_tcl_debugger_available);
+ return TCL_OK;
+ }
+
+ argv++;
+
+ while (*argv) {
+ if (streq(*argv,"-now")) {
+ now = TRUE;
+ argv++;
+ }
+ else break;
+ }
+
+ if (!*argv) {
+ if (now) {
+ Dbg_On(interp,1);
+ exp_tcl_debugger_available = 1;
+ } else {
+ goto usage;
+ }
+ } else if (streq(*argv,"0")) {
+ Dbg_Off(interp);
+ exp_tcl_debugger_available = 0;
+ } else {
+ Dbg_On(interp,now);
+ exp_tcl_debugger_available = 1;
+ }
+ sprintf(interp->result,"%d",exp_tcl_debugger_was_available);
+ return(TCL_OK);
+ usage:
+ exp_error(interp,"usage: [[-now] 1|0]");
+ return TCL_ERROR;
+}
+#endif
+
+/*ARGSUSED*/
+static int
+Exp_ExpInternalCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ static Tcl_DString dstring;
+ static int first_time = TRUE;
+ int fopened = FALSE;
+
+ if (first_time) {
+ Tcl_DStringInit(&dstring);
+ first_time = FALSE;
+ }
+
+ if (argc > 1 && streq(argv[1],"-info")) {
+ if (debugfile) {
+ sprintf(interp->result,"-f %s ",
+ Tcl_DStringValue(&dstring));
+ }
+ strcat(interp->result,((exp_is_debugging==0)?"0":"1"));
+ return TCL_OK;
+ }
+
+ argv++;
+ argc--;
+ while (argc) {
+ if (!streq(*argv,"-f")) break;
+ argc--;argv++;
+ if (argc < 1) goto usage;
+ if (debugfile) fclose(debugfile);
+ argv[0] = Tcl_TildeSubst(interp, argv[0],&dstring);
+ if (argv[0] == NULL) goto error;
+ else {
+ /* Tcl_TildeSubst doesn't store into dstring */
+ /* if no ~, so force string into dstring */
+ /* this is only needed so that next time around */
+ /* we can get dstring for -info if necessary */
+ if (Tcl_DStringValue(&dstring)[0] == '\0') {
+ Tcl_DStringAppend(&dstring,argv[0],-1);
+ }
+ }
+
+ errno = 0;
+ if (NULL == (debugfile = fopen(*argv,"a"))) {
+ char *msg;
+
+ if (errno == 0) {
+ msg = open_failed;
+ } else {
+ msg = Tcl_PosixError(interp);
+ }
+
+ exp_error(interp,"%s: %s",*argv,msg);
+ goto error;
+ }
+ setbuf(debugfile,(char *)0);
+ exp_close_on_exec(fileno(debugfile));
+ fopened = TRUE;
+ argc--;argv++;
+ }
+
+ if (argc != 1) goto usage;
+
+ /* if no -f given, close file */
+ if (fopened == FALSE && debugfile) {
+ fclose(debugfile);
+ debugfile = 0;
+ Tcl_DStringFree(&dstring);
+ }
+
+ exp_is_debugging = atoi(*argv);
+ return(TCL_OK);
+ usage:
+ exp_error(interp,"usage: [-f file] expr");
+ error:
+ Tcl_DStringFree(&dstring);
+ return TCL_ERROR;
+}
+
+char *exp_onexit_action = 0;
+
+/*ARGSUSED*/
+static int
+Exp_ExitCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int value = 0;
+
+ argv++;
+
+ if (*argv) {
+ if (exp_flageq(*argv,"-onexit",3)) {
+ argv++;
+ if (*argv) {
+ int len = strlen(*argv);
+ if (exp_onexit_action)
+ ckfree(exp_onexit_action);
+ exp_onexit_action = ckalloc(len + 1);
+ strcpy(exp_onexit_action,*argv);
+ } else if (exp_onexit_action) {
+ Tcl_AppendResult(interp,exp_onexit_action,(char *)0);
+ }
+ return TCL_OK;
+ } else if (exp_flageq(*argv,"-noexit",3)) {
+ argv++;
+ exp_exit_handlers((ClientData)interp);
+ return TCL_OK;
+ }
+ }
+
+ if (*argv) {
+ if (Tcl_GetInt(interp, *argv, &value) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
+
+ exp_exit(interp,value);
+ /*NOTREACHED*/
+}
+
+/* so cmd table later is more intuitive */
+#define Exp_CloseObjCmd Exp_CloseCmd
+
+/*ARGSUSED*/
+static int
+Exp_CloseCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+#if TCL_MAJOR_VERSION < 8
+char **argv;
+#else
+Tcl_Obj *CONST argv[]; /* Argument objects. */
+#endif
+{
+ int onexec_flag = FALSE; /* true if -onexec seen */
+ int close_onexec;
+ int slave_flag = FALSE;
+ int m = -1;
+
+ int argc_orig = argc;
+#if TCL_MAJOR_VERSION < 8
+ char **argv_orig = argv;
+#else
+ Tcl_Obj *CONST *argv_orig = argv;
+#endif
+
+ argc--; argv++;
+
+#if TCL_MAJOR_VERSION < 8
+#define STARARGV *argv
+#else
+#define STARARGV Tcl_GetStringFromObj(*argv,(int *)0)
+#endif
+
+ for (;argc>0;argc--,argv++) {
+ if (streq("-i",STARARGV)) {
+ argc--; argv++;
+ if (argc == 0) {
+ exp_error(interp,"usage: -i spawn_id");
+ return(TCL_ERROR);
+ }
+ m = atoi(STARARGV);
+ } else if (streq(STARARGV,"-slave")) {
+ slave_flag = TRUE;
+ } else if (streq(STARARGV,"-onexec")) {
+ argc--; argv++;
+ if (argc == 0) {
+ exp_error(interp,"usage: -onexec 0|1");
+ return(TCL_ERROR);
+ }
+ onexec_flag = TRUE;
+ close_onexec = atoi(STARARGV);
+ } else break;
+ }
+
+ if (argc) {
+ /* doesn't look like our format, it must be a Tcl-style file */
+ /* handle. Lucky that formats are easily distinguishable. */
+ /* Historical note: we used "close" long before there was a */
+ /* Tcl builtin by the same name. */
+
+ Tcl_CmdInfo info;
+ Tcl_ResetResult(interp);
+ if (0 == Tcl_GetCommandInfo(interp,"close",&info)) {
+ info.clientData = 0;
+ }
+#if TCL_MAJOR_VERSION < 8
+ return(Tcl_CloseCmd(info.clientData,interp,argc_orig,argv_orig));
+#else
+ return(Tcl_CloseObjCmd(info.clientData,interp,argc_orig,argv_orig));
+#endif
+ }
+
+ if (m == -1) {
+ if (exp_update_master(interp,&m,1,0) == 0) return(TCL_ERROR);
+ }
+
+ if (slave_flag) {
+ struct exp_f *f = exp_fd2f(interp,m,1,0,"-slave");
+ if (!f) return TCL_ERROR;
+
+ if (f->slave_fd) {
+ close(f->slave_fd);
+ f->slave_fd = EXP_NOFD;
+
+ exp_slave_control(m,1);
+
+ return TCL_OK;
+ } else {
+ exp_error(interp,"no such slave");
+ return TCL_ERROR;
+ }
+ }
+
+ if (onexec_flag) {
+ /* heck, don't even bother to check if fd is open or a real */
+ /* spawn id, nothing else depends on it */
+ fcntl(m,F_SETFD,close_onexec);
+ return TCL_OK;
+ }
+
+ return(exp_close(interp,m));
+}
+
+/*ARGSUSED*/
+static void
+tcl_tracer(clientData,interp,level,command,cmdProc,cmdClientData,argc,argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int level;
+char *command;
+int (*cmdProc)();
+ClientData cmdClientData;
+int argc;
+char *argv[];
+{
+ int i;
+
+ /* come out on stderr, by using errorlog */
+ errorlog("%2d",level);
+ for (i = 0;i<level;i++) exp_nferrorlog(" ",0/*ignored - satisfy lint*/);
+ errorlog("%s\r\n",command);
+}
+
+/*ARGSUSED*/
+static int
+Exp_StraceCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ static int trace_level = 0;
+ static Tcl_Trace trace_handle;
+
+ if (argc > 1 && streq(argv[1],"-info")) {
+ sprintf(interp->result,"%d",trace_level);
+ return TCL_OK;
+ }
+
+ if (argc != 2) {
+ exp_error(interp,"usage: trace level");
+ return(TCL_ERROR);
+ }
+ /* tracing already in effect, undo it */
+ if (trace_level > 0) Tcl_DeleteTrace(interp,trace_handle);
+
+ /* get and save new trace level */
+ trace_level = atoi(argv[1]);
+ if (trace_level > 0)
+ trace_handle = Tcl_CreateTrace(interp,
+ trace_level,tcl_tracer,(ClientData)0);
+ return(TCL_OK);
+}
+
+/* following defn's are stolen from tclUnix.h */
+
+/*
+ * The type of the status returned by wait varies from UNIX system
+ * to UNIX system. The macro below defines it:
+ */
+
+#if 0
+#ifndef NO_UNION_WAIT
+# define WAIT_STATUS_TYPE union wait
+#else
+# define WAIT_STATUS_TYPE int
+#endif
+#endif /* 0 */
+
+/*
+ * following definitions stolen from tclUnix.h
+ * (should have been made public!)
+
+ * Supply definitions for macros to query wait status, if not already
+ * defined in header files above.
+ */
+
+#if 0
+#ifndef WIFEXITED
+# define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0)
+#endif
+
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
+#endif
+
+#ifndef WIFSIGNALED
+# define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff)))
+#endif
+
+#ifndef WTERMSIG
+# define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f)
+#endif
+
+#ifndef WIFSTOPPED
+# define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177)
+#endif
+
+#ifndef WSTOPSIG
+# define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff)
+#endif
+#endif /* 0 */
+
+/* end of stolen definitions */
+
+/* Describe the processes created with Expect's fork.
+This allows us to wait on them later.
+
+This is maintained as a linked list. As additional procs are forked,
+new links are added. As procs disappear, links are marked so that we
+can reuse them later.
+*/
+
+struct forked_proc {
+ int pid;
+ WAIT_STATUS_TYPE wait_status;
+ enum {not_in_use, wait_done, wait_not_done} link_status;
+ struct forked_proc *next;
+} *forked_proc_base = 0;
+
+void
+fork_clear_all()
+{
+ struct forked_proc *f;
+
+ for (f=forked_proc_base;f;f=f->next) {
+ f->link_status = not_in_use;
+ }
+}
+
+void
+fork_init(f,pid)
+struct forked_proc *f;
+int pid;
+{
+ f->pid = pid;
+ f->link_status = wait_not_done;
+}
+
+/* make an entry for a new proc */
+void
+fork_add(pid)
+int pid;
+{
+ struct forked_proc *f;
+
+ for (f=forked_proc_base;f;f=f->next) {
+ if (f->link_status == not_in_use) break;
+ }
+
+ /* add new entry to the front of the list */
+ if (!f) {
+ f = (struct forked_proc *)ckalloc(sizeof(struct forked_proc));
+ f->next = forked_proc_base;
+ forked_proc_base = f;
+ }
+ fork_init(f,pid);
+}
+
+/* Provide a last-chance guess for this if not defined already */
+#ifndef WNOHANG
+#define WNOHANG WNOHANG_BACKUP_VALUE
+#endif
+
+/* wait returns are a hodgepodge of things
+ If wait fails, something seriously has gone wrong, for example:
+ bogus arguments (i.e., incorrect, bogus spawn id)
+ no children to wait on
+ async event failed
+ If wait succeeeds, something happened on a particular pid
+ 3rd arg is 0 if successfully reaped (if signal, additional fields supplied)
+ 3rd arg is -1 if unsuccessfully reaped (additional fields supplied)
+*/
+/*ARGSUSED*/
+static int
+Exp_WaitCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int master_supplied = FALSE;
+ int m; /* master waited for */
+ struct exp_f *f; /* ditto */
+ struct forked_proc *fp = 0; /* handle to a pure forked proc */
+
+ struct exp_f ftmp; /* temporary memory for either f or fp */
+
+ int nowait = FALSE;
+ int result = 0; /* 0 means child was successfully waited on */
+ /* -1 means an error occurred */
+ /* -2 means no eligible children to wait on */
+#define NO_CHILD -2
+
+ argv++;
+ argc--;
+ for (;argc>0;argc--,argv++) {
+ if (streq(*argv,"-i")) {
+ argc--; argv++;
+ if (argc==0) {
+ exp_error(interp,"usage: -i spawn_id");
+ return(TCL_ERROR);
+ }
+ master_supplied = TRUE;
+ m = atoi(*argv);
+ } else if (streq(*argv,"-nowait")) {
+ nowait = TRUE;
+ }
+ }
+
+ if (!master_supplied) {
+ if (0 == exp_update_master(interp,&m,0,0))
+ return TCL_ERROR;
+ }
+
+ if (m != EXP_SPAWN_ID_ANY) {
+ if (0 == exp_fd2f(interp,m,0,0,"wait")) {
+ return TCL_ERROR;
+ }
+
+ f = exp_fs + m;
+
+ /* check if waited on already */
+ /* things opened by "open" or set with -nowait */
+ /* are marked sys_waited already */
+ if (!f->sys_waited) {
+ if (nowait) {
+ /* should probably generate an error */
+ /* if SIGCHLD is trapped. */
+
+ /* pass to Tcl, so it can do wait */
+ /* in background */
+#if TCL_MAJOR_VERSION < 8
+ Tcl_DetachPids(1,&f->pid);
+#else
+ Tcl_DetachPids(1,(Tcl_Pid *)&f->pid);
+#endif
+ exp_wait_zero(&f->wait);
+ } else {
+ while (1) {
+ if (Tcl_AsyncReady()) {
+ int rc = Tcl_AsyncInvoke(interp,TCL_OK);
+ if (rc != TCL_OK) return(rc);
+ }
+
+ result = waitpid(f->pid,&f->wait,0);
+ if (result == f->pid) break;
+ if (result == -1) {
+ if (errno == EINTR) continue;
+ else break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Now have Tcl reap anything we just detached.
+ * This also allows procs user has created with "exec &"
+ * and and associated with an "exec &" process to be reaped.
+ */
+
+ Tcl_ReapDetachedProcs();
+ exp_rearm_sigchld(interp); /* new */
+ } else {
+ /* wait for any of our own spawned processes */
+ /* we call waitpid rather than wait to avoid running into */
+ /* someone else's processes. Yes, according to Ousterhout */
+ /* this is the best way to do it. */
+
+ for (m=0;m<=exp_fd_max;m++) {
+ f = exp_fs + m;
+ if (!f->valid) continue;
+ if (f->pid == exp_getpid) continue; /* skip ourself */
+ if (f->user_waited) continue; /* one wait only! */
+ if (f->sys_waited) break;
+ restart:
+ result = waitpid(f->pid,&f->wait,WNOHANG);
+ if (result == f->pid) break;
+ if (result == 0) continue; /* busy, try next */
+ if (result == -1) {
+ if (errno == EINTR) goto restart;
+ else break;
+ }
+ }
+
+ /* if it's not a spawned process, maybe its a forked process */
+ for (fp=forked_proc_base;fp;fp=fp->next) {
+ if (fp->link_status == not_in_use) continue;
+ restart2:
+ result = waitpid(fp->pid,&fp->wait_status,WNOHANG);
+ if (result == fp->pid) {
+ m = -1; /* DOCUMENT THIS! */
+ break;
+ }
+ if (result == 0) continue; /* busy, try next */
+ if (result == -1) {
+ if (errno == EINTR) goto restart2;
+ else break;
+ }
+ }
+
+ if (m > exp_fd_max) {
+ result = NO_CHILD; /* no children */
+ Tcl_ReapDetachedProcs();
+ }
+ exp_rearm_sigchld(interp);
+ }
+
+ /* sigh, wedge forked_proc into an exp_f structure so we don't
+ * have to rewrite remaining code (too much)
+ */
+ if (fp) {
+ f = &ftmp;
+ f->pid = fp->pid;
+ f->wait = fp->wait_status;
+ }
+
+ /* non-portable assumption that pid_t can be printed with %d */
+
+ if (result == -1) {
+ sprintf(interp->result,"%d %d -1 %d POSIX %s %s",
+ f->pid,m,errno,Tcl_ErrnoId(),Tcl_ErrnoMsg(errno));
+ result = TCL_OK;
+ } else if (result == NO_CHILD) {
+ interp->result = "no children";
+ return TCL_ERROR;
+ } else {
+ sprintf(interp->result,"%d %d 0 %d",
+ f->pid,m,WEXITSTATUS(f->wait));
+ if (WIFSIGNALED(f->wait)) {
+ Tcl_AppendElement(interp,"CHILDKILLED");
+ Tcl_AppendElement(interp,Tcl_SignalId((int)(WTERMSIG(f->wait))));
+ Tcl_AppendElement(interp,Tcl_SignalMsg((int) (WTERMSIG(f->wait))));
+ } else if (WIFSTOPPED(f->wait)) {
+ Tcl_AppendElement(interp,"CHILDSUSP");
+ Tcl_AppendElement(interp,Tcl_SignalId((int) (WSTOPSIG(f->wait))));
+ Tcl_AppendElement(interp,Tcl_SignalMsg((int) (WSTOPSIG(f->wait))));
+ }
+ }
+
+ if (fp) {
+ fp->link_status = not_in_use;
+ return ((result == -1)?TCL_ERROR:TCL_OK);
+ }
+
+ f->sys_waited = TRUE;
+ f->user_waited = TRUE;
+
+ /* if user has already called close, make sure fd really is closed */
+ /* and forget about this entry entirely */
+ if (f->user_closed) {
+ if (!f->sys_closed) {
+ sys_close(m,f);
+ }
+ f->valid = FALSE;
+ }
+ return ((result == -1)?TCL_ERROR:TCL_OK);
+}
+
+/*ARGSUSED*/
+static int
+Exp_ForkCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int rc;
+ if (argc > 1) {
+ exp_error(interp,"usage: fork");
+ return(TCL_ERROR);
+ }
+
+ rc = fork();
+ if (rc == -1) {
+ exp_error(interp,"fork: %s",Tcl_PosixError(interp));
+ return TCL_ERROR;
+ } else if (rc == 0) {
+ /* child */
+ exp_forked = TRUE;
+ exp_getpid = getpid();
+ fork_clear_all();
+ } else {
+ /* parent */
+ fork_add(rc);
+ }
+
+ /* both child and parent follow remainder of code */
+ sprintf(interp->result,"%d",rc);
+ debuglog("fork: returns {%s}\r\n",interp->result);
+ return(TCL_OK);
+}
+
+/*ARGSUSED*/
+static int
+Exp_DisconnectCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ /* tell Saber to ignore non-use of ttyfd */
+ /*SUPPRESS 591*/
+ int ttyfd;
+
+ if (argc > 1) {
+ exp_error(interp,"usage: disconnect");
+ return(TCL_ERROR);
+ }
+
+ if (exp_disconnected) {
+ exp_error(interp,"already disconnected");
+ return(TCL_ERROR);
+ }
+ if (!exp_forked) {
+ exp_error(interp,"can only disconnect child process");
+ return(TCL_ERROR);
+ }
+ exp_disconnected = TRUE;
+
+ /* ignore hangup signals generated by testing ptys in getptymaster */
+ /* and other places */
+ signal(SIGHUP,SIG_IGN);
+
+ /* reopen prevents confusion between send/expect_user */
+ /* accidentally mapping to a real spawned process after a disconnect */
+ if (exp_fs[0].pid != EXP_NOPID) {
+ exp_close(interp,0);
+ open("/dev/null",0);
+ fd_new(0, EXP_NOPID);
+ }
+ if (exp_fs[1].pid != EXP_NOPID) {
+ exp_close(interp,1);
+ open("/dev/null",1);
+ fd_new(1, EXP_NOPID);
+ }
+ if (exp_fs[2].pid != EXP_NOPID) {
+ /* reopen stderr saves error checking in error/log routines. */
+ exp_close(interp,2);
+ open("/dev/null",1);
+ fd_new(2, EXP_NOPID);
+ }
+
+ Tcl_UnsetVar(interp,"tty_spawn_id",TCL_GLOBAL_ONLY);
+
+#ifdef DO_SETSID
+ setsid();
+#else
+#ifdef SYSV3
+ /* put process in our own pgrp, and lose controlling terminal */
+#ifdef sysV88
+ /* With setpgrp first, child ends up with closed stdio */
+ /* according to Dave Schmitt <daves@techmpc.csg.gss.mot.com> */
+ if (fork()) exit(0);
+ setpgrp();
+#else
+ setpgrp();
+ /*signal(SIGHUP,SIG_IGN); moved out to above */
+ if (fork()) exit(0); /* first child exits (as per Stevens, */
+ /* UNIX Network Programming, p. 79-80) */
+ /* second child process continues as daemon */
+#endif
+#else /* !SYSV3 */
+#ifdef MIPS_BSD
+ /* required on BSD side of MIPS OS <jmsellen@watdragon.waterloo.edu> */
+# include <sysv/sys.s>
+ syscall(SYS_setpgrp);
+#endif
+ setpgrp(0,0);
+/* setpgrp(0,getpid());*/ /* put process in our own pgrp */
+
+/* Pyramid lacks this defn */
+#ifdef TIOCNOTTY
+ ttyfd = open("/dev/tty", O_RDWR);
+ if (ttyfd >= 0) {
+ /* zap controlling terminal if we had one */
+ (void) ioctl(ttyfd, TIOCNOTTY, (char *)0);
+ (void) close(ttyfd);
+ }
+#endif /* TIOCNOTTY */
+
+#endif /* SYSV3 */
+#endif /* DO_SETSID */
+ return(TCL_OK);
+}
+
+/*ARGSUSED*/
+static int
+Exp_OverlayCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int newfd, oldfd;
+ int dash_name = 0;
+ char *command;
+
+ argc--; argv++;
+ while (argc) {
+ if (*argv[0] != '-') break; /* not a flag */
+ if (streq(*argv,"-")) { /* - by itself */
+ argc--; argv++;
+ dash_name = 1;
+ continue;
+ }
+ newfd = atoi(argv[0]+1);
+ argc--; argv++;
+ if (argc == 0) {
+ exp_error(interp,"overlay -# requires additional argument");
+ return(TCL_ERROR);
+ }
+ oldfd = atoi(argv[0]);
+ argc--; argv++;
+ debuglog("overlay: mapping fd %d to %d\r\n",oldfd,newfd);
+ if (oldfd != newfd) (void) dup2(oldfd,newfd);
+ else debuglog("warning: overlay: old fd == new fd (%d)\r\n",oldfd);
+ }
+ if (argc == 0) {
+ exp_error(interp,"need program name");
+ return(TCL_ERROR);
+ }
+ command = argv[0];
+ if (dash_name) {
+ argv[0] = ckalloc(1+strlen(command));
+ sprintf(argv[0],"-%s",command);
+ }
+
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ (void) execvp(command,argv);
+ exp_error(interp,"execvp(%s): %s\r\n",argv[0],Tcl_PosixError(interp));
+ return(TCL_ERROR);
+}
+
+#if 0
+/*ARGSUSED*/
+int
+cmdReady(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ char num[4]; /* can hold up to "999 " */
+ char buf[1024]; /* can easily hold 256 spawn_ids! */
+ int i, j;
+ int *masters, *masters2;
+ int timeout = get_timeout();
+
+ if (argc < 2) {
+ exp_error(interp,"usage: ready spawn_id1 [spawn_id2 ...]");
+ return(TCL_ERROR);
+ }
+
+ masters = (int *)ckalloc((argc-1)*sizeof(int));
+ masters2 = (int *)ckalloc((argc-1)*sizeof(int));
+
+ for (i=1;i<argc;i++) {
+ j = atoi(argv[i]);
+ if (!exp_fd2f(interp,j,1,"ready")) {
+ ckfree(masters);
+ return(TCL_ERROR);
+ }
+ masters[i-1] = j;
+ }
+ j = i-1;
+ if (TCL_ERROR == ready(masters,i-1,masters2,&j,&timeout))
+ return(TCL_ERROR);
+
+ /* pack result back into out-array */
+ buf[0] = '\0';
+ for (i=0;i<j;i++) {
+ sprintf(num,"%d ",masters2[i]); /* note extra blank */
+ strcat(buf,num);
+ }
+ ckfree(masters); ckfree(masters2);
+ Tcl_Return(interp,buf,TCL_VOLATILE);
+ return(TCL_OK);
+}
+#endif
+
+/*ARGSUSED*/
+int
+Exp_InterpreterCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ if (argc != 1) {
+ exp_error(interp,"no arguments allowed");
+ return(TCL_ERROR);
+ }
+
+ return(exp_interpreter(interp));
+ /* errors and ok, are caught by exp_interpreter() and discarded */
+ /* to return TCL_OK, type "return" */
+}
+
+/* this command supercede's Tcl's builtin CONTINUE command */
+/*ARGSUSED*/
+int
+Exp_ExpContinueDeprecatedCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ if (argc == 1) return(TCL_CONTINUE);
+ else if (argc == 2) {
+ if (streq(argv[1],"-expect")) {
+ debuglog("continue -expect is deprecated, use exp_continue\r\n");
+ return(EXP_CONTINUE);
+ }
+ }
+ exp_error(interp,"usage: continue [-expect]\n");
+ return(TCL_ERROR);
+}
+
+/* this command supercede's Tcl's builtin CONTINUE command */
+/*ARGSUSED*/
+int
+Exp_ExpContinueCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ if (argc == 1) {
+ return EXP_CONTINUE;
+ } else if ((argc == 2) && (0 == strcmp(argv[1],"-continue_timer"))) {
+ return EXP_CONTINUE_TIMER;
+ }
+
+ exp_error(interp,"usage: exp_continue [-continue_timer]\n");
+ return(TCL_ERROR);
+}
+
+#if TCL_MAJOR_VERSION < 8
+/* most of this is directly from Tcl's definition for return */
+/*ARGSUSED*/
+int
+Exp_InterReturnCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ /* let Tcl's return command worry about args */
+ /* if successful (i.e., TCL_RETURN is returned) */
+ /* modify the result, so that we will handle it specially */
+
+ int result = Tcl_ReturnCmd(clientData,interp,argc,argv);
+ if (result == TCL_RETURN)
+ result = EXP_TCL_RETURN;
+ return result;
+}
+#else
+/* most of this is directly from Tcl's definition for return */
+/*ARGSUSED*/
+int
+Exp_InterReturnObjCmd(clientData, interp, objc, objv)
+ClientData clientData;
+Tcl_Interp *interp;
+int objc;
+Tcl_Obj *CONST objv[];
+{
+ /* let Tcl's return command worry about args */
+ /* if successful (i.e., TCL_RETURN is returned) */
+ /* modify the result, so that we will handle it specially */
+
+#if TCL_MAJOR_VERSION < 8
+ int result = Tcl_ReturnCmd(clientData,interp,objc,objv);
+#else
+ int result = Tcl_ReturnObjCmd(clientData,interp,objc,objv);
+#endif
+
+ if (result == TCL_RETURN)
+ result = EXP_TCL_RETURN;
+ return result;
+}
+#endif
+
+/*ARGSUSED*/
+int
+Exp_OpenCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ struct exp_f *f;
+ int m = -1;
+ int m2;
+ int leaveopen = FALSE;
+ Tcl_Channel chan;
+
+ argc--; argv++;
+
+ for (;argc>0;argc--,argv++) {
+ if (streq(*argv,"-i")) {
+ argc--; argv++;
+ if (!*argv) {
+ exp_error(interp,"usage: -i spawn_id");
+ return TCL_ERROR;
+ }
+ m = atoi(*argv);
+ } else if (streq(*argv,"-leaveopen")) {
+ leaveopen = TRUE;
+ argc--; argv++;
+ } else break;
+ }
+
+ if (m == -1) {
+ if (exp_update_master(interp,&m,0,0) == 0) return TCL_ERROR;
+ }
+
+ if (0 == (f = exp_fd2f(interp,m,1,0,"exp_open"))) return TCL_ERROR;
+
+ /* make a new copy of file descriptor */
+ if (-1 == (m2 = dup(m))) {
+ exp_error(interp,"fdopen: %s",Tcl_PosixError(interp));
+ return TCL_ERROR;
+ }
+
+ if (!leaveopen) {
+ /* remove from Expect's memory in anticipation of passing to Tcl */
+ if (f->pid != EXP_NOPID) {
+#if TCL_MAJOR_VERSION < 8
+ Tcl_DetachPids(1,&f->pid);
+#else
+ Tcl_DetachPids(1,(Tcl_Pid *)&f->pid);
+#endif
+ f->pid = EXP_NOPID;
+ f->sys_waited = f->user_waited = TRUE;
+ }
+ exp_close(interp,m);
+ }
+
+ chan = Tcl_MakeFileChannel(
+#if TCL_MAJOR_VERSION < 8
+ (ClientData)m2,
+#endif
+ (ClientData)m2,
+ TCL_READABLE|TCL_WRITABLE);
+ Tcl_RegisterChannel(interp, chan);
+ Tcl_AppendResult(interp, Tcl_GetChannelName(chan), (char *) NULL);
+ return TCL_OK;
+}
+
+/* return 1 if a string is substring of a flag */
+/* this version is the code used by the macro that everyone calls */
+int
+exp_flageq_code(flag,string,minlen)
+char *flag;
+char *string;
+int minlen; /* at least this many chars must match */
+{
+ for (;*flag;flag++,string++,minlen--) {
+ if (*string == '\0') break;
+ if (*string != *flag) return 0;
+ }
+ if (*string == '\0' && minlen <= 0) return 1;
+ return 0;
+}
+
+void
+exp_create_commands(interp,c)
+Tcl_Interp *interp;
+struct exp_cmd_data *c;
+{
+#if TCL_MAJOR_VERSION < 8
+ Interp *iPtr = (Interp *) interp;
+#else
+ Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
+ Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
+#endif
+ char cmdnamebuf[80];
+
+ for (;c->name;c++) {
+#if TCL_MAJOR_VERSION < 8
+ int create = FALSE;
+ /* if already defined, don't redefine */
+ if (c->flags & EXP_REDEFINE) create = TRUE;
+ else if (!Tcl_FindHashEntry(&iPtr->commandTable,c->name)) {
+ create = TRUE;
+ }
+ if (create) {
+ Tcl_CreateCommand(interp,c->name,c->proc,
+ c->data,exp_deleteProc);
+ }
+#else
+ /* if already defined, don't redefine */
+ if ((c->flags & EXP_REDEFINE) ||
+ !(Tcl_FindHashEntry(&globalNsPtr->cmdTable,c->name) ||
+ Tcl_FindHashEntry(&currNsPtr->cmdTable,c->name))) {
+ if (c->objproc)
+ Tcl_CreateObjCommand(interp,c->name,
+ c->objproc,c->data,exp_deleteObjProc);
+ else
+ Tcl_CreateCommand(interp,c->name,c->proc,
+ c->data,exp_deleteProc);
+ }
+#endif
+ if (!(c->name[0] == 'e' &&
+ c->name[1] == 'x' &&
+ c->name[2] == 'p')
+ && !(c->flags & EXP_NOPREFIX)) {
+ sprintf(cmdnamebuf,"exp_%s",c->name);
+#if TCL_MAJOR_VERSION < 8
+ Tcl_CreateCommand(interp,cmdnamebuf,c->proc,
+ c->data,exp_deleteProc);
+#else
+ if (c->objproc)
+ Tcl_CreateObjCommand(interp,cmdnamebuf,c->objproc,c->data,
+ exp_deleteObjProc);
+ else
+ Tcl_CreateCommand(interp,cmdnamebuf,c->proc,
+ c->data,exp_deleteProc);
+#endif
+ }
+ }
+}
+
+static struct exp_cmd_data cmd_data[] = {
+#if TCL_MAJOR_VERSION < 8
+{"close", Exp_CloseCmd, 0, EXP_REDEFINE},
+#else
+{"close", Exp_CloseObjCmd, 0, 0, EXP_REDEFINE},
+#endif
+#ifdef TCL_DEBUGGER
+{"debug", exp_proc(Exp_DebugCmd), 0, 0},
+#endif
+{"exp_internal",exp_proc(Exp_ExpInternalCmd), 0, 0},
+{"disconnect", exp_proc(Exp_DisconnectCmd), 0, 0},
+{"exit", exp_proc(Exp_ExitCmd), 0, EXP_REDEFINE},
+{"exp_continue",exp_proc(Exp_ExpContinueCmd),0, 0},
+{"fork", exp_proc(Exp_ForkCmd), 0, 0},
+{"exp_pid", exp_proc(Exp_ExpPidCmd), 0, 0},
+{"getpid", exp_proc(Exp_GetpidDeprecatedCmd),0, 0},
+{"interpreter", exp_proc(Exp_InterpreterCmd), 0, 0},
+{"log_file", exp_proc(Exp_LogFileCmd), 0, 0},
+{"log_user", exp_proc(Exp_LogUserCmd), 0, 0},
+{"exp_open", exp_proc(Exp_OpenCmd), 0, 0},
+{"overlay", exp_proc(Exp_OverlayCmd), 0, 0},
+#if TCL_MAJOR_VERSION < 8
+{"inter_return",Exp_InterReturnCmd, 0, 0},
+#else
+{"inter_return",Exp_InterReturnObjCmd, 0, 0, 0},
+#endif
+{"send", exp_proc(Exp_SendCmd), (ClientData)&sendCD_proc, 0},
+{"send_error", exp_proc(Exp_SendCmd), (ClientData)&sendCD_error, 0},
+{"send_log", exp_proc(Exp_SendLogCmd), 0, 0},
+{"send_tty", exp_proc(Exp_SendCmd), (ClientData)&sendCD_tty, 0},
+{"send_user", exp_proc(Exp_SendCmd), (ClientData)&sendCD_user, 0},
+{"sleep", exp_proc(Exp_SleepCmd), 0, 0},
+{"spawn", exp_proc(Exp_SpawnCmd), 0, 0},
+{"strace", exp_proc(Exp_StraceCmd), 0, 0},
+{"wait", exp_proc(Exp_WaitCmd), 0, 0},
+{0}};
+
+void
+exp_init_most_cmds(interp)
+Tcl_Interp *interp;
+{
+ exp_create_commands(interp,cmd_data);
+
+#ifdef HAVE_PTYTRAP
+ Tcl_InitHashTable(&slaveNames,TCL_STRING_KEYS);
+#endif /* HAVE_PTYTRAP */
+
+ exp_close_in_child = exp_close_tcl_files;
+}
+/* cribbed directly from tclBasic.c */
+int
+Tcl_CloseCmd(stuff, interp, argc, argv)
+ ClientData *stuff;
+ Tcl_Interp *interp;
+ int argc;
+ char **argv;
+{
+#define NUM_ARGS 20
+ Tcl_Obj *(argStorage[NUM_ARGS]);
+ register Tcl_Obj **objv = argStorage;
+ int i, result;
+ Tcl_Obj *objPtr;
+
+ /*
+ * Create the object argument array "objv". Make sure objv is large
+ * enough to hold the objc arguments plus 1 extra for the zero
+ * end-of-objv word.
+ */
+
+ if ((argc + 1) > NUM_ARGS) {
+ objv = (Tcl_Obj **)
+ Tcl_Alloc((unsigned)(argc + 1) * sizeof(Tcl_Obj *));
+ }
+
+ for (i = 0; i < argc; i++) {
+ objPtr = Tcl_NewStringObj(argv[i], -1);
+ Tcl_IncrRefCount(objPtr);
+ objv[i] = objPtr;
+ }
+ objv[argc] = 0;
+
+ /*
+ * Invoke the command's object-based Tcl_ObjCmdProc.
+ */
+
+ result = Tcl_CloseObjCmd(stuff, interp, argc, objv);
+
+ /*
+ * Move the interpreter's object result to the string result,
+ * then reset the object result.
+ * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULL BYTES.
+ */
+
+ Tcl_SetResult(interp,
+ TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
+ TCL_VOLATILE);
+
+ /*
+ * Decrement the ref counts for the argument objects created above,
+ * then free the objv array if malloc'ed storage was used.
+ */
+
+ for (i = 0; i < argc; i++) {
+ objPtr = objv[i];
+ Tcl_DecrRefCount(objPtr);
+ }
+ if (objv != argStorage) {
+ Tcl_Free((char *) objv);
+ }
+ return result;
+#undef NUM_ARGS
+}
diff --git a/expect/exp_command.h b/expect/exp_command.h
new file mode 100644
index 00000000000..c99266654fc
--- /dev/null
+++ b/expect/exp_command.h
@@ -0,0 +1,355 @@
+/* command.h - definitions for expect commands
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+EXTERN struct exp_f * exp_update_master
+ _ANSI_ARGS_((Tcl_Interp *,int *,int,int));
+EXTERN char * exp_get_var _ANSI_ARGS_((Tcl_Interp *,char *));
+
+EXTERN int exp_default_match_max;
+EXTERN int exp_default_parity;
+EXTERN int exp_default_rm_nulls;
+
+EXTERN int exp_one_arg_braced _ANSI_ARGS_((char *));
+EXTERN int exp_eval_with_one_arg _ANSI_ARGS_((ClientData,
+ Tcl_Interp *,char **));
+EXTERN void exp_lowmemcpy _ANSI_ARGS_((char *,char *,int));
+
+EXTERN int exp_flageq_code _ANSI_ARGS_((char *,char *,int));
+
+#define exp_flageq(flag,string,minlen) \
+(((string)[0] == (flag)[0]) && (exp_flageq_code(((flag)+1),((string)+1),((minlen)-1))))
+
+/* exp_flageq for single char flags */
+#define exp_flageq1(flag,string) \
+ ((string[0] == flag) && (string[1] == '\0'))
+
+/*
+ * The type of the status returned by wait varies from UNIX system
+ * to UNIX system. The macro below defines it:
+ * (stolen from tclUnix.h)
+ */
+
+#define WAIT_STATUS_TYPE int
+#if 0
+#ifdef AIX
+# define WAIT_STATUS_TYPE pid_t
+#else
+#ifndef NO_UNION_WAIT
+# define WAIT_STATUS_TYPE union wait
+#else
+# define WAIT_STATUS_TYPE int
+#endif
+#endif /* AIX */
+
+/* These macros are taken from tclUnix.h */
+
+#undef WIFEXITED
+#ifndef WIFEXITED
+# define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0)
+#endif
+
+#undef WEXITSTATUS
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
+#endif
+
+#undef WIFSIGNALED
+#ifndef WIFSIGNALED
+# define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff)))
+#endif
+
+#undef WTERMSIG
+#ifndef WTERMSIG
+# define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f)
+#endif
+
+#undef WIFSTOPPED
+#ifndef WIFSTOPPED
+# define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177)
+#endif
+
+#undef WSTOPSIG
+#ifndef WSTOPSIG
+# define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff)
+#endif
+
+#endif /* 0 */
+
+/* These macros are suggested by the autoconf documentation. */
+
+#undef WIFEXITED
+#ifndef WIFEXITED
+# define WIFEXITED(stat) (((stat) & 0xff) == 0)
+#endif
+
+#undef WEXITSTATUS
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat) (((stat) >> 8) & 0xff)
+#endif
+
+#undef WIFSIGNALED
+#ifndef WIFSIGNALED
+# define WIFSIGNALED(stat) ((stat) && ((stat) == ((stat) & 0x00ff)))
+#endif
+
+#undef WTERMSIG
+#ifndef WTERMSIG
+# define WTERMSIG(stat) ((stat) & 0x7f)
+#endif
+
+#undef WIFSTOPPED
+#ifndef WIFSTOPPED
+# define WIFSTOPPED(stat) (((stat) & 0xff) == 0177)
+#endif
+
+#undef WSTOPSIG
+#ifndef WSTOPSIG
+# define WSTOPSIG(stat) (((stat) >> 8) & 0xff)
+#endif
+
+
+
+#define EXP_SPAWN_ID_ANY_VARNAME "any_spawn_id"
+#define EXP_SPAWN_ID_ANY_LIT "-1"
+#define EXP_SPAWN_ID_ANY -1
+
+#define EXP_SPAWN_ID_ERROR_LIT "2"
+#define EXP_SPAWN_ID_USER_LIT "0"
+#define EXP_SPAWN_ID_USER 0
+
+#define exp_is_stdinfd(x) ((x) == 0)
+#define exp_is_devttyfd(x) ((x) == exp_dev_tty)
+
+#define EXP_NOPID 0 /* Used when there is no associated pid to */
+ /* wait for. For example: */
+ /* 1) When fd opened by someone else, e.g., */
+ /* Tcl's open */
+ /* 2) When entry not in use */
+ /* 3) To tell user pid of "spawn -open" */
+ /* 4) stdin, out, error */
+
+#define EXP_NOFD -1
+
+/* these are occasionally useful to distinguish between various expect */
+/* commands and are also used as array indices into the per-fd eg[] arrays */
+#define EXP_CMD_BEFORE 0
+#define EXP_CMD_AFTER 1
+#define EXP_CMD_BG 2
+#define EXP_CMD_FG 3
+
+/* each process is associated with a 'struct exp_f'. An array of these */
+/* ('exp_fs') keeps track of all processes. They are indexed by the true fd */
+/* to the master side of the pty */
+struct exp_f {
+ int *fd_ptr;
+#if 0
+ struct exp_f **ptr; /* our own address to this exp_f */
+ /* since address can change, provide this indirect */
+ /* pointer for people (Tk) who require a fixed ptr */
+#endif
+ int pid; /* pid or EXP_NOPID if no pid */
+ char *buffer; /* input buffer */
+ char *lower; /* input buffer in lowercase */
+ int size; /* current size of data */
+ int msize; /* size of buffer (true size is one greater
+ for trailing null) */
+ int umsize; /* user view of size of buffer */
+ int rm_nulls; /* if nulls should be stripped before pat matching */
+ int valid; /* if any of the other fields should be believed */
+ int user_closed;/* if user has issued "close" command or close has */
+ /* occurred implicitly */
+ int sys_closed; /* if close() has been called */
+ int user_waited;/* if user has issued "wait" command */
+ int sys_waited; /* if wait() (or variant) has been called */
+ WAIT_STATUS_TYPE wait; /* raw status from wait() */
+ int parity; /* strip parity if false */
+ int printed; /* # of characters written to stdout (if logging on) */
+ /* but not actually returned via a match yet */
+ int echoed; /* additional # of chars (beyond "printed" above) */
+ /* echoed back but not actually returned via a match */
+ /* yet. This supports interact -echo */
+ int key; /* unique id that identifies what command instance */
+ /* last touched this buffer */
+ int force_read; /* force read to occur (even if buffer already has */
+ /* data). This supports interact CAN_MATCH */
+ int fg_armed; /* If Tk_CreateFileHandler is active for responding */
+ /* to foreground events */
+
+#if TCL_MAJOR_VERSION < 8
+ Tcl_File Master; /* corresponds to master fd */
+ Tcl_File Slave; /* corresponds to slave_fd */
+ Tcl_File MasterOutput; /* corresponds to tcl_output */
+ /*
+ * Following comment only applies to Tcl 7.6:
+ * Explicit fds aren't necessary now, but since the code is already
+ * here from before Tcl required Tcl_File, we'll continue using
+ * the old fds. If we ever port this code to a non-UNIX system,
+ * we'll dump the fds totally.
+ */
+#endif /* TCL_MAJOR_VERSION < 8 */
+
+#ifdef __CYGWIN32__
+ Tcl_Channel channel; /* cygwin32 channel */
+ Tcl_FileProc *fileproc; /* Tcl_CreateFileHandler proc */
+ ClientData procdata; /* Tcl_CreateFileHandler data */
+#endif
+
+ int slave_fd; /* slave fd if "spawn -pty" used */
+#ifdef HAVE_PTYTRAP
+ char *slave_name;/* Full name of slave, i.e., /dev/ttyp0 */
+#endif /* HAVE_PTYTRAP */
+ char *tcl_handle;/* If opened by someone else, i.e. Tcl's open */
+ int tcl_output; /* output fd if opened by someone else */
+ /* input fd is the index of this struct (see above) */
+ int leaveopen; /* If we should not call Tcl's close when we close - */
+ /* only relevant if Tcl does the original open */
+ Tcl_Interp *bg_interp; /* interp to process the bg cases */
+ int bg_ecount; /* number of background ecases */
+ enum {
+ blocked, /* blocked because we are processing the */
+ /* file handler */
+ armed, /* normal state when bg handler in use */
+ unarmed, /* no bg handler in use */
+ disarm_req_while_blocked /* while blocked, a request */
+ /* was received to disarm it. Rather than */
+ /* processing the request immediately, defer */
+ /* it so that when we later try to unblock */
+ /* we will see at that time that it should */
+ /* instead be disarmed */
+ } bg_status;
+};
+
+extern int exp_fd_max; /* highest fd ever used */
+
+
+#define EXP_TEMPORARY 1 /* expect */
+#define EXP_PERMANENT 2 /* expect_after, expect_before, expect_bg */
+
+#define EXP_DIRECT 1
+#define EXP_INDIRECT 2
+
+EXTERN struct exp_f *exp_fs;
+
+EXTERN struct exp_f * exp_fd2f _ANSI_ARGS_((Tcl_Interp *,int,int,int,char *));
+EXTERN void exp_adjust _ANSI_ARGS_((struct exp_f *));
+EXTERN void exp_buffer_shuffle _ANSI_ARGS_((Tcl_Interp *,struct exp_f *,int,char *,char *));
+EXTERN int exp_close _ANSI_ARGS_((Tcl_Interp *,int));
+EXTERN void exp_close_all _ANSI_ARGS_((Tcl_Interp *));
+EXTERN void exp_ecmd_remove_fd_direct_and_indirect
+ _ANSI_ARGS_((Tcl_Interp *,int));
+EXTERN void exp_trap_on _ANSI_ARGS_((int));
+EXTERN int exp_trap_off _ANSI_ARGS_((char *));
+
+EXTERN void exp_strftime();
+
+#define exp_deleteProc (void (*)())0
+#define exp_deleteObjProc (void (*)())0
+
+EXTERN int expect_key;
+EXTERN int exp_configure_count; /* # of times descriptors have been closed */
+ /* or indirect lists have been changed */
+EXTERN int exp_nostack_dump; /* TRUE if user has requested unrolling of */
+ /* stack with no trace */
+
+EXTERN void exp_init_pty _ANSI_ARGS_((void));
+EXTERN void exp_pty_exit _ANSI_ARGS_((void));
+EXTERN void exp_init_tty _ANSI_ARGS_((void));
+EXTERN void exp_init_stdio _ANSI_ARGS_((void));
+/*EXTERN void exp_init_expect _ANSI_ARGS_((Tcl_Interp *));*/
+EXTERN void exp_init_spawn_ids _ANSI_ARGS_((void));
+EXTERN void exp_init_spawn_id_vars _ANSI_ARGS_((Tcl_Interp *));
+EXTERN void exp_init_trap _ANSI_ARGS_((void));
+EXTERN void exp_init_unit_random _ANSI_ARGS_((void));
+EXTERN void exp_init_sig _ANSI_ARGS_((void));
+
+EXTERN int exp_tcl2_returnvalue _ANSI_ARGS_((int));
+EXTERN int exp_2tcl_returnvalue _ANSI_ARGS_((int));
+
+EXTERN void exp_rearm_sigchld _ANSI_ARGS_((Tcl_Interp *));
+EXTERN int exp_string_to_signal _ANSI_ARGS_((Tcl_Interp *,char *));
+
+EXTERN char *exp_onexit_action;
+
+#define exp_new(x) (x *)malloc(sizeof(x))
+
+struct exp_fd_list {
+ int fd;
+ struct exp_fd_list *next;
+};
+
+/* describes a -i flag */
+struct exp_i {
+ int cmdtype; /* EXP_CMD_XXX. When an indirect update is */
+ /* triggered by Tcl, this helps tell us in what */
+ /* exp_i list to look in. */
+ int direct; /* if EXP_DIRECT, then the spawn ids have been given */
+ /* literally, else indirectly through a variable */
+ int duration; /* if EXP_PERMANENT, char ptrs here had to be */
+ /* malloc'd because Tcl command line went away - */
+ /* i.e., in expect_before/after */
+ char *variable;
+ char *value; /* if type == direct, this is the string that the */
+ /* user originally supplied to the -i flag. It may */
+ /* lose relevance as the fd_list is manipulated */
+ /* over time. If type == direct, this is the */
+ /* cached value of variable use this to tell if it */
+ /* has changed or not, and ergo whether it's */
+ /* necessary to reparse. */
+
+ int ecount; /* # of ecases this is used by */
+
+ struct exp_fd_list *fd_list;
+ struct exp_i *next;
+};
+
+EXTERN struct exp_i * exp_new_i_complex _ANSI_ARGS_((Tcl_Interp *,
+ char *, int, Tcl_VarTraceProc *));
+EXTERN struct exp_i * exp_new_i_simple _ANSI_ARGS_((int,int));
+EXTERN struct exp_fd_list *exp_new_fd _ANSI_ARGS_((int));
+EXTERN void exp_free_i _ANSI_ARGS_((Tcl_Interp *,struct exp_i *,
+ Tcl_VarTraceProc *));
+EXTERN void exp_free_fd _ANSI_ARGS_((struct exp_fd_list *));
+EXTERN void exp_free_fd_single _ANSI_ARGS_((struct exp_fd_list *));
+EXTERN void exp_i_update _ANSI_ARGS_((Tcl_Interp *,
+ struct exp_i *));
+
+/*
+ * definitions for creating commands
+ */
+
+#define EXP_NOPREFIX 1 /* don't define with "exp_" prefix */
+#define EXP_REDEFINE 2 /* stomp on old commands with same name */
+
+/* a hack for easily supporting both Tcl 7 and 8 CreateCommand/Obj split */
+/* Can be discarded with Tcl 7 is. */
+#if TCL_MAJOR_VERSION < 8
+#define exp_proc(cmdproc) cmdproc
+#else
+#define exp_proc(cmdproc) 0, cmdproc
+#endif
+
+struct exp_cmd_data {
+ char *name;
+#if TCL_MAJOR_VERSION >= 8
+ Tcl_ObjCmdProc *objproc;
+#endif
+ Tcl_CmdProc *proc;
+ ClientData data;
+ int flags;
+};
+
+EXTERN void exp_create_commands _ANSI_ARGS_((Tcl_Interp *,
+ struct exp_cmd_data *));
+EXTERN void exp_init_main_cmds _ANSI_ARGS_((Tcl_Interp *));
+EXTERN void exp_init_expect_cmds _ANSI_ARGS_((Tcl_Interp *));
+EXTERN void exp_init_most_cmds _ANSI_ARGS_((Tcl_Interp *));
+EXTERN void exp_init_trap_cmds _ANSI_ARGS_((Tcl_Interp *));
+EXTERN void exp_init_interact_cmds _ANSI_ARGS_((Tcl_Interp *));
+EXTERN void exp_init_tty_cmds();
+
diff --git a/expect/exp_console.c b/expect/exp_console.c
new file mode 100644
index 00000000000..1305ef1fc4a
--- /dev/null
+++ b/expect/exp_console.c
@@ -0,0 +1,68 @@
+/* exp_console.c - grab console. This stuff is in a separate file to
+avoid unpleasantness of AIX (3.2.4) .h files which provide no way to
+reference TIOCCONS and include both sys/ioctl.h and sys/sys/stropts.h
+without getting some sort of warning from the compiler. The problem
+is that both define _IO but only ioctl.h checks to see if it is
+defined first. This would suggest that it is sufficient to include
+ioctl.h after stropts.h. Unfortunately, ioctl.h, having seen that _IO
+is defined, then fails to define other important things (like _IOW).
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+#include "expect_cf.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#ifdef HAVE_STRREDIR_H
+#include <sys/strredir.h>
+# ifdef SRIOCSREDIR
+# undef TIOCCONS
+# endif
+#endif
+
+#ifdef HAVE_SYS_FCNTL_H
+#include <sys/fcntl.h>
+#endif
+
+#include "tcl.h"
+#include "exp_rename.h"
+#include "exp_prog.h"
+#include "exp_log.h"
+
+static void
+exp_console_manipulation_failed(s)
+char *s;
+{
+ exp_errorlog("expect: spawn: cannot %s console, check permissions of /dev/console\n",s);
+ exit(-1);
+}
+
+void
+exp_console_set()
+{
+#ifdef SRIOCSREDIR
+ int fd;
+
+ if ((fd = open("/dev/console", O_RDONLY)) == -1) {
+ exp_console_manipulation_failed("open");
+ }
+ if (ioctl(fd, SRIOCSREDIR, 0) == -1) {
+ exp_console_manipulation_failed("redirect");
+ }
+ close(fd);
+#endif
+
+#ifdef TIOCCONS
+ int on = 1;
+
+ if (ioctl(0,TIOCCONS,(char *)&on) == -1) {
+ exp_console_manipulation_failed("redirect");
+ }
+#endif /*TIOCCONS*/
+}
diff --git a/expect/exp_event.c b/expect/exp_event.c
new file mode 100644
index 00000000000..e85da713f18
--- /dev/null
+++ b/expect/exp_event.c
@@ -0,0 +1,1081 @@
+/* exp_event.c - event interface for Expect
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+/* Notes:
+I'm only a little worried because Tk does not check for errno == EBADF
+after calling select. I imagine that if the user passes in a bad file
+descriptor, we'll never get called back, and thus, we'll hang forever
+- it would be better to at least issue a diagnostic to the user.
+
+Another possible problem: Tk does not do file callbacks round-robin.
+
+Another possible problem: Calling Create/DeleteFileHandler
+before/after every Tcl_Eval... in expect/interact could be very
+expensive.
+
+*/
+
+
+#include "expect_cf.h"
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_PTYTRAP
+# include <sys/ptyio.h>
+#endif
+
+#include "tcl.h"
+#include "exp_prog.h"
+#include "exp_command.h" /* for struct exp_f defs */
+#include "exp_event.h"
+
+/* Tcl_DoOneEvent will call our filehandler which will set the following */
+/* vars enabling us to know where and what kind of I/O we can do */
+/*#define EXP_SPAWN_ID_BAD -1*/
+/*#define EXP_SPAWN_ID_TIMEOUT -2*/ /* really indicates a timeout */
+
+static int ready_fd = EXP_SPAWN_ID_BAD;
+static int ready_mask;
+static int default_mask = TCL_READABLE | TCL_EXCEPTION;
+
+
+void
+exp_event_disarm(fd)
+int fd;
+{
+#if TCL_MAJOR_VERSION < 8
+ Tcl_DeleteFileHandler(exp_fs[fd].Master);
+#else
+ Tcl_DeleteFileHandler(fd);
+#endif
+
+ /* remember that filehandler has been disabled so that */
+ /* it can be turned on for fg expect's as well as bg */
+ exp_fs[fd].fg_armed = FALSE;
+}
+
+void
+exp_event_disarm_fast(fd,filehandler)
+int fd;
+Tcl_FileProc *filehandler;
+{
+ /* Temporarily delete the filehandler by assigning it a mask */
+ /* that permits no events! */
+ /* This reduces the calls to malloc/free inside Tcl_...FileHandler */
+ /* Tk insists on having a valid proc here even though it isn't used */
+#if TCL_MAJOR_VERSION < 8
+ Tcl_CreateFileHandler(exp_fs[fd].Master,0,filehandler,(ClientData)0);
+#else
+ Tcl_CreateFileHandler(fd,0,filehandler,(ClientData)0);
+#endif
+
+ /* remember that filehandler has been disabled so that */
+ /* it can be turned on for fg expect's as well as bg */
+ exp_fs[fd].fg_armed = FALSE;
+}
+
+static void
+exp_arm_background_filehandler_force(m)
+int m;
+{
+#if TCL_MAJOR_VERSION < 8
+ Tcl_CreateFileHandler(exp_fs[m].Master,
+#else
+ Tcl_CreateFileHandler(m,
+#endif
+ TCL_READABLE|TCL_EXCEPTION,
+ exp_background_filehandler,
+ (ClientData)(exp_fs[m].fd_ptr));
+
+ exp_fs[m].bg_status = armed;
+}
+
+void
+exp_arm_background_filehandler(m)
+int m;
+{
+ switch (exp_fs[m].bg_status) {
+ case unarmed:
+ exp_arm_background_filehandler_force(m);
+ break;
+ case disarm_req_while_blocked:
+ exp_fs[m].bg_status = blocked; /* forget request */
+ break;
+ case armed:
+ case blocked:
+ /* do nothing */
+ break;
+ }
+}
+
+void
+exp_disarm_background_filehandler(m)
+int m;
+{
+ switch (exp_fs[m].bg_status) {
+ case blocked:
+ exp_fs[m].bg_status = disarm_req_while_blocked;
+ break;
+ case armed:
+ exp_fs[m].bg_status = unarmed;
+ exp_event_disarm(m);
+ break;
+ case disarm_req_while_blocked:
+ case unarmed:
+ /* do nothing */
+ break;
+ }
+}
+
+/* ignore block status and forcibly disarm handler - called from exp_close. */
+/* After exp_close returns, we will not have an opportunity to disarm */
+/* because the fd will be invalid, so we force it here. */
+void
+exp_disarm_background_filehandler_force(m)
+int m;
+{
+ switch (exp_fs[m].bg_status) {
+ case blocked:
+ case disarm_req_while_blocked:
+ case armed:
+ exp_fs[m].bg_status = unarmed;
+ exp_event_disarm(m);
+ break;
+ case unarmed:
+ /* do nothing */
+ break;
+ }
+}
+
+/* this can only be called at the end of the bg handler in which */
+/* case we know the status is some kind of "blocked" */
+void
+exp_unblock_background_filehandler(m)
+int m;
+{
+ switch (exp_fs[m].bg_status) {
+ case blocked:
+ exp_arm_background_filehandler_force(m);
+ break;
+ case disarm_req_while_blocked:
+ exp_disarm_background_filehandler_force(m);
+ break;
+ case armed:
+ case unarmed:
+ /* Not handled, FIXME? */
+ break;
+ }
+}
+
+/* this can only be called at the beginning of the bg handler in which */
+/* case we know the status must be "armed" */
+void
+exp_block_background_filehandler(m)
+int m;
+{
+ exp_fs[m].bg_status = blocked;
+ exp_event_disarm_fast(m,exp_background_filehandler);
+}
+
+
+/*ARGSUSED*/
+static void
+exp_timehandler(clientData)
+ClientData clientData;
+{
+ *(int *)clientData = TRUE;
+}
+
+static void exp_filehandler(clientData,mask)
+ClientData clientData;
+int mask;
+{
+ /* if input appears, record the fd on which it appeared */
+
+ ready_fd = *(int *)clientData;
+ ready_mask = mask;
+ exp_event_disarm_fast(ready_fd,exp_filehandler);
+
+#if 0
+ if (ready_fd == *(int *)clientData) {
+ /* if input appears from an fd which we've already heard */
+ /* forcibly tell it to shut up. We could also shut up */
+ /* every instance, but it is more efficient to leave the */
+ /* fd enabled with the belief that we may rearm soon enough */
+ /* anyway. */
+
+ exp_event_disarm_fast(ready_fd,exp_filehandler);
+ } else {
+ ready_fd = *(int *)clientData;
+ ready_mask = mask;
+ }
+#endif
+}
+
+/* returns status, one of EOF, TIMEOUT, ERROR or DATA */
+/* can now return RECONFIGURE, too */
+/*ARGSUSED*/
+int exp_get_next_event(interp,masters, n,master_out,timeout,key)
+Tcl_Interp *interp;
+int *masters;
+int n; /* # of masters */
+int *master_out; /* 1st ready master, not set if none */
+int timeout; /* seconds */
+int key;
+{
+ static rr = 0; /* round robin ptr */
+ int i; /* index into in-array */
+#ifdef HAVE_PTYTRAP
+ struct request_info ioctl_info;
+#endif
+
+ int old_configure_count = exp_configure_count;
+
+ int timer_created = FALSE;
+ int timer_fired = FALSE;
+ Tcl_TimerToken timetoken;/* handle to Tcl timehandler descriptor */
+
+ for (;;) {
+ int m;
+ struct exp_f *f;
+
+ /* if anything has been touched by someone else, report that */
+ /* an event has been received */
+
+ for (i=0;i<n;i++) {
+ rr++;
+ if (rr >= n) rr = 0;
+
+ m = masters[rr];
+ f = exp_fs + m;
+
+ if (f->key != key) {
+ f->key = key;
+ f->force_read = FALSE;
+ *master_out = m;
+ return(EXP_DATA_OLD);
+ } else if ((!f->force_read) && (f->size != 0)) {
+ *master_out = m;
+ return(EXP_DATA_OLD);
+ }
+ }
+
+ if (!timer_created) {
+ if (timeout >= 0) {
+ timetoken = Tcl_CreateTimerHandler(1000*timeout,
+ exp_timehandler,
+ (ClientData)&timer_fired);
+ timer_created = TRUE;
+ }
+ }
+
+ for (;;) {
+ int j;
+
+ /* make sure that all fds that should be armed are */
+ for (j=0;j<n;j++) {
+ int k = masters[j];
+
+ if (!exp_fs[k].fg_armed) {
+ Tcl_CreateFileHandler(
+#if TCL_MAJOR_VERSION < 8
+ exp_fs[k].Master,
+#else
+ k,
+#endif
+ default_mask,
+ exp_filehandler,
+ (ClientData)exp_fs[k].fd_ptr);
+ exp_fs[k].fg_armed = TRUE;
+ }
+ }
+
+ Tcl_DoOneEvent(0); /* do any event */
+
+ if (timer_fired) return(EXP_TIMEOUT);
+
+ if (old_configure_count != exp_configure_count) {
+ if (timer_created) Tcl_DeleteTimerHandler(timetoken);
+ return EXP_RECONFIGURE;
+ }
+
+ if (ready_fd == EXP_SPAWN_ID_BAD) continue;
+
+ /* if it was from something we're not looking for at */
+ /* the moment, ignore it */
+ for (j=0;j<n;j++) {
+ if (ready_fd == masters[j]) goto found;
+ }
+
+ /* not found */
+ exp_event_disarm_fast(ready_fd,exp_filehandler);
+ ready_fd = EXP_SPAWN_ID_BAD;
+ continue;
+ found:
+ *master_out = ready_fd;
+ ready_fd = EXP_SPAWN_ID_BAD;
+
+ /* this test should be redundant but SunOS */
+ /* raises both READABLE and EXCEPTION (for no */
+ /* apparent reason) when selecting on a plain file */
+ if (ready_mask & TCL_READABLE) {
+ if (timer_created) Tcl_DeleteTimerHandler(timetoken);
+ return EXP_DATA_NEW;
+ }
+
+ /* ready_mask must contain TCL_EXCEPTION */
+#ifndef HAVE_PTYTRAP
+ if (timer_created) Tcl_DeleteTimerHandler(timetoken);
+ return(EXP_EOF);
+#else
+ if (ioctl(*master_out,TIOCREQCHECK,&ioctl_info) < 0) {
+ if (timer_created)
+ Tcl_DeleteTimerHandler(timetoken);
+ exp_debuglog("ioctl error on TIOCREQCHECK: %s", Tcl_PosixError(interp));
+ return(EXP_TCLERROR);
+ }
+ if (ioctl_info.request == TIOCCLOSE) {
+ if (timer_created)
+ Tcl_DeleteTimerHandler(timetoken);
+ return(EXP_EOF);
+ }
+ if (ioctl(*master_out, TIOCREQSET, &ioctl_info) < 0) {
+ exp_debuglog("ioctl error on TIOCREQSET after ioctl or open on slave: %s", Tcl_ErrnoMsg(errno));
+ }
+ /* presumably, we trapped an open here */
+ continue;
+#endif /* !HAVE_PTYTRAP */
+ }
+ }
+}
+
+/* Having been told there was an event for a specific fd, get it */
+/* returns status, one of EOF, TIMEOUT, ERROR or DATA */
+/*ARGSUSED*/
+int
+exp_get_next_event_info(interp,fd,ready_mask)
+Tcl_Interp *interp;
+int fd;
+int ready_mask;
+{
+#ifdef HAVE_PTYTRAP
+ struct request_info ioctl_info;
+#endif
+
+ if (ready_mask & TCL_READABLE) return EXP_DATA_NEW;
+
+ /* ready_mask must contain TCL_EXCEPTION */
+
+#ifndef HAVE_PTYTRAP
+ return(EXP_EOF);
+#else
+ if (ioctl(fd,TIOCREQCHECK,&ioctl_info) < 0) {
+ exp_debuglog("ioctl error on TIOCREQCHECK: %s",
+ Tcl_PosixError(interp));
+ return(EXP_TCLERROR);
+ }
+ if (ioctl_info.request == TIOCCLOSE) {
+ return(EXP_EOF);
+ }
+ if (ioctl(fd, TIOCREQSET, &ioctl_info) < 0) {
+ exp_debuglog("ioctl error on TIOCREQSET after ioctl or open on slave: %s", Tcl_ErrnoMsg(errno));
+ }
+ /* presumably, we trapped an open here */
+ /* call it an error for lack of anything more descriptive */
+ /* it will be thrown away by caller anyway */
+ return EXP_TCLERROR;
+#endif
+}
+
+/*ARGSUSED*/
+int /* returns TCL_XXX */
+exp_dsleep(interp,sec)
+Tcl_Interp *interp;
+double sec;
+{
+ int timer_fired = FALSE;
+
+ Tcl_CreateTimerHandler((int)(sec*1000),exp_timehandler,(ClientData)&timer_fired);
+
+ while (1) {
+ Tcl_DoOneEvent(0);
+ if (timer_fired) return TCL_OK;
+
+ if (ready_fd == EXP_SPAWN_ID_BAD) continue;
+
+ exp_event_disarm_fast(ready_fd,exp_filehandler);
+ ready_fd = EXP_SPAWN_ID_BAD;
+ }
+}
+
+#if 0
+/*ARGSUSED*/
+int /* returns TCL_XXX */
+exp_usleep(interp,usec)
+Tcl_Interp *interp;
+long usec;
+{
+ int timer_fired = FALSE;
+
+ Tcl_CreateTimerHandler(usec/1000,exp_timehandler,(ClientData)&timer_fired);
+
+ while (1) {
+ Tcl_DoOneEvent(0);
+ if (timer_fired) return TCL_OK;
+
+ if (ready_fd == EXP_SPAWN_ID_BAD) continue;
+
+ exp_event_disarm_fast(ready_fd,exp_filehandler);
+ ready_fd = EXP_SPAWN_ID_BAD;
+ }
+}
+#endif
+
+static char destroy_cmd[] = "destroy .";
+
+static void
+exp_event_exit_real(interp)
+Tcl_Interp *interp;
+{
+ Tcl_Eval(interp,destroy_cmd);
+}
+
+/* set things up for later calls to event handler */
+void
+exp_init_event()
+{
+ exp_event_exit = exp_event_exit_real;
+}
+
+#ifdef __CYGWIN32__
+#if 0
+
+/* The Tcl_CreateFileHandler call is only defined on Unix. We provide
+ our own implementation here that works on cygwin32. */
+
+#include <windows.h>
+#include <sys/socket.h>
+#include <tclInt.h>
+
+#if TCL_MAJOR_VERSION < 7
+# error not implemented
+#endif
+
+static void pipe_setup _ANSI_ARGS_((ClientData, int));
+static void pipe_check _ANSI_ARGS_((ClientData, int));
+static void pipe_exit _ANSI_ARGS_((ClientData));
+static int pipe_close _ANSI_ARGS_((ClientData, Tcl_Interp *));
+static int pipe_input _ANSI_ARGS_((ClientData, char *, int, int *));
+static int pipe_output _ANSI_ARGS_((ClientData, char *, int, int *));
+static void pipe_watch _ANSI_ARGS_((ClientData, int));
+static int pipe_get_handle _ANSI_ARGS_((ClientData, int, ClientData *));
+static int pipe_event _ANSI_ARGS_((Tcl_Event *, int));
+
+/* The pipe channel interface. */
+
+static Tcl_ChannelType pipe_channel = {
+ "expect_pipe",
+ NULL, /* block */
+ pipe_close,
+ pipe_input,
+ pipe_output,
+ NULL, /* seek */
+ NULL, /* set option */
+ NULL, /* get option */
+ pipe_watch,
+ pipe_get_handle
+};
+
+/* The structure we use to represent a pipe channel. */
+
+struct pipe_info {
+ struct pipe_info *next; /* Next pipe. */
+ Tcl_Channel channel; /* The Tcl channel. */
+ int fd; /* cygwin32 file descriptor. */
+ int watch_mask; /* Events that should be reported. */
+ int flags; /* State flags; see below. */
+ HANDLE flags_mutex; /* Mutex to control access to flags. */
+ HANDLE mutex; /* Mutex to control access to pipe. */
+ HANDLE try_read; /* Event to tell thread to try a read. */
+ HANDLE pthread; /* Handle of thread inspecting the pipe. */
+};
+
+/* Values that can appear in the flags field of a pipe_info structure. */
+
+#define PIPE_PENDING (1 << 0) /* Message pending. */
+#define PIPE_READABLE (1 << 1) /* Pipe is readable. */
+#define PIPE_CLOSED (1 << 2) /* Pipe is closed. */
+#define PIPE_HAS_THREAD (1 << 3) /* A thread is running. */
+
+/* A pipe event structure. */
+
+struct pipe_event {
+ Tcl_Event header; /* Standard Tcl event header. */
+ struct pipe_info *pipe; /* Pipe information. */
+};
+
+/* Whether we've initialized the pipe code. */
+
+static int pipe_initialized;
+
+/* The list of pipes. */
+
+static struct pipe_info *pipes;
+
+/* A hidden window we use for pipe events. */
+
+static HWND pipe_window;
+
+/* A message we use for pipe events. */
+
+#define PIPE_MESSAGE (WM_USER + 1)
+
+/* Get the flags for a pipe. */
+
+static int
+pipe_get_flags (pipe)
+struct pipe_info *pipe;
+{
+ int flags;
+
+ WaitForSingleObject (pipe->flags_mutex, INFINITE);
+ flags = pipe->flags;
+ ReleaseMutex (pipe->flags_mutex);
+ return flags;
+}
+
+/* Set a flag for a pipe. */
+
+static void
+pipe_set_flag (pipe, flag)
+struct pipe_info *pipe;
+int flag;
+{
+ WaitForSingleObject (pipe->flags_mutex, INFINITE);
+ pipe->flags |= flag;
+ ReleaseMutex (pipe->flags_mutex);
+}
+
+/* Reset a flag for a pipe. */
+
+static void
+pipe_reset_flag (pipe, flag)
+struct pipe_info *pipe;
+int flag;
+{
+ WaitForSingleObject (pipe->flags_mutex, INFINITE);
+ pipe->flags &= ~ flag;
+ ReleaseMutex (pipe->flags_mutex);
+}
+
+/* This function runs in a separate thread. When requested, it sends
+ a message if there is something to read from the pipe. FIXME: I'm
+ not sure that this thread will ever be killed off at present. */
+
+static DWORD
+pipe_thread (arg)
+LPVOID arg;
+{
+ struct pipe_info *pipe = (struct pipe_info *) arg;
+ HANDLE handle = get_osfhandle(pipe->fd);
+ struct timeval timeout;
+
+ while (1) {
+ int n, tba;
+ fd_set r, x;
+
+ /* time out in case this thread was "forgotten" */
+ if (WaitForSingleObject (pipe->try_read, 10000) == WAIT_TIMEOUT)
+ {
+ n = PeekNamedPipe(handle, NULL, 0, NULL, &tba, NULL);
+ if (n == 0)
+ break; /* pipe closed? */
+ }
+
+ if (pipe_get_flags (pipe) & PIPE_CLOSED) {
+ break;
+ }
+
+ /* We use a loop periodically trying PeekNamedPipe.
+ This is inefficient, but unfortunately Windows
+ doesn't have any asynchronous mechanism to read
+ from a pipe. */
+
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 0;
+ FD_ZERO (&r);
+ FD_SET (pipe->fd, &r);
+ FD_ZERO (&x);
+ FD_SET (pipe->fd, &x);
+ if ((n = select (pipe->fd + 1, &r, NULL, &x, &timeout)) <= 0 ||
+ FD_ISSET(pipe->fd, &x))
+ /* pipe_set_flag (pipe, PIPE_CLOSED)*/;
+
+ /* Something can be read from the pipe. */
+ pipe_set_flag (pipe, PIPE_READABLE);
+
+ if (pipe_get_flags (pipe) & PIPE_CLOSED) {
+ break;
+ }
+
+ /* Post a message to wake up the event loop. */
+ PostMessage (pipe_window, PIPE_MESSAGE, 0, (LPARAM) pipe);
+ if (n < 0 || FD_ISSET (pipe->fd, &x))
+ break;
+ }
+
+ /* The pipe is closed. */
+
+ CloseHandle (pipe->flags_mutex); pipe->flags_mutex = NULL;
+ CloseHandle (pipe->try_read); pipe->try_read = NULL;
+ pipe_reset_flag (pipe, PIPE_HAS_THREAD);
+ return 0;
+}
+
+/* This function is called when pipe_thread posts a message. */
+
+static LRESULT CALLBACK
+pipe_proc (hwnd, message, wParam, lParam)
+HWND hwnd;
+UINT message;
+WPARAM wParam;
+LPARAM lParam;
+{
+ if (message != PIPE_MESSAGE) {
+ return DefWindowProc (hwnd, message, wParam, lParam);
+ }
+
+ /* This function really only exists to wake up the main Tcl
+ event loop. We don't actually have to do anything. */
+
+ return 0;
+}
+
+/* Initialize the pipe channel. */
+
+static void
+pipe_init ()
+{
+ WNDCLASS class;
+
+ pipe_initialized = 1;
+
+ Tcl_CreateEventSource (pipe_setup, pipe_check, NULL);
+ Tcl_CreateExitHandler (pipe_exit, NULL);
+
+ /* Create a hidden window for asynchronous notification. */
+
+ memset (&class, 0, sizeof class);
+ class.hInstance = GetModuleHandle (NULL);
+ class.lpszClassName = "expect_pipe";
+ class.lpfnWndProc = pipe_proc;
+
+ if (! RegisterClass (&class)) {
+ exp_errorlog ("RegisterClass failed: %d\n", GetLastError ());
+ exit (-1);
+ }
+
+ pipe_window = CreateWindow ("expect_pipe", "expect_pipe",
+ WS_TILED, 0, 0, 0, 0, NULL, NULL,
+ class.hInstance, NULL);
+ if (pipe_window == NULL) {
+ exp_errorlog ("CreateWindow failed: %d\n", GetLastError ());
+ exit (-1);
+ }
+}
+
+/* Clean up the pipe channel when we exit. */
+
+static void
+pipe_exit (cd)
+ClientData cd;
+{
+ Tcl_DeleteEventSource (pipe_setup, pipe_check, NULL);
+ UnregisterClass ("expect_pipe", GetModuleHandle (NULL));
+ DestroyWindow (pipe_window);
+ pipe_initialized = 0;
+}
+
+/* Set up for a pipe event. */
+
+static void
+pipe_setup (cd, flags)
+ClientData cd;
+int flags;
+{
+ struct pipe_info *p;
+ Tcl_Time zero_time = { 0, 0 };
+
+ if (! (flags & TCL_FILE_EVENTS)) {
+ return;
+ }
+
+ /* See if there is a watched pipe for which we already have an
+ event. If there is, set the maximum block time to 0. */
+
+ for (p = pipes; p != NULL; p = p->next) {
+ if ((p->watch_mask &~ TCL_READABLE)
+ || ((p->watch_mask & TCL_READABLE)
+ && ((pipe_get_flags (p) & PIPE_HAS_THREAD) == 0
+ || (pipe_get_flags (p) & PIPE_READABLE)))) {
+ Tcl_SetMaxBlockTime (&zero_time);
+ break;
+ } else if (p->watch_mask & TCL_READABLE) {
+ /* Tell the thread to try reads and let us
+ know when it is done. */
+ SetEvent (p->try_read);
+ }
+ }
+}
+
+/* Check pipes for events. */
+
+static void
+pipe_check (cd, flags)
+ClientData cd;
+int flags;
+{
+ struct pipe_info *p;
+
+ if (! (flags & TCL_FILE_EVENTS)) {
+ return;
+ }
+
+ /* Queue events for any watched pipes that don't already have
+ events queued. */
+
+ for (p = pipes; p != NULL; p = p->next) {
+ if (((p->watch_mask &~ TCL_READABLE)
+ || ((p->watch_mask & TCL_READABLE)
+ && ((pipe_get_flags (p) & PIPE_HAS_THREAD) == 0
+ || (pipe_get_flags (p) & PIPE_READABLE))))
+ && ! (pipe_get_flags (p) & PIPE_PENDING)) {
+ struct pipe_event *ev;
+
+ pipe_set_flag (p, PIPE_PENDING);
+ ev = (struct pipe_event *) Tcl_Alloc (sizeof *ev);
+ ev->header.proc = pipe_event;
+ ev->pipe = p;
+ Tcl_QueueEvent ((Tcl_Event *) ev, TCL_QUEUE_TAIL);
+ }
+ }
+}
+
+/* Handle closing a pipe. This is probably never called at present. */
+
+static int
+pipe_close (cd, interp)
+ClientData cd;
+Tcl_Interp *interp;
+{
+ struct pipe_info *p = (struct pipe_info *) cd;
+ struct pipe_info **pp;
+
+ for (pp = &pipes; *pp != NULL; pp = &(*pp)->next) {
+ if (*pp == p) {
+ *pp = p->next;
+ break;
+ }
+ }
+
+ /* FIXME: How should we handle closing the handle? At
+ present, this code will only work correctly if the handle
+ is closed before this code is called; otherwise, we may
+ wait forever for the thread. */
+
+ if (pipe_get_flags (p) & PIPE_HAS_THREAD) {
+ close (p->fd);
+ pipe_set_flag (p, PIPE_CLOSED);
+ (void) SetEvent (p->try_read);
+ WaitForSingleObject (p->pthread, 10000);
+ CloseHandle (p->pthread);
+ } else {
+ CloseHandle (p->flags_mutex);
+ }
+ Tcl_Free ((char *) p);
+
+ return 0;
+}
+
+/* Handle reading from a pipe. This will never be called. */
+
+static int
+pipe_input (cd, buf, size, error)
+ClientData cd;
+char *buf;
+int size;
+int *error;
+{
+ exp_errorlog ("pipe_input called");
+ exit (-1);
+}
+
+/* Handle writing to a pipe. This will never be called. */
+
+static int
+pipe_output (cd, buf, size, error)
+ClientData cd;
+char *buf;
+int size;
+int *error;
+{
+ exp_errorlog ("pipe_output called");
+ exit (-1);
+}
+
+/* Handle a pipe event. This is called when a pipe event created by
+ pipe_check reaches the head of the Tcl queue. */
+
+static int
+pipe_event (ev, flags)
+Tcl_Event *ev;
+int flags;
+{
+ struct pipe_event *pev = (struct pipe_event *) ev;
+ struct pipe_info *p;
+ int mask;
+
+ if (! (flags & TCL_FILE_EVENTS)) {
+ return 0;
+ }
+
+ /* Make sure the pipe is still being watched. */
+ for (p = pipes; p != NULL; p = p->next) {
+ if (p == pev->pipe) {
+ pipe_reset_flag (p, PIPE_PENDING);
+ break;
+ }
+ }
+
+ if (p == NULL) {
+ return 1;
+ }
+
+ if (pipe_get_flags (p) & PIPE_HAS_THREAD) {
+ mask = TCL_WRITABLE;
+ if (pipe_get_flags (p) & PIPE_READABLE) {
+ mask |= TCL_READABLE;
+ }
+ } else {
+ mask = TCL_WRITABLE | TCL_READABLE;
+ }
+
+ /* Tell the channel about any events. */
+
+ Tcl_NotifyChannel (p->channel, p->watch_mask & mask);
+
+ return 1;
+}
+
+/* Set up to watch a pipe. */
+
+static void
+pipe_watch (cd, mask)
+ClientData cd;
+int mask;
+{
+ struct pipe_info *p = (struct pipe_info *) cd;
+ int old_mask;
+
+ old_mask = p->watch_mask;
+ p->watch_mask = mask & (TCL_READABLE | TCL_WRITABLE);
+ if (p->watch_mask != 0) {
+ Tcl_Time zero_time = { 0, 0 };
+
+ if ((p->watch_mask & TCL_READABLE) != 0
+ && (pipe_get_flags (p) & PIPE_HAS_THREAD) == 0) {
+ HANDLE thread;
+ DWORD tid;
+
+ p->try_read = CreateEvent (NULL, FALSE, FALSE,
+ NULL);
+ pipe_set_flag (p, PIPE_HAS_THREAD);
+ p->pthread = CreateThread (NULL, 0, pipe_thread,
+ p, 0, &tid);
+ /* CYGNUS LOCAL: plug a handle leak - dj */
+ if (!p->pthread)
+ {
+ fprintf(stderr, "Error: cannot create pipe thread, error=%d\n", GetLastError());
+ exit(1);
+ }
+
+ CloseHandle(p->pthread);
+ }
+
+ if (old_mask == 0) {
+ p->next = pipes;
+ pipes = p;
+ }
+
+ Tcl_SetMaxBlockTime (&zero_time);
+ } else {
+ if (old_mask != 0) {
+ struct pipe_info **pp;
+
+ for (pp = &pipes; *pp != NULL; pp = &(*pp)->next) {
+ if (*pp == p) {
+ *pp = p->next;
+ break;
+ }
+ }
+ }
+ }
+}
+
+/* Get the handle of a pipe. */
+
+static int
+pipe_get_handle (cd, dir, handle_ptr)
+ClientData cd;
+int dir;
+ClientData *handle_ptr;
+{
+ struct pipe_info *p = (struct pipe_info *) cd;
+
+ *handle_ptr = (ClientData *)p->fd;
+ return TCL_OK;
+}
+
+/* Make a pipe channel. */
+
+static Tcl_Channel
+make_pipe_channel (fd, handle)
+int fd;
+HANDLE handle;
+{
+ Tcl_Channel chan;
+ struct pipe_info *p;
+ char namebuf[30];
+
+ if (! pipe_initialized) {
+ pipe_init ();
+ }
+
+ p = (struct pipe_info *) Tcl_Alloc (sizeof *p);
+
+ p->next = NULL;
+ p->fd = fd;
+ p->watch_mask = 0;
+ p->flags = 0;
+ p->flags_mutex = CreateMutex (NULL, FALSE, NULL);
+ p->try_read = NULL;
+
+ sprintf (namebuf, "expect_pipe%d", handle);
+ p->channel = Tcl_CreateChannel (&pipe_channel, namebuf,
+ (ClientData) p,
+ TCL_READABLE | TCL_WRITABLE);
+
+ Tcl_SetChannelOption ((Tcl_Interp *) NULL, p->channel,
+ "-translation", "binary");
+
+ return p->channel;
+}
+
+/* This is called when we read from a file descriptor. If that file
+ descriptor turns out to be a pipe, we turn off the PIPE_READABLE
+ flag. If we didn't do this, then every time we entered the Tcl
+ event loop we would think the pipe was readable. If we read the
+ pipe using Tcl channel functions, we wouldn't have this problem. */
+
+void
+exp_reading_from_descriptor (fd)
+int fd;
+{
+ struct pipe_info *p;
+
+ for (p = pipes; p != NULL; p = p->next) {
+ if (p->fd == fd) {
+ pipe_reset_flag (p, PIPE_READABLE);
+ break;
+ }
+ }
+}
+
+/* Implement Tcl_CreateFileHandler for cygwin32. */
+
+void
+Tcl_CreateFileHandler (fd, mask, proc, cd)
+int fd;
+int mask;
+Tcl_FileProc *proc;
+ClientData cd;
+{
+ if (exp_fs[fd].channel == NULL) {
+ HANDLE handle;
+ Tcl_Channel chan;
+ struct sockaddr sa;
+ int salen;
+
+ /* Tcl can handle channel events on Windows for
+ sockets and regular files. For pipes we defines
+ our own channel type. FIXME: The channels we
+ create here are never deleted. */
+
+ handle = (HANDLE) get_osfhandle (fd);
+ if (handle == (HANDLE) -1)
+ abort ();
+
+ chan = NULL;
+
+ salen = sizeof sa;
+ if (getsockname (fd, &sa, &salen) == 0)
+ chan = Tcl_MakeTcpClientChannel ((ClientData) handle);
+ else if (GetFileType (handle) != FILE_TYPE_PIPE)
+ chan = Tcl_MakeFileChannel ((ClientData) fd,
+ (TCL_READABLE
+ | TCL_WRITABLE));
+ else {
+ /* We assume that we can always write to a
+ pipe. */
+ if ((mask & TCL_READABLE) == 0)
+ chan = Tcl_MakeFileChannel ((ClientData) fd,
+ mask);
+ else
+ chan = make_pipe_channel (fd, handle);
+ }
+
+ if (chan == NULL)
+ abort ();
+
+ exp_fs[fd].channel = chan;
+ }
+
+ if (exp_fs[fd].fileproc != NULL)
+ Tcl_DeleteChannelHandler (exp_fs[fd].channel,
+ exp_fs[fd].fileproc,
+ exp_fs[fd].procdata);
+
+ Tcl_CreateChannelHandler (exp_fs[fd].channel, mask, proc, cd);
+ exp_fs[fd].fileproc = proc;
+ exp_fs[fd].procdata = cd;
+}
+
+/* Implement Tcl_DeleteFileHandler for cygwin32. */
+
+void
+Tcl_DeleteFileHandler (fd)
+int fd;
+{
+ if (exp_fs[fd].channel != NULL && exp_fs[fd].fileproc != NULL) {
+ Tcl_DeleteChannelHandler (exp_fs[fd].channel,
+ exp_fs[fd].fileproc,
+ exp_fs[fd].procdata);
+ exp_fs[fd].fileproc = NULL;
+ }
+}
+
+#endif
+#endif /* __CYGWIN32__ */
diff --git a/expect/exp_event.h b/expect/exp_event.h
new file mode 100644
index 00000000000..734772e08ad
--- /dev/null
+++ b/expect/exp_event.h
@@ -0,0 +1,19 @@
+/* exp_event.h - event definitions */
+
+int exp_get_next_event _ANSI_ARGS_((Tcl_Interp *,int *, int, int *, int, int));
+int exp_get_next_event_info _ANSI_ARGS_((Tcl_Interp *, int, int));
+int exp_dsleep _ANSI_ARGS_((Tcl_Interp *, double));
+void exp_init_event _ANSI_ARGS_((void));
+
+extern void (*exp_event_exit) _ANSI_ARGS_((Tcl_Interp *));
+
+void exp_event_disarm _ANSI_ARGS_((int));
+
+void exp_arm_background_filehandler _ANSI_ARGS_((int));
+void exp_disarm_background_filehandler _ANSI_ARGS_((int));
+void exp_disarm_background_filehandler_force _ANSI_ARGS_((int));
+void exp_unblock_background_filehandler _ANSI_ARGS_((int));
+void exp_block_background_filehandler _ANSI_ARGS_((int));
+
+void exp_background_filehandler _ANSI_ARGS_((ClientData,int));
+
diff --git a/expect/exp_glob.c b/expect/exp_glob.c
new file mode 100644
index 00000000000..dc04caab2de
--- /dev/null
+++ b/expect/exp_glob.c
@@ -0,0 +1,266 @@
+/* exp_glob.c - expect functions for doing glob
+
+Based on Tcl's glob functions but modified to support anchors and to
+return information about the possibility of future matches
+
+Modifications by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include "expect_cf.h"
+#include "tcl.h"
+#include "exp_int.h"
+
+#if 0
+/* The following functions implement expect's glob-style string matching */
+/* Exp_StringMatch allow's implements the unanchored front (or conversely */
+/* the '^') feature. Exp_StringMatch2 does the rest of the work. */
+int /* returns # of chars that matched */
+Exp_StringMatch(string, pattern,offset)
+char *string;
+char *pattern;
+int *offset; /* offset from beginning of string where pattern matches */
+{
+ char *s;
+ int sm; /* count of chars matched or -1 */
+ int caret = FALSE;
+
+ *offset = 0;
+
+ if (pattern[0] == '^') {
+ caret = TRUE;
+ pattern++;
+ }
+
+ sm = Exp_StringMatch2(string,pattern);
+ if (sm >= 0) return(sm);
+
+ if (caret) return(-1);
+
+ if (pattern[0] == '*') return(-1);
+
+ for (s = string;*s;s++) {
+ sm = Exp_StringMatch2(s,pattern);
+ if (sm != -1) {
+ *offset = s-string;
+ return(sm);
+ }
+ }
+ return(-1);
+}
+#endif
+
+/* The following functions implement expect's glob-style string matching */
+/* Exp_StringMatch allow's implements the unanchored front (or conversely */
+/* the '^') feature. Exp_StringMatch2 does the rest of the work. */
+int /* returns # of chars that matched */
+Exp_StringMatch(string, pattern,offset)
+char *string;
+char *pattern;
+int *offset; /* offset from beginning of string where pattern matches */
+{
+ char *s;
+ int sm; /* count of chars matched or -1 */
+ int caret = FALSE;
+ int star = FALSE;
+
+ *offset = 0;
+
+ if (pattern[0] == '^') {
+ caret = TRUE;
+ pattern++;
+ } else if (pattern[0] == '*') {
+ star = TRUE;
+ }
+
+ /*
+ * test if pattern matches in initial position.
+ * This handles front-anchor and 1st iteration of non-front-anchor.
+ * Note that 1st iteration must be tried even if string is empty.
+ */
+
+ sm = Exp_StringMatch2(string,pattern);
+ if (sm >= 0) return(sm);
+
+ if (caret) return -1;
+ if (star) return -1;
+
+ if (*string == '\0') return -1;
+
+ for (s = string+1;*s;s++) {
+ sm = Exp_StringMatch2(s,pattern);
+ if (sm != -1) {
+ *offset = s-string;
+ return(sm);
+ }
+ }
+ return -1;
+}
+
+/* Exp_StringMatch2 --
+
+Like Tcl_StringMatch except that
+1) returns number of characters matched, -1 if failed.
+ (Can return 0 on patterns like "" or "$")
+2) does not require pattern to match to end of string
+3) much of code is stolen from Tcl_StringMatch
+4) front-anchor is assumed (Tcl_StringMatch retries for non-front-anchor)
+*/
+
+int Exp_StringMatch2(string,pattern)
+ register char *string; /* String. */
+ register char *pattern; /* Pattern, which may contain
+ * special characters. */
+{
+ char c2;
+ int match = 0; /* # of chars matched */
+
+ while (1) {
+ /* If at end of pattern, success! */
+ if (*pattern == 0) {
+ return match;
+ }
+
+ /* If last pattern character is '$', verify that entire
+ * string has been matched.
+ */
+ if ((*pattern == '$') && (pattern[1] == 0)) {
+ if (*string == 0) return(match);
+ else return(-1);
+ }
+
+ /* Check for a "*" as the next pattern character. It matches
+ * any substring. We handle this by calling ourselves
+ * recursively for each postfix of string, until either we
+ * match or we reach the end of the string.
+ */
+
+ if (*pattern == '*') {
+#if 1
+ int head_len;
+ char *tail;
+#endif
+ pattern += 1;
+ if (*pattern == 0) {
+ return(strlen(string)+match); /* DEL */
+ }
+#if 1
+ /* find longest match - switched to this on 12/31/93 */
+ head_len = strlen(string); /* length before tail */
+ tail = string + head_len;
+ while (head_len >= 0) {
+ int rc;
+
+ if (-1 != (rc = Exp_StringMatch2(tail, pattern))) {
+ return rc + match + head_len; /* DEL */
+ }
+ tail--;
+ head_len--;
+ }
+#else
+ /* find shortest match */
+ while (*string != 0) {
+ int rc; /* DEL */
+
+ if (-1 != (rc = Exp_StringMatch2(string, pattern))) {
+ return rc+match; /* DEL */
+ }
+ string += 1;
+ match++; /* DEL */
+ }
+ if (*pattern == '$') return 0; /* handle *$ */
+#endif
+ return -1; /* DEL */
+ }
+
+ /*
+ * after this point, all patterns must match at least one
+ * character, so check this
+ */
+
+ if (*string == 0) return -1;
+
+ /* Check for a "?" as the next pattern character. It matches
+ * any single character.
+ */
+
+ if (*pattern == '?') {
+ goto thisCharOK;
+ }
+
+ /* Check for a "[" as the next pattern character. It is followed
+ * by a list of characters that are acceptable, or by a range
+ * (two characters separated by "-").
+ */
+
+ if (*pattern == '[') {
+ pattern += 1;
+ while (1) {
+ if ((*pattern == ']') || (*pattern == 0)) {
+ return -1; /* was 0; DEL */
+ }
+ if (*pattern == *string) {
+ break;
+ }
+ if (pattern[1] == '-') {
+ c2 = pattern[2];
+ if (c2 == 0) {
+ return -1; /* DEL */
+ }
+ if ((*pattern <= *string) && (c2 >= *string)) {
+ break;
+ }
+ if ((*pattern >= *string) && (c2 <= *string)) {
+ break;
+ }
+ pattern += 2;
+ }
+ pattern += 1;
+ }
+
+/* OOPS! Found a bug in vanilla Tcl - have sent back to Ousterhout */
+/* but he hasn't integrated it yet. - DEL */
+
+#if 0
+ while ((*pattern != ']') && (*pattern != 0)) {
+#else
+ while (*pattern != ']') {
+ if (*pattern == 0) {
+ pattern--;
+ break;
+ }
+#endif
+ pattern += 1;
+ }
+ goto thisCharOK;
+ }
+
+ /* If the next pattern character is backslash, strip it off
+ * so we do exact matching on the character that follows.
+ */
+
+ if (*pattern == '\\') {
+ pattern += 1;
+ if (*pattern == 0) {
+ return -1;
+ }
+ }
+
+ /* There's no special character. Just make sure that the next
+ * characters of each string match.
+ */
+
+ if (*pattern != *string) {
+ return -1;
+ }
+
+ thisCharOK: pattern += 1;
+ string += 1;
+ match++;
+ }
+}
+
diff --git a/expect/exp_int.h b/expect/exp_int.h
new file mode 100644
index 00000000000..6f5aa7a394b
--- /dev/null
+++ b/expect/exp_int.h
@@ -0,0 +1,34 @@
+/* exp_int.h - private symbols common to both expect program and library
+
+Written by: Don Libes, libes@cme.nist.gov, NIST, 12/3/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+#ifndef _EXPECT_INT_H
+#define _EXPECT_INT_H
+
+#ifndef TRUE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#ifndef HAVE_MEMCPY
+#define memcpy(x,y,len) bcopy(y,x,len)
+#endif
+
+#include <errno.h>
+
+int Exp_StringMatch();
+int Exp_StringMatch2();
+void exp_console_set _ANSI_ARGS_((void));
+
+#ifdef NO_STDLIB_H
+# include "../compat/stdlib.h"
+#else
+# include <stdlib.h> /* for malloc */
+#endif /*NO_STDLIB_H*/
+
+#endif /* _EXPECT_INT_H */
diff --git a/expect/exp_inter.c b/expect/exp_inter.c
new file mode 100644
index 00000000000..d57935ad251
--- /dev/null
+++ b/expect/exp_inter.c
@@ -0,0 +1,2256 @@
+/* interact (using select) - give user keyboard control
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include "expect_cf.h"
+#include <stdio.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#include <ctype.h>
+
+#include "tcl.h"
+#include "string.h"
+
+#include "exp_tty_in.h"
+#include "exp_rename.h"
+#include "exp_prog.h"
+#include "exp_command.h"
+#include "exp_log.h"
+#include "exp_tstamp.h" /* remove when timestamp stuff is gone */
+
+#include "tclRegexp.h"
+#include "exp_regexp.h"
+
+extern char *TclGetRegError();
+extern void TclRegError();
+
+#define INTER_OUT "interact_out"
+
+/*
+ * tests if we are running this using a real tty
+ *
+ * these tests are currently only used to control what gets written to the
+ * logfile. Note that removal of the test of "..._is_tty" means that stdin
+ * or stdout could be redirected and yet stdout would still be logged.
+ * However, it's not clear why anyone would use log_file when these are
+ * redirected in the first place. On the other hand, it is reasonable to
+ * run expect as a daemon in which case, stdin/out do not appear to be
+ * ttys, yet it makes sense for them to be logged with log_file as if they
+ * were.
+ */
+#if 0
+#define real_tty_output(x) (exp_stdout_is_tty && (((x)==1) || ((x)==exp_dev_tty)))
+#define real_tty_input(x) (exp_stdin_is_tty && (((x)==0) || ((x)==exp_dev_tty)))
+#endif
+
+#define real_tty_output(x) (((x)==1) || ((x)==exp_dev_tty))
+#define real_tty_input(x) (exp_stdin_is_tty && (((x)==0) || ((x)==exp_dev_tty)))
+
+#define new(x) (x *)ckalloc(sizeof(x))
+
+struct action {
+ char *statement;
+ int tty_reset; /* if true, reset tty mode upon action */
+ int iread; /* if true, reread indirects */
+ int iwrite; /* if true, write spawn_id element */
+ int timestamp; /* if true, generate timestamp */
+ struct action *next; /* chain only for later for freeing */
+};
+
+struct keymap {
+ char *keys; /* original pattern provided by user */
+ regexp *re;
+ int null; /* true if looking to match 0 byte */
+ int case_sensitive;
+ int echo; /* if keystrokes should be echoed */
+ int writethru; /* if keystrokes should go through to process */
+ int indices; /* true if should write indices */
+ struct action action;
+ struct keymap *next;
+};
+
+struct output {
+ struct exp_i *i_list;
+ struct action *action_eof;
+ struct output *next;
+};
+
+struct input {
+ struct exp_i *i_list;
+ struct output *output;
+ struct action *action_eof;
+ struct action *action_timeout;
+ struct keymap *keymap;
+ int timeout_nominal; /* timeout nominal */
+ int timeout_remaining; /* timeout remaining */
+ struct input *next;
+};
+
+static void free_input();
+static void free_keymap();
+static void free_output();
+static void free_action();
+static struct action *new_action();
+static int inter_eval();
+
+/* in_keymap() accepts user keystrokes and returns one of MATCH,
+CANMATCH, or CANTMATCH. These describe whether the keystrokes match a
+key sequence, and could or can't if more characters arrive. The
+function assigns a matching keymap if there is a match or can-match.
+A matching keymap is assigned on can-match so we know whether to echo
+or not.
+
+in_keymap is optimized (if you can call it that) towards a small
+number of key mappings, but still works well for large maps, since no
+function calls are made, and we stop as soon as there is a single-char
+mismatch, and go on to the next one. A hash table or compiled DFA
+probably would not buy very much here for most maps.
+
+The basic idea of how this works is it does a smart sequential search.
+At each position of the input string, we attempt to match each of the
+keymaps. If at least one matches, the first match is returned.
+
+If there is a CANMATCH and there are more keymaps to try, we continue
+trying. If there are no more keymaps to try, we stop trying and
+return with an indication of the first keymap that can match.
+
+Note that I've hacked up the regexp pattern matcher in two ways. One
+is to force the pattern to always be anchored at the front. That way,
+it doesn't waste time attempting to match later in the string (before
+we're ready). The other is to return can-match.
+
+*/
+
+static int
+in_keymap(string,stringlen,keymap,km_match,match_length,skip,rm_nulls)
+char *string;
+int stringlen;
+struct keymap *keymap; /* linked list of keymaps */
+struct keymap **km_match; /* keymap that matches or can match */
+int *match_length; /* # of chars that matched */
+int *skip; /* # of chars to skip */
+int rm_nulls; /* skip nulls if true */
+{
+ struct keymap *km;
+ char *ks; /* string from a keymap */
+ char *start_search; /* where in the string to start searching */
+ char *string_end;
+
+ /* assert (*km == 0) */
+
+ /* a shortcut that should help master output which typically */
+ /* is lengthy and has no key maps. Otherwise it would mindlessly */
+ /* iterate on each character anyway. */
+ if (!keymap) {
+ *skip = stringlen;
+ return(EXP_CANTMATCH);
+ }
+
+ string_end = string + stringlen;
+
+ /* Mark beginning of line for ^ . */
+ regbol = string;
+
+/* skip over nulls - Pascal Meheut, pascal@cnam.cnam.fr 18-May-1993 */
+/* for (start_search = string;*start_search;start_search++) {*/
+ for (start_search = string;start_search<string_end;start_search++) {
+ if (*km_match) break; /* if we've already found a CANMATCH */
+ /* don't bother starting search from positions */
+ /* further along the string */
+
+ for (km=keymap;km;km=km->next) {
+ char *s; /* current character being examined */
+
+ if (km->null) {
+ if (*start_search == 0) {
+ *skip = start_search-string;
+ *match_length = 1; /* s - start_search == 1 */
+ *km_match = km;
+ return(EXP_MATCH);
+ }
+ } else if (!km->re) {
+ /* fixed string */
+ for (s = start_search,ks = km->keys ;;s++,ks++) {
+ /* if we hit the end of this map, must've matched! */
+ if (*ks == 0) {
+ *skip = start_search-string;
+ *match_length = s-start_search;
+ *km_match = km;
+ return(EXP_MATCH);
+ }
+
+ /* if we ran out of user-supplied characters, and */
+ /* still haven't matched, it might match if the user */
+ /* supplies more characters next time */
+
+ if (s == string_end) {
+ /* skip to next key entry, but remember */
+ /* possibility that this entry might match */
+ if (!*km_match) *km_match = km;
+ break;
+ }
+
+ /* if this is a problem for you, use exp_parity command */
+/* if ((*s & 0x7f) == *ks) continue;*/
+ if (*s == *ks) continue;
+ if ((*s == '\0') && rm_nulls) {
+ ks--;
+ continue;
+ }
+ break;
+ }
+ } else {
+ /* regexp */
+ int r; /* regtry status */
+ regexp *prog = km->re;
+
+ /* if anchored, but we're not at beginning, skip pattern */
+ if (prog->reganch) {
+ if (string != start_search) continue;
+ }
+
+ /* known starting char - quick test 'fore lotta work */
+ if (prog->regstart) {
+ /* if this is a problem for you, use exp_parity command */
+/* /* if ((*start_search & 0x7f) != prog->regstart) continue; */
+ if (*start_search != prog->regstart) continue;
+ }
+ r = exp_regtry(prog,start_search,match_length);
+ if (r == EXP_MATCH) {
+ *km_match = km;
+ *skip = start_search-string;
+ return(EXP_MATCH);
+ }
+ if (r == EXP_CANMATCH) {
+ if (!*km_match) *km_match = km;
+ }
+ }
+ }
+ }
+
+ if (*km_match) {
+ /* report a can-match */
+
+ char *p;
+
+ *skip = (start_search-string)-1;
+#if 0
+ *match_length = stringlen - *skip;
+#else
+ /*
+ * there may be nulls in the string in which case
+ * the pattern matchers can report CANMATCH when
+ * the null is hit. So find the null and compute
+ * the length of the possible match.
+ *
+ * Later, after we squeeze out the nulls, we will
+ * retry the match, but for now, go along with
+ * calling it a CANMATCH
+ */
+ p = start_search;
+ while (*p) {
+ p++;
+ }
+ *match_length = (p - start_search) + 1;
+ /*printf(" match_length = %d\n",*match_length);*/
+#endif
+ return(EXP_CANMATCH);
+ }
+
+ *skip = start_search-string;
+ return(EXP_CANTMATCH);
+}
+
+#ifdef SIMPLE_EVENT
+
+/*
+
+The way that the "simple" interact works is that the original Expect
+process reads from the tty and writes to the spawned process. A child
+process is forked to read from the spawned process and write to the
+tty. It looks like this:
+
+ user
+ --> tty >--
+ / \
+ ^ v
+ child original
+ process Expect
+ ^ process
+ | v
+ \ /
+ < spawned <
+ process
+
+*/
+
+
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
+#endif
+
+#include <setjmp.h>
+
+static jmp_buf env; /* for interruptable read() */
+static int reading; /* while we are reading */
+ /* really, while "env" is valid */
+static int deferred_interrupt = FALSE; /* if signal is received, but not */
+ /* in i_read record this here, so it will */
+ /* be handled next time through i_read */
+
+void sigchld_handler()
+{
+ if (reading) longjmp(env,1);
+
+ deferred_interrupt = TRUE;
+}
+
+#define EXP_CHILD_EOF -100
+
+/* interruptable read */
+static int
+i_read(fd,buffer,length)
+int fd;
+char *buffer;
+int length;
+{
+ int cc = EXP_CHILD_EOF;
+
+ if (deferred_interrupt) return(cc);
+
+ if (0 == setjmp(env)) {
+ reading = TRUE;
+ cc = read(fd,buffer,length);
+ }
+ reading = FALSE;
+ return(cc);
+}
+
+/* exit status for the child process created by cmdInteract */
+#define CHILD_DIED -2
+#define SPAWNED_PROCESS_DIED -3
+
+static void
+clean_up_after_child(interp,master)
+Tcl_Interp *interp;
+int master;
+{
+/* should really be recoded using the common wait code in command.c */
+ int status;
+ int pid;
+ int i;
+
+ pid = wait(&status); /* for slave */
+ for (i=0;i<=exp_fd_max;i++) {
+ if (exp_fs[i].pid == pid) {
+ exp_fs[i].sys_waited = TRUE;
+ exp_fs[i].wait = status;
+ }
+ }
+ pid = wait(&status); /* for child */
+ for (i=0;i<=exp_fd_max;i++) {
+ if (exp_fs[i].pid == pid) {
+ exp_fs[i].sys_waited = TRUE;
+ exp_fs[i].wait = status;
+ }
+ }
+
+ deferred_interrupt = FALSE;
+ exp_close(interp,master);
+ master = -1;
+}
+#endif /*SIMPLE_EVENT*/
+
+static int
+update_interact_fds(interp,fd_count,fd_to_input,fd_list,input_base,
+ do_indirect,config_count,real_tty_caller)
+Tcl_Interp *interp;
+int *fd_count;
+struct input ***fd_to_input; /* map from fd's to "struct input"s */
+int **fd_list;
+struct input *input_base;
+int do_indirect; /* if true do indirects */
+int *config_count;
+int *real_tty_caller;
+{
+ struct input *inp;
+ struct output *outp;
+ struct exp_fd_list *fdp;
+ int count;
+
+ int real_tty = FALSE;
+
+ *config_count = exp_configure_count;
+
+ count = 0;
+ for (inp = input_base;inp;inp=inp->next) {
+
+ if (do_indirect) {
+ /* do not update "direct" entries (again) */
+ /* they were updated upon creation */
+ if (inp->i_list->direct == EXP_INDIRECT) {
+ exp_i_update(interp,inp->i_list);
+ }
+ for (outp = inp->output;outp;outp=outp->next) {
+ if (outp->i_list->direct == EXP_INDIRECT) {
+ exp_i_update(interp,outp->i_list);
+ }
+ }
+ }
+
+ /* revalidate all input descriptors */
+ for (fdp = inp->i_list->fd_list;fdp;fdp=fdp->next) {
+ count++;
+ /* have to "adjust" just in case spawn id hasn't had */
+ /* a buffer sized yet */
+ if (!exp_fd2f(interp,fdp->fd,1,1,"interact"))
+ return(TCL_ERROR);
+ }
+
+ /* revalidate all output descriptors */
+ for (outp = inp->output;outp;outp=outp->next) {
+ for (fdp = outp->i_list->fd_list;fdp;fdp=fdp->next) {
+ /* make user_spawn_id point to stdout */
+ if (fdp->fd == 0) {
+ fdp->fd = 1;
+ } else if (fdp->fd == 1) {
+ /* do nothing */
+ } else if (!exp_fd2f(interp,fdp->fd,1,0,"interact"))
+ return(TCL_ERROR);
+ }
+ }
+ }
+ if (!do_indirect) return TCL_OK;
+
+ if (*fd_to_input == 0) {
+ *fd_to_input = (struct input **)ckalloc(
+ (exp_fd_max+1) * sizeof(struct input *));
+ *fd_list = (int *)ckalloc(count * sizeof(int));
+ } else {
+ *fd_to_input = (struct input **)ckrealloc((char *)*fd_to_input,
+ (exp_fd_max+1) * sizeof(struct input *));
+ *fd_list = (int *)ckrealloc((char *)*fd_list,count * sizeof(int));
+ }
+
+ count = 0;
+ for (inp = input_base;inp;inp=inp->next) {
+ for (fdp = inp->i_list->fd_list;fdp;fdp=fdp->next) {
+ /* build map to translate from spawn_id to struct input */
+ (*fd_to_input)[fdp->fd] = inp;
+
+ /* build input to ready() */
+ (*fd_list)[count] = fdp->fd;
+
+ if (real_tty_input(fdp->fd)) real_tty = TRUE;
+
+ count++;
+ }
+ }
+ *fd_count = count;
+
+ *real_tty_caller = real_tty; /* tell caller if we have found that */
+ /* we are using real tty */
+
+ return TCL_OK;
+}
+
+/*ARGSUSED*/
+static char *
+inter_updateproc(clientData, interp, name1, name2, flags)
+ClientData clientData;
+Tcl_Interp *interp; /* Interpreter containing variable. */
+char *name1; /* Name of variable. */
+char *name2; /* Second part of variable name. */
+int flags; /* Information about what happened. */
+{
+ exp_configure_count++;
+ return 0;
+}
+
+#define finish(x) { status = x; goto done; }
+
+static char return_cmd[] = "return";
+static char interpreter_cmd[] = "interpreter";
+
+/*ARGSUSED*/
+int
+Exp_InteractCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ char *arg; /* shorthand for current argv */
+#ifdef SIMPLE_EVENT
+ int pid;
+#endif /*SIMPLE_EVENT*/
+
+ /*declarations*/
+ int input_count; /* count of struct input descriptors */
+ struct input **fd_to_input; /* map from fd's to "struct input"s */
+ int *fd_list;
+ struct keymap *km; /* ptr for above while parsing */
+/* extern char *tclRegexpError; /* declared in tclInt.h */
+ int master = EXP_SPAWN_ID_BAD;
+ char *master_string = 0;/* string representation of master */
+ int need_to_close_master = FALSE; /* if an eof is received */
+ /* we use this to defer close until later */
+
+ int next_tty_reset = FALSE; /* if we've seen a single -reset */
+ int next_iread = FALSE;/* if we've seen a single -iread */
+ int next_iwrite = FALSE;/* if we've seen a single -iread */
+ int next_re = FALSE; /* if we've seen a single -re */
+ int next_null = FALSE; /* if we've seen the null keyword */
+ int next_writethru = FALSE;/*if macros should also go to proc output */
+ int next_indices = FALSE;/* if we should write indices */
+ int next_echo = FALSE; /* if macros should be echoed */
+ int next_timestamp = FALSE; /* if we should generate a timestamp */
+/* int next_case_sensitive = TRUE;*/
+ char **oldargv = 0; /* save original argv here if we split it */
+ int status = TCL_OK; /* final return value */
+ int i; /* trusty temp */
+
+ int timeout_simple = TRUE; /* if no or global timeout */
+
+ int real_tty; /* TRUE if we are interacting with real tty */
+ int tty_changed = FALSE;/* true if we had to change tty modes for */
+ /* interact to work (i.e., to raw, noecho) */
+ int was_raw;
+ int was_echo;
+ exp_tty tty_old;
+
+ char *replace_user_by_process = 0; /* for -u flag */
+
+ struct input *input_base;
+#define input_user input_base
+ struct input *input_default;
+ struct input *inp; /* overused ptr to struct input */
+ struct output *outp; /* overused ptr to struct output */
+
+ int dash_input_count = 0; /* # of "-input"s seen */
+ int arbitrary_timeout;
+ int default_timeout;
+ struct action action_timeout; /* common to all */
+ struct action action_eof; /* common to all */
+ struct action **action_eof_ptr; /* allow -input/ouput to */
+ /* leave their eof-action assignable by a later */
+ /* -eof */
+ struct action *action_base = 0;
+ struct keymap **end_km;
+
+ int key;
+ int configure_count; /* monitor reconfigure events */
+
+ if ((argc == 2) && exp_one_arg_braced(argv[1])) {
+ return(exp_eval_with_one_arg(clientData,interp,argv));
+ } else if ((argc == 3) && streq(argv[1],"-brace")) {
+ char *new_argv[2];
+ new_argv[0] = argv[0];
+ new_argv[1] = argv[2];
+ return(exp_eval_with_one_arg(clientData,interp,new_argv));
+ }
+
+ argv++;
+ argc--;
+
+ default_timeout = EXP_TIME_INFINITY;
+ arbitrary_timeout = EXP_TIME_INFINITY; /* if user specifies */
+ /* a bunch of timeouts with EXP_TIME_INFINITY, this will be */
+ /* left around for us to find. */
+
+ input_user = new(struct input);
+ input_user->i_list = exp_new_i_simple(0,EXP_TEMPORARY); /* stdin by default */
+ input_user->output = 0;
+ input_user->action_eof = &action_eof;
+ input_user->timeout_nominal = EXP_TIME_INFINITY;
+ input_user->action_timeout = 0;
+ input_user->keymap = 0;
+
+ end_km = &input_user->keymap;
+ inp = input_user;
+ action_eof_ptr = &input_user->action_eof;
+
+ input_default = new(struct input);
+ input_default->i_list = exp_new_i_simple(EXP_SPAWN_ID_BAD,EXP_TEMPORARY); /* fix up later */
+ input_default->output = 0;
+ input_default->action_eof = &action_eof;
+ input_default->timeout_nominal = EXP_TIME_INFINITY;
+ input_default->action_timeout = 0;
+ input_default->keymap = 0;
+ input_default->next = 0; /* no one else */
+ input_user->next = input_default;
+
+ /* default and common -eof action */
+ action_eof.statement = return_cmd;
+ action_eof.tty_reset = FALSE;
+ action_eof.iread = FALSE;
+ action_eof.iwrite = FALSE;
+ action_eof.timestamp = FALSE;
+
+ for (;argc>0;argc--,argv++) {
+ arg = *argv;
+ if (exp_flageq("eof",arg,3)) {
+ struct action *action;
+
+ argc--;argv++;
+ *action_eof_ptr = action = new_action(&action_base);
+
+ action->statement = *argv;
+
+ action->tty_reset = next_tty_reset;
+ next_tty_reset = FALSE;
+ action->iwrite = next_iwrite;
+ next_iwrite = FALSE;
+ action->iread = next_iread;
+ next_iread = FALSE;
+ action->timestamp = next_timestamp;
+ next_timestamp = FALSE;
+ continue;
+ } else if (exp_flageq("timeout",arg,7)) {
+ int t;
+ struct action *action;
+
+ argc--;argv++;
+ if (argc < 1) {
+ exp_error(interp,"timeout needs time");
+ return(TCL_ERROR);
+ }
+ t = atoi(*argv);
+ argc--;argv++;
+
+ /* we need an arbitrary timeout to start */
+ /* search for lowest one later */
+ if (t != -1) arbitrary_timeout = t;
+
+ timeout_simple = FALSE;
+ action = inp->action_timeout = new_action(&action_base);
+ inp->timeout_nominal = t;
+
+ action->statement = *argv;
+
+ action->tty_reset = next_tty_reset;
+ next_tty_reset = FALSE;
+ action->iwrite = next_iwrite;
+ next_iwrite = FALSE;
+ action->iread = next_iread;
+ next_iread = FALSE;
+ action->timestamp = next_timestamp;
+ next_timestamp = FALSE;
+ continue;
+ } else if (exp_flageq("null",arg,4)) {
+ next_null = TRUE;
+ } else if (arg[0] == '-') {
+ arg++;
+ if (exp_flageq1('-',arg) /* "--" */
+ || (exp_flageq("exact",arg,3))) {
+ argc--;argv++;
+ } else if (exp_flageq("regexp",arg,2)) {
+ if (argc < 1) {
+ exp_error(interp,"-re needs pattern");
+ return(TCL_ERROR);
+ }
+ next_re = TRUE;
+ argc--;
+ argv++;
+ } else if (exp_flageq("input",arg,2)) {
+ dash_input_count++;
+ if (dash_input_count == 2) {
+ inp = input_default;
+ input_user->next = input_default;
+ } else if (dash_input_count > 2) {
+ struct input *previous_input = inp;
+ inp = new(struct input);
+ previous_input->next = inp;
+ }
+ inp->output = 0;
+ inp->action_eof = &action_eof;
+ action_eof_ptr = &inp->action_eof;
+ inp->timeout_nominal = default_timeout;
+ inp->action_timeout = &action_timeout;
+ inp->keymap = 0;
+ end_km = &inp->keymap;
+ inp->next = 0;
+ argc--;argv++;
+ if (argc < 1) {
+ exp_error(interp,"-input needs argument");
+ return(TCL_ERROR);
+ }
+/* inp->spawn_id = atoi(*argv);*/
+ inp->i_list = exp_new_i_complex(interp,*argv,
+ EXP_TEMPORARY,inter_updateproc);
+ continue;
+ } else if (exp_flageq("output",arg,3)) {
+ struct output *tmp;
+
+ /* imply a "-input" */
+ if (dash_input_count == 0) dash_input_count = 1;
+
+ outp = new(struct output);
+
+ /* link new output in front of others */
+ tmp = inp->output;
+ inp->output = outp;
+ outp->next = tmp;
+
+ argc--;argv++;
+ if (argc < 1) {
+ exp_error(interp,"-output needs argument");
+ return(TCL_ERROR);
+ }
+ outp->i_list = exp_new_i_complex(interp,*argv,
+ EXP_TEMPORARY,inter_updateproc);
+
+ outp->action_eof = &action_eof;
+ action_eof_ptr = &outp->action_eof;
+ continue;
+ } else if (exp_flageq1('u',arg)) { /* treat process as user */
+ argc--;argv++;
+ if (argc < 1) {
+ exp_error(interp,"-u needs argument");
+ return(TCL_ERROR);
+ }
+ replace_user_by_process = *argv;
+
+ /* imply a "-input" */
+ if (dash_input_count == 0) dash_input_count = 1;
+
+ continue;
+ } else if (exp_flageq1('o',arg)) {
+ /* apply following patterns to opposite side */
+ /* of interaction */
+
+ end_km = &input_default->keymap;
+
+ /* imply two "-input" */
+ if (dash_input_count < 2) {
+ dash_input_count = 2;
+ inp = input_default;
+ action_eof_ptr = &inp->action_eof;
+ }
+ continue;
+ } else if (exp_flageq1('i',arg)) {
+ /* substitute master */
+
+ argc--;argv++;
+/* master = atoi(*argv);*/
+ master_string = *argv;
+ /* will be used later on */
+
+ end_km = &input_default->keymap;
+
+ /* imply two "-input" */
+ if (dash_input_count < 2) {
+ dash_input_count = 2;
+ inp = input_default;
+ action_eof_ptr = &inp->action_eof;
+ }
+ continue;
+/* } else if (exp_flageq("nocase",arg,3)) {*/
+/* next_case_sensitive = FALSE;*/
+/* continue;*/
+ } else if (exp_flageq("echo",arg,4)) {
+ next_echo = TRUE;
+ continue;
+ } else if (exp_flageq("nobuffer",arg,3)) {
+ next_writethru = TRUE;
+ continue;
+ } else if (exp_flageq("indices",arg,3)) {
+ next_indices = TRUE;
+ continue;
+ } else if (exp_flageq1('f',arg)) {
+ /* leftover from "fast" days */
+ continue;
+ } else if (exp_flageq("reset",arg,5)) {
+ next_tty_reset = TRUE;
+ continue;
+ } else if (exp_flageq1('F',arg)) {
+ /* leftover from "fast" days */
+ continue;
+ } else if (exp_flageq("iread",arg,2)) {
+ next_iread = TRUE;
+ continue;
+ } else if (exp_flageq("iwrite",arg,2)) {
+ next_iwrite = TRUE;
+ continue;
+ } else if (exp_flageq("eof",arg,3)) {
+ struct action *action;
+
+ argc--;argv++;
+ debuglog("-eof is deprecated, use eof\r\n");
+ *action_eof_ptr = action = new_action(&action_base);
+ action->statement = *argv;
+ action->tty_reset = next_tty_reset;
+ next_tty_reset = FALSE;
+ action->iwrite = next_iwrite;
+ next_iwrite = FALSE;
+ action->iread = next_iread;
+ next_iread = FALSE;
+ action->timestamp = next_timestamp;
+ next_timestamp = FALSE;
+
+ continue;
+ } else if (exp_flageq("timeout",arg,7)) {
+ int t;
+ struct action *action;
+ debuglog("-timeout is deprecated, use timeout\r\n");
+
+ argc--;argv++;
+ if (argc < 1) {
+ exp_error(interp,"-timeout needs time");
+ return(TCL_ERROR);
+ }
+
+ t = atoi(*argv);
+ argc--;argv++;
+ if (t != -1)
+ arbitrary_timeout = t;
+ /* we need an arbitrary timeout to start */
+ /* search for lowest one later */
+
+#if 0
+ /* if -timeout comes before "-input", then applies */
+ /* to all descriptors, else just the current one */
+ if (dash_input_count > 0) {
+ timeout_simple = FALSE;
+ action = inp->action_timeout =
+ new_action(&action_base);
+ inp->timeout_nominal = t;
+ } else {
+ action = &action_timeout;
+ default_timeout = t;
+ }
+#endif
+ timeout_simple = FALSE;
+ action = inp->action_timeout = new_action(&action_base);
+ inp->timeout_nominal = t;
+
+ action->statement = *argv;
+ action->tty_reset = next_tty_reset;
+ next_tty_reset = FALSE;
+ action->iwrite = next_iwrite;
+ next_iwrite = FALSE;
+ action->iread = next_iread;
+ next_iread = FALSE;
+ action->timestamp = next_timestamp;
+ next_timestamp = FALSE;
+ continue;
+ } else if (exp_flageq("timestamp",arg,2)) {
+ debuglog("-timestamp is deprecated, use exp_timestamp command\r\n");
+ next_timestamp = TRUE;
+ continue;
+ } else if (exp_flageq("nobrace",arg,7)) {
+ /* nobrace does nothing but take up space */
+ /* on the command line which prevents */
+ /* us from re-expanding any command lines */
+ /* of one argument that looks like it should */
+ /* be expanded to multiple arguments. */
+ continue;
+ }
+ }
+
+ /*
+ * pick up the pattern
+ */
+
+ km = new(struct keymap);
+
+ /* so that we can match in order user specified */
+ /* link to end of keymap list */
+ *end_km = km;
+ km->next = 0;
+ end_km = &km->next;
+
+ km->echo = next_echo;
+ km->writethru = next_writethru;
+ km->indices = next_indices;
+ km->action.tty_reset = next_tty_reset;
+ km->action.iwrite = next_iwrite;
+ km->action.iread = next_iread;
+ km->action.timestamp = next_timestamp;
+/* km->case_sensitive = next_case_sensitive;*/
+
+ next_indices = next_echo = next_writethru = FALSE;
+ next_tty_reset = FALSE;
+ next_iwrite = next_iread = FALSE;
+/* next_case_sensitive = TRUE;*/
+
+ km->keys = *argv;
+
+ km->null = FALSE;
+ km->re = 0;
+ if (next_re) {
+ TclRegError((char *)0);
+ if (0 == (km->re = TclRegComp(*argv))) {
+ exp_error(interp,"bad regular expression: %s",
+ TclGetRegError());
+ return(TCL_ERROR);
+ }
+ next_re = FALSE;
+ } if (next_null) {
+ km->null = TRUE;
+ next_null = FALSE;
+ }
+
+ argc--;argv++;
+
+ km->action.statement = *argv;
+ debuglog("defining key %s, action %s\r\n",
+ km->keys,
+ km->action.statement?(dprintify(km->action.statement))
+ :interpreter_cmd);
+
+ /* imply a "-input" */
+ if (dash_input_count == 0) dash_input_count = 1;
+ }
+
+ /* if the user has not supplied either "-output" for the */
+ /* default two "-input"s, fix them up here */
+
+ if (!input_user->output) {
+ struct output *o = new(struct output);
+ if (master_string == 0) {
+ if (0 == exp_update_master(interp,&master,1,1)) {
+ return(TCL_ERROR);
+ }
+ o->i_list = exp_new_i_simple(master,EXP_TEMPORARY);
+ } else {
+ o->i_list = exp_new_i_complex(interp,master_string,
+ EXP_TEMPORARY,inter_updateproc);
+ }
+#if 0
+ if (master == EXP_SPAWN_ID_BAD) {
+ if (0 == exp_update_master(interp,&master,1,1)) {
+ return(TCL_ERROR);
+ }
+ }
+ o->i_list = exp_new_i_simple(master,EXP_TEMPORARY);
+#endif
+ o->next = 0; /* no one else */
+ o->action_eof = &action_eof;
+ input_user->output = o;
+ }
+
+ if (!input_default->output) {
+ struct output *o = new(struct output);
+ o->i_list = exp_new_i_simple(1,EXP_TEMPORARY);/* stdout by default */
+ o->next = 0; /* no one else */
+ o->action_eof = &action_eof;
+ input_default->output = o;
+ }
+
+ /* if user has given "-u" flag, substitute process for user */
+ /* in first two -inputs */
+ if (replace_user_by_process) {
+ /* through away old ones */
+ exp_free_i(interp,input_user->i_list, inter_updateproc);
+ exp_free_i(interp,input_default->output->i_list,inter_updateproc);
+
+ /* replace with arg to -u */
+ input_user->i_list = exp_new_i_complex(interp,
+ replace_user_by_process,
+ EXP_TEMPORARY,inter_updateproc);
+ input_default->output->i_list = exp_new_i_complex(interp,
+ replace_user_by_process,
+ EXP_TEMPORARY,inter_updateproc);
+ }
+
+ /*
+ * now fix up for default spawn id
+ */
+
+ /* user could have replaced it with an indirect, so force update */
+ if (input_default->i_list->direct == EXP_INDIRECT) {
+ exp_i_update(interp,input_default->i_list);
+ }
+
+ if (input_default->i_list->fd_list
+ && (input_default->i_list->fd_list->fd == EXP_SPAWN_ID_BAD)) {
+ if (master_string == 0) {
+ if (0 == exp_update_master(interp,&master,1,1)) {
+ return(TCL_ERROR);
+ }
+ input_default->i_list->fd_list->fd = master;
+ } else {
+ /* discard old one and install new one */
+ exp_free_i(interp,input_default->i_list,inter_updateproc);
+ input_default->i_list = exp_new_i_complex(interp,master_string,
+ EXP_TEMPORARY,inter_updateproc);
+ }
+#if 0
+ if (master == EXP_SPAWN_ID_BAD) {
+ if (0 == exp_update_master(interp,&master,1,1)) {
+ return(TCL_ERROR);
+ }
+ }
+ input_default->i_list->fd_list->fd = master;
+#endif
+ }
+
+ /*
+ * check for user attempting to interact with self
+ * they're almost certainly just fooling around
+ */
+
+ /* user could have replaced it with an indirect, so force update */
+ if (input_user->i_list->direct == EXP_INDIRECT) {
+ exp_i_update(interp,input_user->i_list);
+ }
+
+ if (input_user->i_list->fd_list && input_default->i_list->fd_list
+ && (input_user->i_list->fd_list->fd == input_default->i_list->fd_list->fd)) {
+ exp_error(interp,"cannot interact with self - set spawn_id to a spawned process");
+ return(TCL_ERROR);
+ }
+
+ fd_list = 0;
+ fd_to_input = 0;
+
+ /***************************************************************/
+ /* all data structures are sufficiently set up that we can now */
+ /* "finish()" to terminate this procedure */
+ /***************************************************************/
+
+ status = update_interact_fds(interp,&input_count,&fd_to_input,&fd_list,input_base,1,&configure_count,&real_tty);
+ if (status == TCL_ERROR) finish(TCL_ERROR);
+
+ if (real_tty) {
+ tty_changed = exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo);
+ }
+
+ for (inp = input_base,i=0;inp;inp=inp->next,i++) {
+ /* start timers */
+ inp->timeout_remaining = inp->timeout_nominal;
+ }
+
+ key = expect_key++;
+
+ /* declare ourselves "in sync" with external view of close/indirect */
+ configure_count = exp_configure_count;
+
+#ifndef SIMPLE_EVENT
+ /* loop waiting (in event handler) for input */
+ for (;;) {
+ int te; /* result of Tcl_Eval */
+ struct exp_f *u;
+ int rc; /* return code from ready. This is further */
+ /* refined by matcher. */
+ int cc; /* chars count from read() */
+ int m; /* master */
+ int m_out; /* where master echoes to */
+ struct action *action = 0;
+ time_t previous_time;
+ time_t current_time;
+ int match_length, skip;
+ int change; /* if action requires cooked mode */
+ int attempt_match = TRUE;
+ struct input *soonest_input;
+ int print; /* # of chars to print */
+ int oldprinted; /* old version of u->printed */
+
+ int timeout; /* current as opposed to default_timeout */
+
+ /* calculate how long to wait */
+ /* by finding shortest remaining timeout */
+ if (timeout_simple) {
+ timeout = default_timeout;
+ } else {
+ timeout = arbitrary_timeout;
+
+ for (inp=input_base;inp;inp=inp->next) {
+ if ((inp->timeout_remaining != EXP_TIME_INFINITY) &&
+ (inp->timeout_remaining <= timeout)) {
+ soonest_input = inp;
+ timeout = inp->timeout_remaining;
+ }
+ }
+
+ time(&previous_time);
+ /* timestamp here rather than simply saving old */
+ /* current time (after ready()) to account for */
+ /* possibility of slow actions */
+
+ /* timeout can actually be EXP_TIME_INFINITY here if user */
+ /* explicitly supplied it in a few cases (or */
+ /* the count-down code is broken) */
+ }
+
+ /* update the world, if necessary */
+ if (configure_count != exp_configure_count) {
+ status = update_interact_fds(interp,&input_count,
+ &fd_to_input,&fd_list,input_base,1,
+ &configure_count,&real_tty);
+ if (status) finish(status);
+ }
+
+ rc = exp_get_next_event(interp,fd_list,input_count,&m,timeout,key);
+ if (rc == EXP_TCLERROR) return(TCL_ERROR);
+
+ if (rc == EXP_RECONFIGURE) continue;
+
+ if (rc == EXP_TIMEOUT) {
+ if (timeout_simple) {
+ action = &action_timeout;
+ goto got_action;
+ } else {
+ action = soonest_input->action_timeout;
+ /* arbitrarily pick first fd out of list */
+ m = soonest_input->i_list->fd_list->fd;
+ }
+ }
+ if (!timeout_simple) {
+ int time_diff;
+
+ time(&current_time);
+ time_diff = current_time - previous_time;
+
+ /* update all timers */
+ for (inp=input_base;inp;inp=inp->next) {
+ if (inp->timeout_remaining != EXP_TIME_INFINITY) {
+ inp->timeout_remaining -= time_diff;
+ if (inp->timeout_remaining < 0)
+ inp->timeout_remaining = 0;
+ }
+ }
+ }
+
+ /* at this point, we have some kind of event which can be */
+ /* immediately processed - i.e. something that doesn't block */
+
+ /* figure out who we are */
+ inp = fd_to_input[m];
+/* u = inp->f;*/
+ u = exp_fs+m;
+
+ /* reset timer */
+ inp->timeout_remaining = inp->timeout_nominal;
+
+ switch (rc) {
+ case EXP_DATA_NEW:
+ if (u->size == u->msize) {
+ /* In theory, interact could be invoked when this situation */
+ /* already exists, hence the "probably" in the warning below */
+
+ debuglog("WARNING: interact buffer is full, probably because your\r\n");
+ debuglog("patterns have matched all of it but require more chars\r\n");
+ debuglog("in order to complete the match.\r\n");
+ debuglog("Dumping first half of buffer in order to continue\r\n");
+ debuglog("Recommend you enlarge the buffer or fix your patterns.\r\n");
+ exp_buffer_shuffle(interp,u,0,INTER_OUT,"interact");
+ }
+ cc = read(m, u->buffer + u->size,
+ u->msize - u->size);
+ if (cc > 0) {
+ u->key = key;
+ u->size += cc;
+ u->buffer[u->size] = '\0';
+
+ /* strip parity if requested */
+ if (u->parity == 0) {
+ /* do it from end backwards */
+ char *p = u->buffer + u->size - 1;
+ int count = cc;
+ while (count--) {
+ *p-- &= 0x7f;
+ }
+ }
+
+ /* avoid another function call if possible */
+ if (debugfile || is_debugging) {
+ debuglog("spawn id %d sent <%s>\r\n",m,
+ exp_printify(u->buffer + u->size - cc));
+ }
+ break;
+ }
+
+ rc = EXP_EOF;
+ /* Most systems have read() return 0, allowing */
+ /* control to fall thru and into this code. On some */
+ /* systems (currently HP and new SGI), read() does */
+ /* see eof, and it must be detected earlier. Then */
+ /* control jumps directly to this EXP_EOF label. */
+
+ /*FALLTHRU*/
+ case EXP_EOF:
+ action = inp->action_eof;
+ attempt_match = FALSE;
+ skip = u->size;
+ debuglog("interact: received eof from spawn_id %d\r\n",m);
+ /* actual close is done later so that we have a */
+ /* chance to flush out any remaining characters */
+ need_to_close_master = TRUE;
+
+#if EOF_SO
+ /* should really check for remaining chars and */
+ /* flush them but this will only happen in the */
+ /* unlikely scenario that there are partially */
+ /* matched buffered chars. */
+ /* So for now, indicate no chars to skip. */
+ skip = 0;
+ exp_close(interp,m);
+#endif
+ break;
+ case EXP_DATA_OLD:
+ cc = 0;
+ break;
+ case EXP_TIMEOUT:
+ action = inp->action_timeout;
+ attempt_match = FALSE;
+ skip = u->size;
+ break;
+ }
+
+ km = 0;
+
+ if (attempt_match) {
+ rc = in_keymap(u->buffer,u->size,inp->keymap,
+ &km,&match_length,&skip,u->rm_nulls);
+ } else {
+ attempt_match = TRUE;
+ }
+
+ /* put regexp result in variables */
+ if (km && km->re) {
+#define out(var,val) debuglog("expect: set %s(%s) \"%s\"\r\n",INTER_OUT,var, \
+ dprintify(val)); \
+ Tcl_SetVar2(interp,INTER_OUT,var,val,0);
+
+ char name[20], value[20];
+ regexp *re = km->re;
+ char match_char;/* place to hold char temporarily */
+ /* uprooted by a NULL */
+
+ for (i=0;i<NSUBEXP;i++) {
+ int offset;
+
+ if (re->startp[i] == 0) continue;
+
+ if (km->indices) {
+ /* start index */
+ sprintf(name,"%d,start",i);
+ offset = re->startp[i]-u->buffer;
+ sprintf(value,"%d",offset);
+ out(name,value);
+
+ /* end index */
+ sprintf(name,"%d,end",i);
+ sprintf(value,"%d",re->endp[i]-u->buffer-1);
+ out(name,value);
+ }
+
+ /* string itself */
+ sprintf(name,"%d,string",i);
+ /* temporarily null-terminate in */
+ /* middle */
+ match_char = *re->endp[i];
+ *re->endp[i] = 0;
+ out(name,re->startp[i]);
+ *re->endp[i] = match_char;
+ }
+ }
+
+ /*
+ * dispose of chars that should be skipped
+ * i.e., chars that cannot possibly be part of a match.
+ */
+
+ /* "skip" is count of chars not involved in match */
+ /* "print" is count with chars involved in match */
+
+ if (km && km->writethru) {
+ print = skip + match_length;
+ } else print = skip;
+
+ /*
+ * echo chars if appropriate
+ */
+ if (km && km->echo) {
+ int seen; /* either printed or echoed */
+
+ /* echo to stdout rather than stdin */
+ m_out = (m == 0)?1:m;
+
+ /* write is unlikely to fail, since we just read */
+ /* from same descriptor */
+ seen = u->printed + u->echoed;
+ if (skip >= seen) {
+ write(m_out,u->buffer+skip,match_length);
+ } else if ((match_length + skip - seen) > 0) {
+ write(m_out,u->buffer+seen,match_length+skip-seen);
+ }
+ u->echoed = match_length + skip - u->printed;
+ }
+
+ oldprinted = u->printed;
+
+ /* If expect has left characters in buffer, it has */
+ /* already echoed them to the screen, thus we must */
+ /* prevent them being rewritten. Unfortunately this */
+ /* gives the possibility of matching chars that have */
+ /* already been output, but we do so since the user */
+ /* could have avoided it by flushing the output */
+ /* buffers directly. */
+ if (print > u->printed) { /* usual case */
+ int wc; /* return code from write() */
+ for (outp = inp->output;outp;outp=outp->next) {
+ struct exp_fd_list *fdp;
+ for (fdp = outp->i_list->fd_list;fdp;fdp=fdp->next) {
+ int od; /* output descriptor */
+
+ /* send to logfile if open */
+ /* and user is seeing it */
+ if (logfile && real_tty_output(fdp->fd)) {
+ fwrite(u->buffer+u->printed,1,
+ print - u->printed,logfile);
+ }
+
+ /* send to each output descriptor */
+ od = fdp->fd;
+ /* if opened by Tcl, it may use a different */
+ /* output descriptor */
+ od = (exp_fs[od].tcl_handle?exp_fs[od].tcl_output:od);
+
+ wc = write(od,u->buffer+u->printed,
+ print - u->printed);
+ if (wc <= 0) {
+ debuglog("interact: write on spawn id %d failed (%s)\r\n",fdp->fd,Tcl_PosixError(interp));
+ action = outp->action_eof;
+ change = (action && action->tty_reset);
+
+ if (change && tty_changed)
+ exp_tty_set(interp,&tty_old,was_raw,was_echo);
+ te = inter_eval(interp,action,m);
+
+ if (change && real_tty) tty_changed =
+ exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo);
+ switch (te) {
+ case TCL_BREAK:
+ case TCL_CONTINUE:
+ finish(te);
+ case EXP_TCL_RETURN:
+ finish(TCL_RETURN);
+ case TCL_RETURN:
+ finish(TCL_OK);
+ case TCL_OK:
+ /* god knows what the user might */
+ /* have done to us in the way of */
+ /* closed fds, so .... */
+ action = 0; /* reset action */
+ continue;
+ default:
+ finish(te);
+ }
+ }
+ }
+ }
+ u->printed = print;
+ }
+
+ /* u->printed is now accurate with respect to the buffer */
+ /* However, we're about to shift the old data out of the */
+ /* buffer. Thus, u->size, printed, and echoed must be */
+ /* updated */
+
+ /* first update size based on skip information */
+ /* then set skip to the total amount skipped */
+
+ if (rc == EXP_MATCH) {
+ action = &km->action;
+
+ skip += match_length;
+ u->size -= skip;
+
+ if (u->size) {
+ memcpy(u->buffer, u->buffer + skip, u->size);
+ exp_lowmemcpy(u->lower,u->buffer+ skip, u->size);
+ }
+ } else {
+ if (skip) {
+ u->size -= skip;
+ memcpy(u->buffer, u->buffer + skip, u->size);
+ exp_lowmemcpy(u->lower,u->buffer+ skip, u->size);
+ }
+ }
+
+#if EOF_SO
+ /* as long as buffer is still around, null terminate it */
+ if (rc != EXP_EOF) {
+ u->buffer[u->size] = '\0';
+ u->lower [u->size] = '\0';
+ }
+#else
+ u->buffer[u->size] = '\0';
+ u->lower [u->size] = '\0';
+#endif
+
+ /* now update printed based on total amount skipped */
+
+ u->printed -= skip;
+ /* if more skipped than printed (i.e., keymap encountered) */
+ /* for printed positive */
+ if (u->printed < 0) u->printed = 0;
+
+ /* if we are in the middle of a match, force the next event */
+ /* to wait for more data to arrive */
+ u->force_read = (rc == EXP_CANMATCH);
+
+ /* finally reset echoed if necessary */
+ if (rc != EXP_CANMATCH) {
+ if (skip >= oldprinted + u->echoed) u->echoed = 0;
+ }
+
+ if (rc == EXP_EOF) {
+ exp_close(interp,m);
+ need_to_close_master = FALSE;
+ }
+
+ if (action) {
+got_action:
+ change = (action && action->tty_reset);
+ if (change && tty_changed)
+ exp_tty_set(interp,&tty_old,was_raw,was_echo);
+
+ te = inter_eval(interp,action,m);
+
+ if (change && real_tty) tty_changed =
+ exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo);
+ switch (te) {
+ case TCL_BREAK:
+ case TCL_CONTINUE:
+ finish(te);
+ case EXP_TCL_RETURN:
+ finish(TCL_RETURN);
+ case TCL_RETURN:
+ finish(TCL_OK);
+ case TCL_OK:
+ /* god knows what the user might */
+ /* have done to us in the way of */
+ /* closed fds, so .... */
+ action = 0; /* reset action */
+ continue;
+ default:
+ finish(te);
+ }
+ }
+ }
+
+#else /* SIMPLE_EVENT */
+/* deferred_interrupt = FALSE;*/
+{
+ int te; /* result of Tcl_Eval */
+ struct exp_f *u;
+ int rc; /* return code from ready. This is further */
+ /* refined by matcher. */
+ int cc; /* chars count from read() */
+ int m; /* master */
+ struct action *action = 0;
+ time_t previous_time;
+ time_t current_time;
+ int match_length, skip;
+ int change; /* if action requires cooked mode */
+ int attempt_match = TRUE;
+ struct input *soonest_input;
+ int print; /* # of chars to print */
+ int oldprinted; /* old version of u->printed */
+
+ int timeout; /* current as opposed to default_timeout */
+
+ if (-1 == (pid = fork())) {
+ exp_error(interp,"fork: %s",Tcl_PosixError(interp));
+ finish(TCL_ERROR);
+ }
+ if (pid == 0) { /* child - send process output to user */
+ exp_close(interp,0);
+
+ m = fd_list[1]; /* get 2nd fd */
+ input_count = 1;
+
+ while (1) {
+
+ /* calculate how long to wait */
+ /* by finding shortest remaining timeout */
+ if (timeout_simple) {
+ timeout = default_timeout;
+ } else {
+ timeout = arbitrary_timeout;
+
+ for (inp=input_base;inp;inp=inp->next) {
+ if ((inp->timeout_remaining != EXP_TIME_INFINITY) &&
+ (inp->timeout_remaining < timeout))
+ soonest_input = inp;
+ timeout = inp->timeout_remaining;
+ }
+
+ time(&previous_time);
+ /* timestamp here rather than simply saving old */
+ /* current time (after ready()) to account for */
+ /* possibility of slow actions */
+
+ /* timeout can actually be EXP_TIME_INFINITY here if user */
+ /* explicitly supplied it in a few cases (or */
+ /* the count-down code is broken) */
+ }
+
+ /* +1 so we can look at the "other" file descriptor */
+ rc = exp_get_next_event(interp,fd_list+1,input_count,&m,timeout,key);
+ if (!timeout_simple) {
+ int time_diff;
+
+ time(&current_time);
+ time_diff = current_time - previous_time;
+
+ /* update all timers */
+ for (inp=input_base;inp;inp=inp->next) {
+ if (inp->timeout_remaining != EXP_TIME_INFINITY) {
+ inp->timeout_remaining -= time_diff;
+ if (inp->timeout_remaining < 0)
+ inp->timeout_remaining = 0;
+ }
+ }
+ }
+
+ /* at this point, we have some kind of event which can be */
+ /* immediately processed - i.e. something that doesn't block */
+
+ /* figure out who we are */
+ inp = fd_to_input[m];
+/* u = inp->f;*/
+ u = exp_fs+m;
+
+ switch (rc) {
+ case EXP_DATA_NEW:
+ cc = read(m, u->buffer + u->size,
+ u->msize - u->size);
+ if (cc > 0) {
+ u->key = key;
+ u->size += cc;
+ u->buffer[u->size] = '\0';
+
+ /* strip parity if requested */
+ if (u->parity == 0) {
+ /* do it from end backwards */
+ char *p = u->buffer + u->size - 1;
+ int count = cc;
+ while (count--) {
+ *p-- &= 0x7f;
+ }
+ }
+
+ /* avoid another function call if possible */
+ if (debugfile || is_debugging) {
+ debuglog("spawn id %d sent <%s>\r\n",m,
+ exp_printify(u->buffer + u->size - cc));
+ }
+ break;
+ }
+ /*FALLTHRU*/
+
+ /* Most systems have read() return 0, allowing */
+ /* control to fall thru and into this code. On some */
+ /* systems (currently HP and new SGI), read() does */
+ /* see eof, and it must be detected earlier. Then */
+ /* control jumps directly to this EXP_EOF label. */
+ case EXP_EOF:
+ action = inp->action_eof;
+ attempt_match = FALSE;
+ skip = u->size;
+ rc = EXP_EOF;
+ debuglog("interact: child received eof from spawn_id %d\r\n",m);
+ exp_close(interp,m);
+ break;
+ case EXP_DATA_OLD:
+ cc = 0;
+ break;
+ }
+
+ km = 0;
+
+ if (attempt_match) {
+ rc = in_keymap(u->buffer,u->size,inp->keymap,
+ &km,&match_length,&skip);
+ } else {
+ attempt_match = TRUE;
+ }
+
+ /* put regexp result in variables */
+ if (km && km->re) {
+#define INTER_OUT "interact_out"
+#define out(i,val) debuglog("expect: set %s(%s) \"%s\"\r\n",INTER_OUT,i, \
+ dprintify(val)); \
+ Tcl_SetVar2(interp,INTER_OUT,i,val,0);
+
+ char name[20], value[20];
+ regexp *re = km->re;
+ char match_char;/* place to hold char temporarily */
+ /* uprooted by a NULL */
+
+ for (i=0;i<NSUBEXP;i++) {
+ int offset;
+
+ if (re->startp[i] == 0) continue;
+
+ if (km->indices) {
+ /* start index */
+ sprintf(name,"%d,start",i);
+ offset = re->startp[i]-u->buffer;
+ sprintf(value,"%d",offset);
+ out(name,value);
+
+ /* end index */
+ sprintf(name,"%d,end",i);
+ sprintf(value,"%d",re->endp[i]-u->buffer-1);
+ out(name,value);
+ }
+
+ /* string itself */
+ sprintf(name,"%d,string",i);
+ /* temporarily null-terminate in */
+ /* middle */
+ match_char = *re->endp[i];
+ *re->endp[i] = 0;
+ out(name,re->startp[i]);
+ *re->endp[i] = match_char;
+ }
+ }
+
+ /* dispose of chars that should be skipped */
+
+ /* skip is chars not involved in match */
+ /* print is with chars involved in match */
+
+ if (km && km->writethru) {
+ print = skip + match_length;
+ } else print = skip;
+
+ /* figure out if we should echo any chars */
+ if (km && km->echo) {
+ int seen; /* either printed or echoed */
+
+ /* echo to stdout rather than stdin */
+ if (m == 0) m = 1;
+
+ /* write is unlikely to fail, since we just read */
+ /* from same descriptor */
+ seen = u->printed + u->echoed;
+ if (skip >= seen) {
+ write(m,u->buffer+skip,match_length);
+ } else if ((match_length + skip - seen) > 0) {
+ write(m,u->buffer+seen,match_length+skip-seen);
+ }
+ u->echoed = match_length + skip - u->printed;
+ }
+
+ oldprinted = u->printed;
+
+ /* If expect has left characters in buffer, it has */
+ /* already echoed them to the screen, thus we must */
+ /* prevent them being rewritten. Unfortunately this */
+ /* gives the possibility of matching chars that have */
+ /* already been output, but we do so since the user */
+ /* could have avoided it by flushing the output */
+ /* buffers directly. */
+ if (print > u->printed) { /* usual case */
+ int wc; /* return code from write() */
+ for (outp = inp->output;outp;outp=outp->next) {
+ struct exp_fd_list *fdp;
+ for (fdp = outp->i_list->fd_list;fdp;fdp=fdp->next) {
+ int od; /* output descriptor */
+
+ /* send to logfile if open */
+ /* and user is seeing it */
+ if (logfile && real_tty_output(fdp->fd)) {
+ fwrite(u->buffer+u->printed,1,
+ print - u->printed,logfile);
+ }
+
+ /* send to each output descriptor */
+ od = fdp->fd;
+ /* if opened by Tcl, it may use a different */
+ /* output descriptor */
+ od = (exp_fs[od].tcl_handle?exp_fs[od].tcl_output:od);
+
+ wc = write(od,u->buffer+u->printed,
+ print - u->printed);
+ if (wc <= 0) {
+ debuglog("interact: write on spawn id %d failed (%s)\r\n",fdp->fd,Tcl_PosixError(interp));
+ action = outp->action_eof;
+
+ te = inter_eval(interp,action,m);
+
+ switch (te) {
+ case TCL_BREAK:
+ case TCL_CONTINUE:
+ finish(te);
+ case EXP_TCL_RETURN:
+ finish(TCL_RETURN);
+ case TCL_RETURN:
+ finish(TCL_OK);
+ case TCL_OK:
+ /* god knows what the user might */
+ /* have done to us in the way of */
+ /* closed fds, so .... */
+ action = 0; /* reset action */
+ continue;
+ default:
+ finish(te);
+ }
+ }
+ }
+ }
+ u->printed = print;
+ }
+
+ /* u->printed is now accurate with respect to the buffer */
+ /* However, we're about to shift the old data out of the */
+ /* buffer. Thus, u->size, printed, and echoed must be */
+ /* updated */
+
+ /* first update size based on skip information */
+ /* then set skip to the total amount skipped */
+
+ if (rc == EXP_MATCH) {
+ action = &km->action;
+
+ skip += match_length;
+ u->size -= skip;
+
+ if (u->size)
+ memcpy(u->buffer, u->buffer + skip, u->size);
+ exp_lowmemcpy(u->lower,u->buffer+ skip, u->size);
+ } else {
+ if (skip) {
+ u->size -= skip;
+ memcpy(u->buffer, u->buffer + skip, u->size);
+ exp_lowmemcpy(u->lower,u->buffer+ skip, u->size);
+ }
+ }
+
+ /* as long as buffer is still around, null terminate it */
+ if (rc != EXP_EOF) {
+ u->buffer[u->size] = '\0';
+ u->lower [u->size] = '\0';
+ }
+ /* now update printed based on total amount skipped */
+
+ u->printed -= skip;
+ /* if more skipped than printed (i.e., keymap encountered) */
+ /* for printed positive */
+ if (u->printed < 0) u->printed = 0;
+
+ /* if we are in the middle of a match, force the next event */
+ /* to wait for more data to arrive */
+ u->force_read = (rc == EXP_CANMATCH);
+
+ /* finally reset echoed if necessary */
+ if (rc != EXP_CANMATCH) {
+ if (skip >= oldprinted + u->echoed) u->echoed = 0;
+ }
+
+ if (action) {
+ te = inter_eval(interp,action,m);
+ switch (te) {
+ case TCL_BREAK:
+ case TCL_CONTINUE:
+ finish(te);
+ case EXP_TCL_RETURN:
+ finish(TCL_RETURN);
+ case TCL_RETURN:
+ finish(TCL_OK);
+ case TCL_OK:
+ /* god knows what the user might */
+ /* have done to us in the way of */
+ /* closed fds, so .... */
+ action = 0; /* reset action */
+ continue;
+ default:
+ finish(te);
+ }
+ }
+ }
+ } else { /* parent - send user keystrokes to process */
+#include <signal.h>
+
+#if defined(SIGCLD) && !defined(SIGCHLD)
+#define SIGCHLD SIGCLD
+#endif
+ debuglog("fork = %d\r\n",pid);
+ signal(SIGCHLD,sigchld_handler);
+/* restart:*/
+/* tty_changed = exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo);*/
+
+ m = fd_list[0]; /* get 1st fd */
+ input_count = 1;
+
+ while (1) {
+ /* calculate how long to wait */
+ /* by finding shortest remaining timeout */
+ if (timeout_simple) {
+ timeout = default_timeout;
+ } else {
+ timeout = arbitrary_timeout;
+
+ for (inp=input_base;inp;inp=inp->next) {
+ if ((inp->timeout_remaining != EXP_TIME_INFINITY) &&
+ (inp->timeout_remaining < timeout))
+ soonest_input = inp;
+ timeout = inp->timeout_remaining;
+ }
+
+ time(&previous_time);
+ /* timestamp here rather than simply saving old */
+ /* current time (after ready()) to account for */
+ /* possibility of slow actions */
+
+ /* timeout can actually be EXP_TIME_INFINITY here if user */
+ /* explicitly supplied it in a few cases (or */
+ /* the count-down code is broken) */
+ }
+
+ rc = exp_get_next_event(interp,fd_list,input_count,&m,timeout,key);
+ if (!timeout_simple) {
+ int time_diff;
+
+ time(&current_time);
+ time_diff = current_time - previous_time;
+
+ /* update all timers */
+ for (inp=input_base;inp;inp=inp->next) {
+ if (inp->timeout_remaining != EXP_TIME_INFINITY) {
+ inp->timeout_remaining -= time_diff;
+ if (inp->timeout_remaining < 0)
+ inp->timeout_remaining = 0;
+ }
+ }
+ }
+
+ /* at this point, we have some kind of event which can be */
+ /* immediately processed - i.e. something that doesn't block */
+
+ /* figure out who we are */
+ inp = fd_to_input[m];
+/* u = inp->f;*/
+ u = exp_fs+m;
+
+ switch (rc) {
+ case EXP_DATA_NEW:
+ cc = i_read(m, u->buffer + u->size,
+ u->msize - u->size);
+ if (cc > 0) {
+ u->key = key;
+ u->size += cc;
+ u->buffer[u->size] = '\0';
+
+ /* strip parity if requested */
+ if (u->parity == 0) {
+ /* do it from end backwards */
+ char *p = u->buffer + u->size - 1;
+ int count = cc;
+ while (count--) {
+ *p-- &= 0x7f;
+ }
+ }
+
+ /* avoid another function call if possible */
+ if (debugfile || is_debugging) {
+ debuglog("spawn id %d sent <%s>\r\n",m,
+ exp_printify(u->buffer + u->size - cc));
+ }
+ break;
+ } else if (cc == EXP_CHILD_EOF) {
+ /* user could potentially have two outputs in which */
+ /* case we might be looking at the wrong one, but */
+ /* the likelihood of this is nil */
+ action = inp->output->action_eof;
+ attempt_match = FALSE;
+ skip = u->size;
+ rc = EXP_EOF;
+ debuglog("interact: process died/eof\r\n");
+ clean_up_after_child(interp,fd_list[1]);
+ break;
+ }
+ /*FALLTHRU*/
+
+ /* Most systems have read() return 0, allowing */
+ /* control to fall thru and into this code. On some */
+ /* systems (currently HP and new SGI), read() does */
+ /* see eof, and it must be detected earlier. Then */
+ /* control jumps directly to this EXP_EOF label. */
+ case EXP_EOF:
+ action = inp->action_eof;
+ attempt_match = FALSE;
+ skip = u->size;
+ rc = EXP_EOF;
+ debuglog("user sent EOF or disappeared\n\n");
+ break;
+ case EXP_DATA_OLD:
+ cc = 0;
+ break;
+ }
+
+ km = 0;
+
+ if (attempt_match) {
+ rc = in_keymap(u->buffer,u->size,inp->keymap,
+ &km,&match_length,&skip);
+ } else {
+ attempt_match = TRUE;
+ }
+
+ /* put regexp result in variables */
+ if (km && km->re) {
+ char name[20], value[20];
+ regexp *re = km->re;
+ char match_char;/* place to hold char temporarily */
+ /* uprooted by a NULL */
+
+ for (i=0;i<NSUBEXP;i++) {
+ int offset;
+
+ if (re->startp[i] == 0) continue;
+
+ if (km->indices) {
+ /* start index */
+ sprintf(name,"%d,start",i);
+ offset = re->startp[i]-u->buffer;
+ sprintf(value,"%d",offset);
+ out(name,value);
+
+ /* end index */
+ sprintf(name,"%d,end",i);
+ sprintf(value,"%d",re->endp[i]-u->buffer-1);
+ out(name,value);
+ }
+
+ /* string itself */
+ sprintf(name,"%d,string",i);
+ /* temporarily null-terminate in */
+ /* middle */
+ match_char = *re->endp[i];
+ *re->endp[i] = 0;
+ out(name,re->startp[i]);
+ *re->endp[i] = match_char;
+ }
+ }
+
+ /* dispose of chars that should be skipped */
+
+ /* skip is chars not involved in match */
+ /* print is with chars involved in match */
+
+ if (km && km->writethru) {
+ print = skip + match_length;
+ } else print = skip;
+
+ /* figure out if we should echo any chars */
+ if (km && km->echo) {
+ int seen; /* either printed or echoed */
+
+ /* echo to stdout rather than stdin */
+ if (m == 0) m = 1;
+
+ /* write is unlikely to fail, since we just read */
+ /* from same descriptor */
+ seen = u->printed + u->echoed;
+ if (skip >= seen) {
+ write(m,u->buffer+skip,match_length);
+ } else if ((match_length + skip - seen) > 0) {
+ write(m,u->buffer+seen,match_length+skip-seen);
+ }
+ u->echoed = match_length + skip - u->printed;
+ }
+
+ oldprinted = u->printed;
+
+ /* If expect has left characters in buffer, it has */
+ /* already echoed them to the screen, thus we must */
+ /* prevent them being rewritten. Unfortunately this */
+ /* gives the possibility of matching chars that have */
+ /* already been output, but we do so since the user */
+ /* could have avoided it by flushing the output */
+ /* buffers directly. */
+ if (print > u->printed) { /* usual case */
+ int wc; /* return code from write() */
+ for (outp = inp->output;outp;outp=outp->next) {
+ struct exp_fd_list *fdp;
+ for (fdp = outp->i_list->fd_list;fdp;fdp=fdp->next) {
+ int od; /* output descriptor */
+
+ /* send to logfile if open */
+ /* and user is seeing it */
+ if (logfile && real_tty_output(fdp->fd)) {
+ fwrite(u->buffer+u->printed,1,
+ print - u->printed,logfile);
+ }
+
+ /* send to each output descriptor */
+ od = fdp->fd;
+ /* if opened by Tcl, it may use a different */
+ /* output descriptor */
+ od = (exp_fs[od].tcl_handle?exp_fs[od].tcl_output:od);
+
+ wc = write(od,u->buffer+u->printed,
+ print - u->printed);
+ if (wc <= 0) {
+ debuglog("interact: write on spawn id %d failed (%s)\r\n",fdp->fd,Tcl_PosixError(interp));
+ clean_up_after_child(interp,fdp->fd);
+ action = outp->action_eof;
+ change = (action && action->tty_reset);
+ if (change && tty_changed)
+ exp_tty_set(interp,&tty_old,was_raw,was_echo);
+ te = inter_eval(interp,action,m);
+
+ if (change && real_tty) tty_changed =
+ exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo);
+ switch (te) {
+ case TCL_BREAK:
+ case TCL_CONTINUE:
+ finish(te);
+ case EXP_TCL_RETURN:
+ finish(TCL_RETURN);
+ case TCL_RETURN:
+ finish(TCL_OK);
+ case TCL_OK:
+ /* god knows what the user might */
+ /* have done to us in the way of */
+ /* closed fds, so .... */
+ action = 0; /* reset action */
+ continue;
+ default:
+ finish(te);
+ }
+ }
+ }
+ }
+ u->printed = print;
+ }
+
+ /* u->printed is now accurate with respect to the buffer */
+ /* However, we're about to shift the old data out of the */
+ /* buffer. Thus, u->size, printed, and echoed must be */
+ /* updated */
+
+ /* first update size based on skip information */
+ /* then set skip to the total amount skipped */
+
+ if (rc == EXP_MATCH) {
+ action = &km->action;
+
+ skip += match_length;
+ u->size -= skip;
+
+ if (u->size)
+ memcpy(u->buffer, u->buffer + skip, u->size);
+ exp_lowmemcpy(u->lower,u->buffer+ skip, u->size);
+ } else {
+ if (skip) {
+ u->size -= skip;
+ memcpy(u->buffer, u->buffer + skip, u->size);
+ exp_lowmemcpy(u->lower,u->buffer+ skip, u->size);
+ }
+ }
+
+ /* as long as buffer is still around, null terminate it */
+ if (rc != EXP_EOF) {
+ u->buffer[u->size] = '\0';
+ u->lower [u->size] = '\0';
+ }
+ /* now update printed based on total amount skipped */
+
+ u->printed -= skip;
+ /* if more skipped than printed (i.e., keymap encountered) */
+ /* for printed positive */
+ if (u->printed < 0) u->printed = 0;
+
+ /* if we are in the middle of a match, force the next event */
+ /* to wait for more data to arrive */
+ u->force_read = (rc == EXP_CANMATCH);
+
+ /* finally reset echoed if necessary */
+ if (rc != EXP_CANMATCH) {
+ if (skip >= oldprinted + u->echoed) u->echoed = 0;
+ }
+
+ if (action) {
+ change = (action && action->tty_reset);
+ if (change && tty_changed)
+ exp_tty_set(interp,&tty_old,was_raw,was_echo);
+
+ te = inter_eval(interp,action,m);
+
+ if (change && real_tty) tty_changed =
+ exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo);
+ switch (te) {
+ case TCL_BREAK:
+ case TCL_CONTINUE:
+ finish(te);
+ case EXP_TCL_RETURN:
+ finish(TCL_RETURN);
+ case TCL_RETURN:
+ finish(TCL_OK);
+ case TCL_OK:
+ /* god knows what the user might */
+ /* have done to us in the way of */
+ /* closed fds, so .... */
+ action = 0; /* reset action */
+ continue;
+ default:
+ finish(te);
+ }
+ }
+ }
+ }
+}
+#endif /* SIMPLE_EVENT */
+
+ done:
+#ifdef SIMPLE_EVENT
+ /* force child to exit upon eof from master */
+ if (pid == 0) {
+ exit(SPAWNED_PROCESS_DIED);
+ }
+#endif /* SIMPLE_EVENT */
+
+ if (need_to_close_master) exp_close(interp,master);
+
+ if (tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo);
+ if (oldargv) ckfree((char *)argv);
+ if (fd_list) ckfree((char *)fd_list);
+ if (fd_to_input) ckfree((char *)fd_to_input);
+ free_input(interp,input_base);
+ free_action(action_base);
+
+ return(status);
+}
+
+/* version of Tcl_Eval for interact */
+static int
+inter_eval(interp,action,spawn_id)
+Tcl_Interp *interp;
+struct action *action;
+int spawn_id;
+{
+ int status;
+ char value[20];
+
+ /* deprecated */
+ if (action->timestamp) {
+ time_t current_time;
+ time(&current_time);
+ exp_timestamp(interp,&current_time,INTER_OUT);
+ }
+ /* deprecated */
+
+ if (action->iwrite) {
+ sprintf(value,"%d",spawn_id);
+ out("spawn_id",value);
+ }
+
+ if (action->statement) {
+ status = Tcl_Eval(interp,action->statement);
+ } else {
+ exp_nflog("\r\n",1);
+ status = exp_interpreter(interp);
+ }
+
+ return status;
+}
+
+static void
+free_keymap(km)
+struct keymap *km;
+{
+ if (km == 0) return;
+ free_keymap(km->next);
+
+ ckfree((char *)km);
+}
+
+static void
+free_action(a)
+struct action *a;
+{
+ struct action *next;
+
+ while (a) {
+ next = a->next;
+ ckfree((char *)a);
+ a = next;
+ }
+}
+
+static void
+free_input(interp,i)
+Tcl_Interp *interp;
+struct input *i;
+{
+ if (i == 0) return;
+ free_input(interp,i->next);
+
+ exp_free_i(interp,i->i_list,inter_updateproc);
+ free_output(interp,i->output);
+ free_keymap(i->keymap);
+ ckfree((char *)i);
+}
+
+static struct action *
+new_action(base)
+struct action **base;
+{
+ struct action *o = new(struct action);
+
+ /* stick new action into beginning of list of all actions */
+ o->next = *base;
+ *base = o;
+
+ return o;
+}
+
+static void
+free_output(interp,o)
+Tcl_Interp *interp;
+struct output *o;
+{
+ if (o == 0) return;
+ free_output(interp,o->next);
+ exp_free_i(interp,o->i_list,inter_updateproc);
+
+ ckfree((char *)o);
+}
+
+static struct exp_cmd_data cmd_data[] = {
+{"interact", exp_proc(Exp_InteractCmd), 0, 0},
+{0}};
+
+void
+exp_init_interact_cmds(interp)
+Tcl_Interp *interp;
+{
+ exp_create_commands(interp,cmd_data);
+}
diff --git a/expect/exp_log.c b/expect/exp_log.c
new file mode 100644
index 00000000000..b09a828755b
--- /dev/null
+++ b/expect/exp_log.c
@@ -0,0 +1,261 @@
+/* exp_log.c - logging routines and other things common to both Expect
+ program and library. Note that this file must NOT have any
+ references to Tcl except for including tclInt.h
+*/
+
+#include "expect_cf.h"
+#include <stdio.h>
+/*#include <varargs.h> tclInt.h drags in varargs.h. Since Pyramid */
+/* objects to including varargs.h twice, just */
+/* omit this one. */
+#include "tclInt.h"
+#include "expect_comm.h"
+#include "exp_int.h"
+#include "exp_rename.h"
+#include "exp_log.h"
+
+int loguser = TRUE; /* if TRUE, expect/spawn may write to stdout */
+int logfile_all = FALSE; /* if TRUE, write log of all interactions */
+ /* despite value of loguser. */
+FILE *logfile = 0;
+FILE *debugfile = 0;
+int exp_is_debugging = FALSE;
+
+/* Following this are several functions that log the conversation. */
+/* Most of them have multiple calls to printf-style functions. */
+/* At first glance, it seems stupid to reformat the same arguments again */
+/* but we have no way of telling how long the formatted output will be */
+/* and hence cannot allocate a buffer to do so. */
+/* Fortunately, in production code, most of the duplicate reformatting */
+/* will be skipped, since it is due to handling errors and debugging. */
+
+/* send to log if open */
+/* send to stderr if debugging enabled */
+/* use this for logging everything but the parent/child conversation */
+/* (this turns out to be almost nothing) */
+/* uppercase L differentiates if from math function of same name */
+#define LOGUSER (loguser || force_stdout)
+/*VARARGS*/
+void
+exp_log TCL_VARARGS_DEF(int,arg1)
+/*exp_log(va_alist)*/
+/*va_dcl*/
+{
+ int force_stdout;
+ char *fmt;
+ va_list args;
+
+ force_stdout = TCL_VARARGS_START(int,arg1,args);
+ /*va_start(args);*/
+ /*force_stdout = va_arg(args,int);*/
+ fmt = va_arg(args,char *);
+ if (debugfile) vfprintf(debugfile,fmt,args);
+ if (logfile_all || (LOGUSER && logfile)) vfprintf(logfile,fmt,args);
+ if (LOGUSER) vfprintf(stdout,fmt,args);
+ va_end(args);
+}
+
+/* just like log but does no formatting */
+/* send to log if open */
+/* use this function for logging the parent/child conversation */
+void
+exp_nflog(buf,force_stdout)
+char *buf;
+int force_stdout; /* override value of loguser */
+{
+ int length = strlen(buf);
+
+ if (debugfile) fwrite(buf,1,length,debugfile);
+ if (logfile_all || (LOGUSER && logfile)) fwrite(buf,1,length,logfile);
+ if (LOGUSER) fwrite(buf,1,length,stdout);
+#if 0
+ if (logfile_all || (LOGUSER && logfile)) {
+ int newlength = exp_copy_out(length);
+ fwrite(exp_out_buffer,1,newlength,logfile);
+ }
+#endif
+}
+#undef LOGUSER
+
+/* send to log if open and debugging enabled */
+/* send to stderr if debugging enabled */
+/* use this function for recording unusual things in the log */
+/*VARARGS*/
+void
+debuglog TCL_VARARGS_DEF(char *,arg1)
+/*debuglog(va_alist)*/
+/*va_dcl*/
+{
+ char *fmt;
+ va_list args;
+
+ fmt = TCL_VARARGS_START(char *,arg1,args);
+ /*va_start(args);*/
+ /*fmt = va_arg(args,char *);*/
+ if (debugfile) vfprintf(debugfile,fmt,args);
+ if (is_debugging) {
+ vfprintf(stderr,fmt,args);
+ if (logfile) vfprintf(logfile,fmt,args);
+ }
+
+ va_end(args);
+}
+
+/* send to log if open */
+/* send to stderr */
+/* use this function for error conditions */
+/*VARARGS*/
+void
+exp_errorlog TCL_VARARGS_DEF(char *,arg1)
+/*exp_errorlog(va_alist)*/
+/*va_dcl*/
+{
+ char *fmt;
+ va_list args;
+
+ fmt = TCL_VARARGS_START(char *,arg1,args);
+ /*va_start(args);*/
+ /*fmt = va_arg(args,char *);*/
+ vfprintf(stderr,fmt,args);
+ if (debugfile) vfprintf(debugfile,fmt,args);
+ if (logfile) vfprintf(logfile,fmt,args);
+ va_end(args);
+}
+
+/* just like errorlog but does no formatting */
+/* send to log if open */
+/* use this function for logging the parent/child conversation */
+/*ARGSUSED*/
+void
+exp_nferrorlog(buf,force_stdout)
+char *buf;
+int force_stdout; /* not used, only declared here for compat with */
+ /* exp_nflog() */
+{
+ int length = strlen(buf);
+ fwrite(buf,1,length,stderr);
+ if (debugfile) fwrite(buf,1,length,debugfile);
+ if (logfile) fwrite(buf,1,length,logfile);
+}
+
+#if 0
+static int out_buffer_size;
+static char *outp_last;
+static char *out_buffer;
+static char *outp; /* pointer into out_buffer - static in order */
+ /* to update whenever out_buffer is enlarged */
+
+
+void
+exp_init_log()
+{
+ out_buffer = ckalloc(BUFSIZ);
+ out_buffer_size = BUFSIZ;
+ outp_last = out_buffer + BUFSIZ - 1;
+}
+
+char *
+enlarge_out_buffer()
+{
+ int offset = outp - out_buffer;
+
+ int new_out_buffer_size = out_buffer_size = BUFSIZ;
+ realloc(out_buffer,new_out_buffer_size);
+
+ out_buffer_size = new_out_buffer_size;
+ outp = out_buffer + offset;
+
+ outp_last = out_buffer + out_buffer_size - 1;
+
+ return(out_buffer);
+}
+
+/* like sprintf, but uses a static buffer enlarged as necessary */
+/* currently supported are %s, %d, and %#d where # is a single-digit */
+void
+exp_sprintf TCL_VARARGS_DEF(char *,arg1)
+/* exp_sprintf(va_alist)*/
+/*va_dcl*/
+{
+ char *fmt;
+ va_list args;
+ char int_literal[20]; /* big enough for an int literal? */
+ char *int_litp; /* pointer into int_literal */
+ char *width;
+ char *string_arg;
+ int int_arg;
+ char *int_fmt;
+
+ fmt = TCL_VARARGS_START(char *,arg1,args);
+ /*va_start(args);*/
+ /*fmt = va_arg(args,char *);*/
+
+ while (*fmt != '\0') {
+ if (*fmt != '%') {
+ *outp++ = *fmt++;
+ continue;
+ }
+
+ /* currently, only single-digit widths are used */
+ if (isdigit(*fmt)) {
+ width = fmt++;
+ } else width = 0;
+
+ switch (*fmt) {
+ case 's': /* interpolate string */
+ string_arg = va_arg(args,char *);
+
+ while (*string_arg) {
+ if (outp == outp_last) {
+ if (enlarge_out_buffer() == 0) {
+ /* FAIL */
+ return;
+ }
+ }
+ *outp++ = *string_arg++;
+ }
+ fmt++;
+ break;
+ case 'd': /* interpolate int */
+ int_arg = va_arg(args,int);
+
+ if (width) int_fmt = width;
+ else int_fmt = fmt;
+
+ sprintf(int_literal,int_fmt,int_arg);
+
+ int_litp = int_literal;
+ for (int_litp;*int_litp;) {
+ if (enlarge_out_buffer() == 0) return;
+ *outp++ = *int_litp++;
+ }
+ fmt++;
+ break;
+ default: /* anything else is literal */
+ if (enlarge_out_buffer() == 0) return; /* FAIL */
+ *outp++ = *fmt++;
+ break;
+ }
+ }
+}
+
+/* copy input string to exp_output, replacing \r\n sequences by \n */
+/* return length of new string */
+int
+exp_copy_out(char *s)
+{
+ outp = out_buffer;
+ int count = 0;
+
+ while (*s) {
+ if ((*s == '\r') && (*(s+1) =='\n')) s++;
+ if (enlarge_out_buffer() == 0) {
+ /* FAIL */
+ break;
+ }
+ *outp = *s;
+ count++;
+ }
+ return count;
+}
+#endif
diff --git a/expect/exp_log.h b/expect/exp_log.h
new file mode 100644
index 00000000000..88b39957e54
--- /dev/null
+++ b/expect/exp_log.h
@@ -0,0 +1,28 @@
+/* exp_log.h */
+
+#include "exp_printify.h"
+
+/* special version of log for non-null-terminated strings which */
+/* never need printf-style formatting. */
+#define logn(buf,length) { \
+ if (logfile) fwrite(buf,1,length,logfile); \
+ if (debugfile) fwrite(buf,1,length,debugfile); \
+ }
+
+#define dprintify(x) ((is_debugging || debugfile)?exp_printify(x):0)
+/* in circumstances where "debuglog(printify(...))" is written, call */
+/* dprintify instead. This will avoid doing any formatting that would */
+/* occur before debuglog got control and decided not to do anything */
+/* because (is_debugging || debugfile) was false. */
+
+extern void exp_errorlog _ANSI_ARGS_(TCL_VARARGS(char *,fmt));
+extern void exp_log _ANSI_ARGS_(TCL_VARARGS(int,force_stdout));
+extern void exp_debuglog _ANSI_ARGS_(TCL_VARARGS(char *,fmt));
+extern void exp_nflog _ANSI_ARGS_((char *buf, int force_stdout));
+extern void exp_nferrorlog _ANSI_ARGS_((char *buf, int force_stdout));
+
+extern FILE *debugfile;
+extern FILE *logfile;
+extern int logfile_all;
+
+extern int is_debugging; /* useful to know for avoid debug calls */
diff --git a/expect/exp_main_exp.c b/expect/exp_main_exp.c
new file mode 100644
index 00000000000..48c92a3655f
--- /dev/null
+++ b/expect/exp_main_exp.c
@@ -0,0 +1,60 @@
+/* main.c - main() and some logging routines for expect
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+#include "expect_cf.h"
+#include <stdio.h>
+#include "tcl.h"
+#ifdef USE_ITCL
+#include "itcl.h"
+#endif
+#include "expect_tcl.h"
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int rc = 0;
+ Tcl_Interp *interp = Tcl_CreateInterp();
+
+ /* need this for [info nameofexecutable] to work */
+ Tcl_FindExecutable (argv[0]);
+
+ if (Tcl_Init(interp) == TCL_ERROR) {
+ fprintf(stderr,"Tcl_Init failed: %s\n",interp->result);
+ exit(1);
+ }
+ if (Expect_Init(interp) == TCL_ERROR) {
+ fprintf(stderr,"Expect_Init failed: %s\n",interp->result);
+ exit(1);
+ }
+
+#ifdef USE_ITCL
+ if (Itcl_Init(interp) == TCL_ERROR) {
+ fprintf(stderr,"Itcl_Init failed: %s\n",interp->result);
+ exit(1);
+ }
+#endif
+ exp_parse_argv(interp,argc,argv);
+
+ /* become interactive if requested or "nothing to do" */
+ if (exp_interactive)
+ (void) exp_interpreter(interp);
+ else if (exp_cmdfile)
+ rc = exp_interpret_cmdfile(interp,exp_cmdfile);
+ else if (exp_cmdfilename)
+ rc = exp_interpret_cmdfilename(interp,exp_cmdfilename);
+
+ /* assert(exp_cmdlinecmds != 0) */
+
+ exp_exit(interp,rc);
+ /*NOTREACHED*/
+ return 0; /* Needed only to prevent compiler warning. */
+}
+
diff --git a/expect/exp_main_sub.c b/expect/exp_main_sub.c
new file mode 100644
index 00000000000..32e00c0d7a4
--- /dev/null
+++ b/expect/exp_main_sub.c
@@ -0,0 +1,892 @@
+/* exp_main_sub.c - miscellaneous subroutines for Expect or Tk main() */
+
+#include "expect_cf.h"
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#include <sys/types.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#include "tcl.h"
+#include "tclInt.h"
+#include "exp_rename.h"
+#include "exp_prog.h"
+#include "exp_command.h"
+#include "exp_tty_in.h"
+#include "exp_log.h"
+#include "exp_event.h"
+#ifdef TCL_DEBUGGER
+#include "Dbg.h"
+#endif
+
+#ifdef __CENTERLINE__
+#undef EXP_VERSION
+#define EXP_VERSION "5.0.3" /* I give up! */
+ /* It is not necessary that number */
+ /* be accurate. It is just here to */
+ /* pacify Centerline which doesn't */
+ /* seem to be able to get it from */
+ /* the Makefile. */
+#undef SCRIPTDIR
+#define SCRIPTDIR "example/"
+#undef EXECSCRIPTDIR
+#define EXECSCRIPTDIR "example/"
+#endif
+char exp_version[] = EXP_VERSION;
+#define NEED_TCL_MAJOR 7
+#define NEED_TCL_MINOR 5
+
+char *exp_argv0 = "this program"; /* default program name */
+void (*exp_app_exit)() = 0;
+void (*exp_event_exit)() = 0;
+FILE *exp_cmdfile = 0;
+char *exp_cmdfilename = 0;
+int exp_cmdlinecmds = FALSE;
+int exp_interactive = FALSE;
+int exp_buffer_command_input = FALSE;/* read in entire cmdfile at once */
+int exp_fgets();
+
+Tcl_Interp *exp_interp; /* for use by signal handlers who can't figure out */
+ /* the interpreter directly */
+int exp_tcl_debugger_available = FALSE;
+
+int exp_getpid;
+
+static void
+usage(interp)
+Tcl_Interp *interp;
+{
+ errorlog("usage: expect [-div] [-c cmds] [[-f] cmdfile] [args]\r\n");
+ exp_exit(interp,1);
+}
+
+/*ARGSUSED*/
+void
+exp_exit(interp,status)
+Tcl_Interp *interp; /* historic */
+int status;
+{
+ Tcl_Exit(status);
+}
+
+/* this clumsiness because pty routines don't know Tcl definitions */
+static
+void
+exp_pty_exit_for_tcl(clientData)
+ClientData clientData;
+{
+ exp_pty_exit();
+}
+
+static
+void
+exp_init_pty_exit()
+{
+ Tcl_CreateExitHandler(exp_pty_exit_for_tcl,(ClientData)0);
+}
+
+/* This can be called twice or even recursively - it's safe. */
+void
+exp_exit_handlers(clientData)
+ClientData clientData;
+{
+ extern int exp_forked;
+
+ Tcl_Interp *interp = (Tcl_Interp *)clientData;
+
+ /* use following checks to prevent recursion in exit handlers */
+ /* if this code ever supports multiple interps, these should */
+ /* become interp-specific */
+
+ static int did_app_exit = FALSE;
+ static int did_expect_exit = FALSE;
+
+ /* don't think this code is relevant any longer, but not positive! */
+ if (!interp) {
+ /* if no interp handy (i.e., called from interrupt handler) */
+ /* use last one created - it's a hack but we're exiting */
+ /* ungracefully to begin with */
+ interp = exp_interp;
+ }
+
+ if (!did_expect_exit) {
+ did_expect_exit = TRUE;
+ /* called user-defined exit routine if one exists */
+ if (exp_onexit_action) {
+ int result = Tcl_GlobalEval(interp,exp_onexit_action);
+ if (result != TCL_OK) Tcl_BackgroundError(interp);
+ }
+ } else {
+ debuglog("onexit handler called recursively - forcing exit\r\n");
+ }
+
+ if (exp_app_exit) {
+ if (!did_app_exit) {
+ did_app_exit = TRUE;
+ (*exp_app_exit)(interp);
+ } else {
+ debuglog("application exit handler called recursively - forcing exit\r\n");
+ }
+ }
+
+ if (!exp_disconnected
+ && !exp_forked
+ && (exp_dev_tty != -1)
+ && isatty(exp_dev_tty)
+ && exp_ioctled_devtty) {
+ exp_tty_set(interp,&exp_tty_original,exp_dev_tty,0);
+ }
+ /* all other files either don't need to be flushed or will be
+ implicitly closed at exit. Spawned processes are free to continue
+ running, however most will shutdown after seeing EOF on stdin.
+ Some systems also deliver SIGHUP and other sigs to idle processes
+ which will blow them away if not prepared.
+ */
+
+ exp_close_all(interp);
+}
+
+static int
+history_nextid(interp)
+Tcl_Interp *interp;
+{
+ Interp *iPtr = (Interp *)interp;
+
+#if TCL_MAJOR_VERSION < 8
+ return iPtr->curEventNum+1;
+#else
+ /* unncessarily tricky coding - if nextid isn't defined,
+ maintain our own static version */
+
+ static int nextid = 0;
+ char *nextidstr = Tcl_GetVar2(interp,"tcl::history","nextid",0);
+ if (nextidstr) {
+ /* intentionally ignore failure */
+ (void) sscanf(nextidstr,"%d",&nextid);
+ }
+ return ++nextid;
+#endif
+}
+
+/* this stupidity because Tcl needs commands in writable space */
+static char prompt1[] = "prompt1";
+static char prompt2[] = "prompt2";
+
+static char *prompt2_default = "+> ";
+static char prompt1_default[] = "expect%d.%d> ";
+
+/*ARGSUSED*/
+int
+Exp_Prompt1Cmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ Interp *iPtr = (Interp *)interp;
+
+ sprintf(interp->result,prompt1_default,
+ iPtr->numLevels,history_nextid(interp));
+ return(TCL_OK);
+}
+
+/*ARGSUSED*/
+int
+Exp_Prompt2Cmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ strcpy(interp->result,prompt2_default);
+ return(TCL_OK);
+}
+
+/*ARGSUSED*/
+static int
+ignore_procs(interp,s)
+Tcl_Interp *interp;
+char *s; /* function name */
+{
+ return ((s[0] == 'p') &&
+ (s[1] == 'r') &&
+ (s[2] == 'o') &&
+ (s[3] == 'm') &&
+ (s[4] == 'p') &&
+ (s[5] == 't') &&
+ ((s[6] == '1') ||
+ (s[6] == '2')) &&
+ (s[7] == '\0')
+ );
+}
+
+/* handle an error from Tcl_Eval or Tcl_EvalFile */
+static void
+handle_eval_error(interp,check_for_nostack)
+Tcl_Interp *interp;
+int check_for_nostack;
+{
+ char *msg;
+
+ /* if errorInfo has something, print it */
+ /* else use what's in interp->result */
+
+ msg = Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY);
+ if (!msg) msg = interp->result;
+ else if (check_for_nostack) {
+ /* suppress errorInfo if generated via */
+ /* error ... -nostack */
+ if (0 == strncmp("-nostack",msg,8)) return;
+
+ /*
+ * This shouldn't be necessary, but previous test fails
+ * because of recent change John made - see eval_trap_action()
+ * in exp_trap.c for more info
+ */
+ if (exp_nostack_dump) {
+ exp_nostack_dump = FALSE;
+ return;
+ }
+ }
+
+ /* no \n at end, since ccmd will already have one. */
+ /* Actually, this is not true if command is last in */
+ /* file and has no newline after it, oh well */
+ errorlog("%s\r\n",exp_cook(msg,(int *)0));
+}
+
+/* user has pressed escape char from interact or somehow requested expect.
+If a user-supplied command returns:
+
+TCL_ERROR, assume user is experimenting and reprompt
+TCL_OK, ditto
+TCL_RETURN, return TCL_OK (assume user just wants to escape() to return)
+EXP_TCL_RETURN, return TCL_RETURN
+anything else return it
+*/
+int
+exp_interpreter(interp)
+Tcl_Interp *interp;
+{
+ int rc;
+ char *ccmd; /* pointer to complete command */
+ char line[BUFSIZ+1]; /* space for partial command */
+ int newcmd = TRUE;
+ Tcl_DString dstring;
+ Interp *iPtr = (Interp *)interp;
+ int tty_changed = FALSE;
+
+ exp_tty tty_old;
+ int was_raw, was_echo;
+
+ int dummy;
+ Tcl_Channel outChannel;
+ int fd = fileno(stdin);
+
+ expect_key++;
+
+ Tcl_DStringInit(&dstring);
+
+ newcmd = TRUE;
+ while (TRUE) {
+ outChannel = Tcl_GetStdChannel(TCL_STDOUT);
+ if (outChannel) {
+ Tcl_Flush(outChannel);
+ }
+
+ /* force terminal state */
+ tty_changed = exp_tty_cooked_echo(interp,&tty_old,&was_raw,&was_echo);
+
+ if (newcmd) {
+ rc = Tcl_Eval(interp,prompt1);
+ if (rc == TCL_OK) exp_log(1,"%s",interp->result);
+ else exp_log(1,prompt1_default,iPtr->numLevels,
+ history_nextid(interp));
+ } else {
+ rc = Tcl_Eval(interp,prompt2);
+ if (rc == TCL_OK) exp_log(1,"%s",interp->result);
+ else exp_log(1,prompt2_default,1);
+ }
+
+ exp_fs[fd].force_read = 1;
+ rc = exp_get_next_event(interp,&fd,1,&dummy,EXP_TIME_INFINITY,
+ exp_fs[fd].key);
+ /* check for rc == EXP_TCLERROR? */
+
+ if (rc != EXP_EOF) {
+ rc = read(0,line,BUFSIZ);
+#ifdef SIMPLE_EVENT
+ if (rc == -1 && errno == EINTR) {
+ if (Tcl_AsyncReady()) {
+ (void) Tcl_AsyncInvoke(interp,TCL_OK);
+ }
+ continue;
+ }
+#endif
+ if (rc <= 0) {
+ if (!newcmd) line[0] = 0;
+ else rc = EXP_EOF;
+ } else line[rc] = '\0';
+ }
+
+ if (rc == EXP_EOF) exp_exit(interp,0);
+
+ if (debugfile) fwrite(line,1,strlen(line),debugfile);
+ /* intentionally always write to logfile */
+ if (logfile) fwrite(line,1,strlen(line),logfile);
+ /* no need to write to stdout, since they will see */
+ /* it just from it having been echoed as they are */
+ /* typing it */
+
+ ccmd = Tcl_DStringAppend(&dstring,line,rc);
+ if (!Tcl_CommandComplete(ccmd)) {
+ newcmd = FALSE;
+ continue; /* continue collecting command */
+ }
+ newcmd = TRUE;
+
+ if (tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo);
+
+ rc = Tcl_RecordAndEval(interp,ccmd,0);
+ Tcl_DStringFree(&dstring);
+ switch (rc) {
+ case TCL_OK:
+ if (*interp->result != 0)
+ exp_log(1,"%s\r\n",exp_cook(interp->result,(int *)0));
+ continue;
+ case TCL_ERROR:
+ handle_eval_error(interp,1);
+ /* since user is typing by hand, we expect lots */
+ /* of errors, and want to give another chance */
+ continue;
+#define finish(x) {rc = x; goto done;}
+ case TCL_BREAK:
+ case TCL_CONTINUE:
+ finish(rc);
+ case EXP_TCL_RETURN:
+ finish(TCL_RETURN);
+ case TCL_RETURN:
+ finish(TCL_OK);
+ default:
+ /* note that ccmd has trailing newline */
+ errorlog("error %d: %s\r\n",rc,ccmd);
+ continue;
+ }
+ }
+ /* cannot fall thru here, must jump to label */
+ done:
+ if (tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo);
+
+ Tcl_DStringFree(&dstring);
+
+ return(rc);
+}
+
+/*ARGSUSED*/
+int
+Exp_ExpVersionCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int emajor, umajor;
+ char *user_version; /* user-supplied version string */
+
+ if (argc == 1) {
+ Tcl_SetResult(interp,exp_version,TCL_STATIC);
+ return(TCL_OK);
+ }
+ if (argc > 3) {
+ exp_error(interp,"usage: expect_version [[-exit] version]");
+ return(TCL_ERROR);
+ }
+
+ user_version = argv[argc==2?1:2];
+ emajor = atoi(exp_version);
+ umajor = atoi(user_version);
+
+ /* first check major numbers */
+ if (emajor == umajor) {
+ int u, e;
+
+ /* now check minor numbers */
+ char *dot = strchr(user_version,'.');
+ if (!dot) {
+ exp_error(interp,"version number must include a minor version number");
+ return TCL_ERROR;
+ }
+
+ u = atoi(dot+1);
+ dot = strchr(exp_version,'.');
+ e = atoi(dot+1);
+ if (e >= u) return(TCL_OK);
+ }
+
+ if (argc == 2) {
+ exp_error(interp,"%s requires Expect version %s (but using %s)",
+ exp_argv0,user_version,exp_version);
+ return(TCL_ERROR);
+ }
+ errorlog("%s: requires Expect version %s (but using %s)\r\n",
+ exp_argv0,user_version,exp_version);
+ exp_exit(interp,1);
+ /*NOTREACHED*/
+}
+
+static char init_auto_path[] = "lappend auto_path $exp_library $exp_exec_library";
+
+int
+Expect_Init(interp)
+Tcl_Interp *interp;
+{
+ static int first_time = TRUE;
+
+ if (first_time) {
+ int tcl_major = atoi(TCL_VERSION);
+ char *dot = strchr(TCL_VERSION,'.');
+ int tcl_minor = atoi(dot+1);
+
+ if (tcl_major < NEED_TCL_MAJOR ||
+ (tcl_major == NEED_TCL_MAJOR && tcl_minor < NEED_TCL_MINOR)) {
+ sprintf(interp->result,
+ "%s compiled with Tcl %d.%d but needs at least Tcl %d.%d\n",
+ exp_argv0,tcl_major,tcl_minor,
+ NEED_TCL_MAJOR,NEED_TCL_MINOR);
+ return TCL_ERROR;
+ }
+
+ if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) {
+ return TCL_ERROR;
+ }
+ if (Tcl_PkgProvide(interp, "Expect", EXP_VERSION) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ exp_getpid = getpid();
+ exp_init_pty();
+ exp_init_pty_exit();
+ exp_init_tty(); /* do this only now that we have looked at */
+ /* original tty state */
+ exp_init_stdio();
+ exp_init_sig();
+ exp_init_event();
+ exp_init_trap();
+ exp_init_unit_random();
+ exp_init_spawn_ids();
+
+ Tcl_CreateExitHandler(exp_exit_handlers,(ClientData)interp);
+
+ first_time = FALSE;
+ }
+
+ /* save last known interp for emergencies */
+ exp_interp = interp;
+
+ /* initialize commands */
+ exp_init_most_cmds(interp); /* add misc cmds to interpreter */
+ exp_init_expect_cmds(interp); /* add expect cmds to interpreter */
+ exp_init_main_cmds(interp); /* add main cmds to interpreter */
+ exp_init_trap_cmds(interp); /* add trap cmds to interpreter */
+ exp_init_tty_cmds(interp); /* add tty cmds to interpreter */
+ exp_init_interact_cmds(interp); /* add interact cmds to interpreter */
+
+ exp_init_spawn_id_vars(interp);
+
+ Tcl_SetVar(interp,"expect_library",SCRIPTDIR,0);/* deprecated */
+ Tcl_SetVar(interp,"exp_library",SCRIPTDIR,0);
+ Tcl_SetVar(interp,"exp_exec_library",EXECSCRIPTDIR,0);
+ Tcl_Eval(interp,init_auto_path);
+ Tcl_ResetResult(interp);
+
+#ifdef TCL_DEBUGGER
+ Dbg_IgnoreFuncs(interp,ignore_procs);
+#endif
+
+ return TCL_OK;
+}
+
+static char sigexit_init_default[] = "trap exit {SIGINT SIGTERM}";
+static char debug_init_default[] = "trap {exp_debug 1} SIGINT";
+
+void
+exp_parse_argv(interp,argc,argv)
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ char argc_rep[10]; /* enough space for storing literal rep of argc */
+
+ int sys_rc = TRUE; /* read system rc file */
+ int my_rc = TRUE; /* read personal rc file */
+
+ int c;
+ int rc;
+
+ extern int optind;
+ extern char *optarg;
+ char *args; /* ptr to string-rep of all args */
+ char *debug_init;
+
+ exp_argv0 = argv[0];
+
+#ifdef TCL_DEBUGGER
+ Dbg_ArgcArgv(argc,argv,1);
+#endif
+
+ /* initially, we must assume we are not interactive */
+ /* this prevents interactive weirdness courtesy of unknown via -c */
+ /* after handling args, we can change our mind */
+ Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
+
+ Tcl_Eval(interp,sigexit_init_default);
+
+ while ((c = getopt(argc, argv, "b:c:dD:f:inN-v")) != EOF) {
+ switch(c) {
+ case '-':
+ /* getopt already handles -- internally, however */
+ /* this allows us to abort getopt when dash is at */
+ /* the end of another option which is required */
+ /* in order to allow things like -n- on #! line */
+ goto abort_getopt;
+ case 'c': /* command */
+ exp_cmdlinecmds = TRUE;
+ rc = Tcl_Eval(interp,optarg);
+ if (rc != TCL_OK) {
+ errorlog("%s\r\n",exp_cook(Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY),(int *)0));
+ }
+ break;
+ case 'd': exp_is_debugging = TRUE;
+ debuglog("expect version %s\r\n",exp_version);
+ break;
+#ifdef TCL_DEBUGGER
+ case 'D':
+ exp_tcl_debugger_available = TRUE;
+ if (Tcl_GetInt(interp,optarg,&rc) != TCL_OK) {
+ errorlog("%s: -D argument must be 0 or 1\r\n",
+ exp_argv0);
+ exp_exit(interp,1);
+ }
+
+ /* set up trap handler before Dbg_On so user does */
+ /* not have to see it at first debugger prompt */
+ if (0 == (debug_init = getenv("EXPECT_DEBUG_INIT"))) {
+ debug_init = debug_init_default;
+ }
+ Tcl_Eval(interp,debug_init);
+ if (rc == 1) Dbg_On(interp,0);
+ break;
+#endif
+ case 'f': /* name of cmd file */
+ exp_cmdfilename = optarg;
+ break;
+ case 'b': /* read cmdfile one part at a time */
+ exp_cmdfilename = optarg;
+ exp_buffer_command_input = TRUE;
+ break;
+ case 'i': /* interactive */
+ exp_interactive = TRUE;
+ break;
+ case 'n': /* don't read personal rc file */
+ my_rc = FALSE;
+ break;
+ case 'N': /* don't read system-wide rc file */
+ sys_rc = FALSE;
+ break;
+ case 'v':
+ printf("expect version %s\n", exp_version);
+ exp_exit (interp, 0);
+ break;
+ default: usage(interp);
+ }
+ }
+
+ abort_getopt:
+
+ for (c = 0;c<argc;c++) {
+ debuglog("argv[%d] = %s ",c,argv[c]);
+ }
+ debuglog("\r\n");
+
+ /* if user hasn't explicitly requested we be interactive */
+ /* look for a file or some other source of commands */
+ if (!exp_interactive) {
+ /* get cmd file name, if we haven't got it already */
+ if (!exp_cmdfilename && (optind < argc)) {
+ exp_cmdfilename = argv[optind];
+ optind++;
+ }
+
+ if (exp_cmdfilename) {
+ if (streq(exp_cmdfilename,"-")) {
+ exp_cmdfile = stdin;
+ exp_cmdfilename = 0;
+ } else if (exp_buffer_command_input) {
+ errno = 0;
+ exp_cmdfile = fopen(exp_cmdfilename,"r");
+ if (exp_cmdfile) {
+ exp_cmdfilename = 0;
+ exp_close_on_exec(fileno(exp_cmdfile));
+ } else {
+ char *msg;
+
+ if (errno == 0) {
+ msg = "could not read - odd file name?";
+ } else {
+ msg = Tcl_ErrnoMsg(errno);
+ }
+ errorlog("%s: %s\r\n",exp_cmdfilename,msg);
+ exp_exit(interp,1);
+ }
+ }
+ } else if (!exp_cmdlinecmds) {
+ if (isatty(0)) {
+ /* no other source of commands, force interactive */
+ exp_interactive = TRUE;
+ } else {
+ /* read cmds from redirected stdin */
+ exp_cmdfile = stdin;
+ }
+ }
+ }
+
+ if (exp_interactive) {
+ Tcl_SetVar(interp, "tcl_interactive","1",TCL_GLOBAL_ONLY);
+ }
+
+ /* collect remaining args and make into argc, argv0, and argv */
+ sprintf(argc_rep,"%d",argc-optind);
+ Tcl_SetVar(interp,"argc",argc_rep,0);
+ debuglog("set argc %s\r\n",argc_rep);
+
+ if (exp_cmdfilename) {
+ Tcl_SetVar(interp,"argv0",exp_cmdfilename,0);
+ debuglog("set argv0 \"%s\"\r\n",exp_cmdfilename);
+ } else {
+ Tcl_SetVar(interp,"argv0",exp_argv0,0);
+ debuglog("set argv0 \"%s\"\r\n",exp_argv0);
+ }
+
+ args = Tcl_Merge(argc-optind,argv+optind);
+ debuglog("set argv \"%s\"\r\n",args);
+ Tcl_SetVar(interp,"argv",args,0);
+ ckfree(args);
+
+ exp_interpret_rcfiles(interp,my_rc,sys_rc);
+}
+
+/* read rc files */
+void
+exp_interpret_rcfiles(interp,my_rc,sys_rc)
+Tcl_Interp *interp;
+int my_rc;
+int sys_rc;
+{
+ int rc;
+
+ if (sys_rc) {
+ char file[200];
+ int fd;
+
+ sprintf(file,"%s/expect.rc",SCRIPTDIR);
+ if (-1 != (fd = open(file,0))) {
+ if (TCL_ERROR == (rc = Tcl_EvalFile(interp,file))) {
+ errorlog("error executing system initialization file: %s\r\n",file);
+ if (rc != TCL_ERROR)
+ errorlog("Tcl_Eval = %d\r\n",rc);
+ if (*interp->result != 0)
+ errorlog("%s\r\n",interp->result);
+ exp_exit(interp,1);
+ }
+ close(fd);
+ }
+ }
+ if (my_rc) {
+ char file[200];
+ char *home;
+ int fd;
+ char *getenv();
+
+ if ((NULL != (home = getenv("DOTDIR"))) ||
+ (NULL != (home = getenv("HOME")))) {
+ sprintf(file,"%s/.expect.rc",home);
+ if (-1 != (fd = open(file,0))) {
+ if (TCL_ERROR == (rc = Tcl_EvalFile(interp,file))) {
+ errorlog("error executing file: %s\r\n",file);
+ if (rc != TCL_ERROR)
+ errorlog("Tcl_Eval = %d\r\n",rc);
+ if (*interp->result != 0)
+ errorlog("%s\r\n",interp->result);
+ exp_exit(interp,1);
+ }
+ close(fd);
+ }
+ }
+ }
+}
+
+int
+exp_interpret_cmdfilename(interp,filename)
+Tcl_Interp *interp;
+char *filename;
+{
+ int rc;
+
+ debuglog("executing commands from command file %s\r\n",filename);
+
+ Tcl_ResetResult(interp);
+ if (TCL_OK != (rc = Tcl_EvalFile(interp,filename))) {
+ /* EvalFile doesn't bother to copy error to errorInfo */
+ /* so force it */
+ Tcl_AddErrorInfo(interp, "");
+ handle_eval_error(interp,0);
+ }
+ return rc;
+}
+
+int
+exp_interpret_cmdfile(interp,fp)
+Tcl_Interp *interp;
+FILE *fp;
+{
+ int rc = 0;
+ int newcmd;
+ int eof;
+
+ Tcl_DString dstring;
+ Tcl_DStringInit(&dstring);
+
+ debuglog("executing commands from command file\r\n");
+
+ newcmd = TRUE;
+ eof = FALSE;
+ while (1) {
+ char line[BUFSIZ];/* buffer for partial Tcl command */
+ char *ccmd; /* pointer to complete Tcl command */
+
+ if (fgets(line,BUFSIZ,fp) == NULL) {
+ if (newcmd) break;
+ eof = TRUE;
+ }
+ ccmd = Tcl_DStringAppend(&dstring,line,-1);
+ if (!Tcl_CommandComplete(ccmd) && !eof) {
+ newcmd = FALSE;
+ continue; /* continue collecting command */
+ }
+ newcmd = TRUE;
+
+ rc = Tcl_Eval(interp,ccmd);
+ Tcl_DStringFree(&dstring);
+ if (rc != TCL_OK) {
+ handle_eval_error(interp,0);
+ break;
+ }
+ if (eof) break;
+ }
+ Tcl_DStringFree(&dstring);
+ return rc;
+}
+
+#ifdef SHARE_CMD_BUFFER
+/* fgets that shared input buffer with expect_user */
+int
+exp_fgets(interp,buf,max)
+Tcl_Interp *interp;
+char *buf;
+int max;
+{
+ char *nl; /* position of newline which signifies end of line */
+ int write_count;/* length of first line of incoming data */
+
+ int m = fileno(stdin);
+ struct exp_f *f;
+ int cc;
+
+ int dummy;
+
+ /* avoid returning no data, just because someone else read it in by */
+ /* passing most recent key */
+ cc = exp_get_next_event(interp,&m,1,&dummy,EXP_TIME_INFINITY,exp_fs[m].key);
+
+ if (cc == EXP_DATA_NEW) {
+ /* try to read it */
+
+ cc = exp_i_read(m,EXP_TIME_INFINITY);
+
+ /* the meaning of 0 from i_read means eof. Muck with it a */
+ /* little, so that from now on it means "no new data arrived */
+ /* but it should be looked at again anyway". */
+ if (cc == 0) {
+ cc = EXP_EOF;
+ } else if (cc > 0) {
+ f = exp_fs + m;
+ f->buffer[f->size += cc] = '\0';
+ }
+ } else if (cc == EXP_DATA_OLD) {
+ f = exp_fs + m;
+ cc = 0;
+ }
+
+ /* EOF and TIMEOUT return here */
+ /* In such cases, there is no need to update screen since, if there */
+ /* was prior data read, it would have been sent to the screen when */
+ /* it was read. */
+ if (cc < 0) return (cc);
+
+ /* copy up to end of first line */
+
+ /* calculate end of first line */
+ nl = strchr(f->buffer,'\n');
+ if (nl) write_count = 1+nl-f->buffer;
+ else write_count = f->size;
+
+ /* make sure line fits in buffer area */
+ if (write_count > max) write_count = max;
+
+ /* copy it */
+ memcpy(buf,f->buffer,write_count);
+ buf[write_count] = '\0';
+
+ /* update display and f */
+
+ f->printed = 0;
+ /* for simplicity force f->printed = 0. This way, the user gets */
+ /* to see the commands that are about to be executed. Not seeing */
+ /* commands you are supposedly typing sounds very uncomfortable! */
+
+ if (logfile_all || (loguser && logfile)) {
+ fwrite(f->buffer,1,write_count,logfile);
+ }
+ if (debugfile) fwrite(f->buffer,1,write_count,debugfile);
+
+ f->size -= write_count;
+ memcpy(f->buffer,f->buffer+write_count,1+f->size);
+ /* copy to lowercase buffer */
+ exp_lowmemcpy(f->lower,f->buffer,1+f->size);
+
+ return(write_count);
+}
+#endif /*SHARE_CMD_BUFFER*/
+
+static struct exp_cmd_data cmd_data[] = {
+{"expect_version",exp_proc(Exp_ExpVersionCmd), 0, 0}, /* deprecated */
+{"exp_version", exp_proc(Exp_ExpVersionCmd), 0, 0},
+{"prompt1", exp_proc(Exp_Prompt1Cmd), 0, EXP_NOPREFIX},
+{"prompt2", exp_proc(Exp_Prompt2Cmd), 0, EXP_NOPREFIX},
+{0}};
+
+void
+exp_init_main_cmds(interp)
+Tcl_Interp *interp;
+{
+ exp_create_commands(interp,cmd_data);
+}
diff --git a/expect/exp_main_tk.c b/expect/exp_main_tk.c
new file mode 100644
index 00000000000..f6ebb91cc97
--- /dev/null
+++ b/expect/exp_main_tk.c
@@ -0,0 +1,445 @@
+/* exp_main_tk.c - main for expectk
+
+ This file consists of three pieces:
+ 1) AppInit for Expectk. This has been suitably modified to invoke
+ a modified version of Tk_Init.
+ 2) Tk_Init for Expectk. What's wrong with the normal Tk_Init is that
+ removes the -- in the cmd-line arg list, so Expect cannot know
+ whether args are flags to Expectk or data for the script. Sigh.
+ 3) Additions and supporting utilities to Tk's Argv parse table to
+ support Expectk's flags.
+
+ Author: Don Libes, NIST, 2/20/96
+
+*/
+
+/* Expectk's AppInit */
+
+/*
+ * tkAppInit.c --
+ *
+ * Provides a default version of the Tcl_AppInit procedure for
+ * use in wish and similar Tk-based applications.
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#) tkAppInit.c 1.19 95/12/23 17:09:24";
+#endif /* not lint */
+
+#include <ctype.h>
+
+#include "tk.h"
+
+#include "expect_tcl.h"
+#include "Dbg.h"
+
+/*
+ * The following variable is a special hack that is needed in order for
+ * Sun shared libraries to be used for Tcl.
+ */
+
+extern int matherr();
+int *tclDummyMathPtr = (int *) matherr;
+
+#ifdef TK_TEST
+EXTERN int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+#endif /* TK_TEST */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * main --
+ *
+ * This is the main program for the application.
+ *
+ * Results:
+ * None: Tk_Main never returns here, so this procedure never
+ * returns either.
+ *
+ * Side effects:
+ * Whatever the application does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+main(argc, argv)
+ int argc; /* Number of command-line arguments. */
+ char **argv; /* Values of command-line arguments. */
+{
+ Tk_Main(argc, argv, Tcl_AppInit);
+ return 0; /* Needed only to prevent compiler warning. */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppInit --
+ *
+ * This procedure performs application-specific initialization.
+ * Most applications, especially those that incorporate additional
+ * packages, will have their own version of this procedure.
+ *
+ * Results:
+ * Returns a standard Tcl completion code, and leaves an error
+ * message in interp->result if an error occurs.
+ *
+ * Side effects:
+ * Depends on the startup script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_AppInit(interp)
+ Tcl_Interp *interp; /* Interpreter for application. */
+{
+ if (Tcl_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+
+ /* do Expect first so we can get access to Expect commands when */
+ /* Tk_Init does the argument parsing of -c */
+ if (Expect_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ Tcl_StaticPackage(interp, "Expect", Expect_Init, (Tcl_PackageInitProc *)NULL);
+
+ if (Tk_Init2(interp) == TCL_ERROR) { /* DEL */
+ return TCL_ERROR;
+ }
+ Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
+
+ /*
+ * Call the init procedures for included packages. Each call should
+ * look like this:
+ *
+ * if (Mod_Init(interp) == TCL_ERROR) {
+ * return TCL_ERROR;
+ * }
+ *
+ * where "Mod" is the name of the module.
+ */
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+
+ /*
+ * Specify a user-specific startup file to invoke if the application
+ * is run interactively. Typically the startup file is "~/.apprc"
+ * where "app" is the name of the application. If this line is deleted
+ * then no user-specific startup file will be run under any conditions.
+ */
+
+ Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);
+ return TCL_OK;
+}
+
+
+
+
+/*
+ * Count of number of main windows currently open in this process.
+ */
+
+static int numMainWindows;
+
+/*
+ * The variables and table below are used to parse arguments from
+ * the "argv" variable in Tk_Init.
+ */
+
+static int synchronize;
+static char *name;
+static char *display;
+static char *geometry;
+static char *colormap;
+static char *visual;
+static int rest = 0;
+
+/* for Expect */
+int my_rc = 1;
+int sys_rc = 1;
+int optcmd_eval();
+#ifdef TCL_DEBUGGER
+int optcmd_debug();
+#endif
+int print_version = 0;
+
+static Tk_ArgvInfo argTable[] = {
+ {"-colormap", TK_ARGV_STRING, (char *) NULL, (char *) &colormap,
+ "Colormap for main window"},
+ {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display,
+ "Display to use"},
+ {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry,
+ "Initial geometry for window"},
+ {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name,
+ "Name to use for application"},
+ {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize,
+ "Use synchronous mode for display server"},
+ {"-visual", TK_ARGV_STRING, (char *) NULL, (char *) &visual,
+ "Visual for main window"},
+ {"--", TK_ARGV_REST, (char *) 1, (char *) &rest,
+ "Pass all remaining arguments through to script"},
+/* for Expect */
+ {"-command", TK_ARGV_GENFUNC, (char *) optcmd_eval, (char *)0,
+ "Command(s) to execute immediately"},
+ {"-diag", TK_ARGV_CONSTANT, (char *) 1, (char *) &exp_is_debugging,
+ "Enable diagnostics"},
+ {"-norc", TK_ARGV_CONSTANT, (char *) 0, (char *) &my_rc,
+ "Don't read ~/.expect.rc"},
+ {"-NORC", TK_ARGV_CONSTANT, (char *) 0, (char *) &sys_rc,
+ "Don't read system-wide expect.rc"},
+ {"-version", TK_ARGV_CONSTANT, (char *) 1, (char *) &print_version,
+ "Print version and exit"},
+#if TCL_DEBUGGER
+ {"-Debug", TK_ARGV_GENFUNC, (char *) optcmd_debug, (char *)0,
+ "Enable debugger"},
+#endif
+ {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL,
+ (char *) NULL}
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_Init --
+ *
+ * This procedure is invoked to add Tk to an interpreter. It
+ * incorporates all of Tk's commands into the interpreter and
+ * creates the main window for a new Tk application. If the
+ * interpreter contains a variable "argv", this procedure
+ * extracts several arguments from that variable, uses them
+ * to configure the main window, and modifies argv to exclude
+ * the arguments (see the "wish" documentation for a list of
+ * the arguments that are extracted).
+ *
+ * Results:
+ * Returns a standard Tcl completion code and sets interp->result
+ * if there is an error.
+ *
+ * Side effects:
+ * Depends on various initialization scripts that get invoked.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tk_Init2(interp)
+ Tcl_Interp *interp; /* Interpreter to initialize. */
+{
+ char *p;
+ int argc, code;
+ char **argv, *args[20];
+ Tcl_DString class;
+ char buffer[30];
+
+ /*
+ * If there is an "argv" variable, get its value, extract out
+ * relevant arguments from it, and rewrite the variable without
+ * the arguments that we used.
+ */
+
+ synchronize = 0;
+ name = display = geometry = colormap = visual = NULL;
+ p = Tcl_GetVar2(interp, "argv", (char *) NULL, TCL_GLOBAL_ONLY);
+ argv = NULL;
+ if (p != NULL) {
+ if (Tcl_SplitList(interp, p, &argc, &argv) != TCL_OK) {
+ argError:
+ Tcl_AddErrorInfo(interp,
+ "\n (processing arguments in argv variable)");
+ return TCL_ERROR;
+ }
+ if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv,
+ argTable, TK_ARGV_DONT_SKIP_FIRST_ARG|TK_ARGV_NO_DEFAULTS)
+ != TCL_OK) {
+ ckfree((char *) argv);
+ goto argError;
+ }
+
+ if (print_version) {
+ extern char exp_version[];
+ printf ("expectk version %s\n", exp_version);
+ exp_exit (interp, 0);
+ }
+
+ p = Tcl_Merge(argc, argv);
+ Tcl_SetVar2(interp, "argv", (char *) NULL, p, TCL_GLOBAL_ONLY);
+ sprintf(buffer, "%d", argc);
+ Tcl_SetVar2(interp, "argc", (char *) NULL, buffer, TCL_GLOBAL_ONLY);
+ ckfree(p);
+ }
+
+ /*
+ * Figure out the application's name and class.
+ */
+
+ if (name == NULL) {
+ name = Tcl_GetVar(interp, "argv0", TCL_GLOBAL_ONLY);
+ if ((name == NULL) || (*name == 0)) {
+ name = "tk";
+ } else {
+ p = (char *)strrchr(name, '/'); /* added cast - DEL */
+ if (p != NULL) {
+ name = p+1;
+ }
+ }
+ }
+ Tcl_DStringInit(&class);
+ Tcl_DStringAppend(&class, name, -1);
+ p = Tcl_DStringValue(&class);
+ if (islower(*p)) {
+ *p = toupper((unsigned char) *p);
+ }
+
+ /*
+ * Create an argument list for creating the top-level window,
+ * using the information parsed from argv, if any.
+ */
+
+ args[0] = "toplevel";
+ args[1] = ".";
+ args[2] = "-class";
+ args[3] = Tcl_DStringValue(&class);
+ argc = 4;
+ if (display != NULL) {
+ args[argc] = "-screen";
+ args[argc+1] = display;
+ argc += 2;
+
+ /*
+ * If this is the first application for this process, save
+ * the display name in the DISPLAY environment variable so
+ * that it will be available to subprocesses created by us.
+ */
+
+ if (numMainWindows == 0) {
+ Tcl_SetVar2(interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY);
+ }
+ }
+ if (colormap != NULL) {
+ args[argc] = "-colormap";
+ args[argc+1] = colormap;
+ argc += 2;
+ }
+ if (visual != NULL) {
+ args[argc] = "-visual";
+ args[argc+1] = visual;
+ argc += 2;
+ }
+ args[argc] = NULL;
+ code = TkCreateFrame((ClientData) NULL, interp, argc, args, 1, name);
+ Tcl_DStringFree(&class);
+ if (code != TCL_OK) {
+ goto done;
+ }
+ Tcl_ResetResult(interp);
+ if (synchronize) {
+ XSynchronize(Tk_Display(Tk_MainWindow(interp)), True);
+ }
+
+ /*
+ * Set the geometry of the main window, if requested. Put the
+ * requested geometry into the "geometry" variable.
+ */
+
+ if (geometry != NULL) {
+ Tcl_SetVar(interp, "geometry", geometry, TCL_GLOBAL_ONLY);
+ code = Tcl_VarEval(interp, "wm geometry . ", geometry, (char *) NULL);
+ if (code != TCL_OK) {
+ goto done;
+ }
+ }
+ if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL) {
+ code = TCL_ERROR;
+ goto done;
+ }
+ code = Tcl_PkgProvide(interp, "Tk", TK_VERSION);
+ if (code != TCL_OK) {
+ goto done;
+ }
+
+ /*
+ * Invoke platform-specific initialization.
+ */
+
+#if TCL_MAJOR_VERSION < 8
+ code = TkPlatformInit(interp);
+#else
+ code = TkpInit(interp, 0);
+#endif
+
+ done:
+ if (argv != NULL) {
+ ckfree((char *) argv);
+ }
+ return code;
+}
+
+/*ARGSUSED*/
+int
+optcmd_eval(dst,interp,key,argc,argv)
+char *dst;
+Tcl_Interp *interp;
+char *key;
+int argc;
+char **argv;
+{
+ int i;
+ int rc;
+
+ exp_cmdlinecmds = 1;
+
+ rc = Tcl_Eval(interp,argv[0]);
+ if (rc == TCL_ERROR) return -1;
+
+ argc--;
+ for (i=0;i<argc;i++) {
+ argv[i] = argv[i+1];
+ }
+
+ return argc;
+}
+
+#ifdef TCL_DEBUGGER
+/*ARGSUSED*/
+int
+optcmd_debug(dst,interp,key,argc,argv)
+char *dst;
+Tcl_Interp *interp;
+char *key;
+int argc;
+char **argv;
+{
+ int i;
+
+ if (argc == 0) {
+ strcpy(interp->result,"-Debug flag needs 1 or 0 argument");
+ return -1;
+ }
+
+ if (Tcl_GetInt(interp,argv[0],&i) != TCL_OK) {
+ return -1;
+ }
+
+ if (i) {
+ Dbg_On(interp,0);
+ }
+
+ argc--;
+ for (i=0;i<argc;i++) {
+ argv[i] = argv[i+1];
+ }
+
+ return argc;
+}
+#endif /*TCL_DEBUGGER*/
diff --git a/expect/exp_memmove.c b/expect/exp_memmove.c
new file mode 100644
index 00000000000..324bc2db844
--- /dev/null
+++ b/expect/exp_memmove.c
@@ -0,0 +1,25 @@
+/* memmove - some systems lack this */
+
+#include "expect_cf.h"
+#include "tcl.h"
+
+/* like memcpy but can handle overlap */
+#ifndef HAVE_MEMMOVE
+char *
+memmove(dest,src,n)
+VOID *dest;
+CONST VOID *src;
+int n;
+{
+ char *d;
+ CONST char *s;
+
+ d = dest;
+ s = src;
+ if (s<d && (d < s+n)) {
+ for (d+=n, s+=n; 0<n; --n)
+ *--d = *--s;
+ } else for (;0<n;--n) *d++ = *s++;
+ return dest;
+}
+#endif /* HAVE_MEMMOVE */
diff --git a/expect/exp_noevent.c b/expect/exp_noevent.c
new file mode 100644
index 00000000000..fb2317116dc
--- /dev/null
+++ b/expect/exp_noevent.c
@@ -0,0 +1,180 @@
+/* interact (with only one process) - give user keyboard control
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+/* This file exists for deficient versions of UNIX that lack select,
+poll, or some other multiplexing hook. Instead, this code uses two
+processes per spawned process. One sends characters from the spawnee
+to the spawner; a second send chars the other way.
+
+This will work on any UNIX system. The only sacrifice is that it
+doesn't support multiple processes. Eventually, it should catch
+SIGCHLD on dead processes and do the right thing. But it is pretty
+gruesome to imagine so many processes to do all this. If you change
+it successfully, please mail back the changes to me. - Don
+*/
+
+#include "expect_cf.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#include "tcl.h"
+#include "exp_prog.h"
+#include "exp_command.h" /* for struct exp_f defs */
+#include "exp_event.h"
+
+/*ARGSUSED*/
+void
+exp_arm_background_filehandler(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_disarm_background_filehandler(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_disarm_background_filehandler_force(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_unblock_background_filehandler(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_block_background_filehandler(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_event_disarm(fd)
+int fd;
+{
+}
+
+/* returns status, one of EOF, TIMEOUT, ERROR or DATA */
+/*ARGSUSED*/
+int
+exp_get_next_event(interp,masters, n,master_out,timeout,key)
+Tcl_Interp *interp;
+int *masters;
+int n; /* # of masters */
+int *master_out; /* 1st event master, not set if none */
+int timeout; /* seconds */
+int key;
+{
+ int m;
+ struct exp_f *f;
+
+ if (n > 1) {
+ exp_error(interp,"expect not compiled with multiprocess support");
+ /* select a different INTERACT_TYPE in Makefile */
+ return(TCL_ERROR);
+ }
+
+ m = *master_out = masters[0];
+ f = exp_fs + m;
+
+ if (f->key != key) {
+ f->key = key;
+ f->force_read = FALSE;
+ return(EXP_DATA_OLD);
+ } else if ((!f->force_read) && (f->size != 0)) {
+ return(EXP_DATA_OLD);
+ }
+
+ return(EXP_DATA_NEW);
+}
+
+/*ARGSUSED*/
+int
+exp_get_next_event_info(interp,fd,ready_mask)
+Tcl_Interp *interp;
+int fd;
+int ready_mask;
+{
+}
+
+/* There is no portable way to do sub-second sleeps on such a system, so */
+/* do the next best thing (without a busy loop) and fake it: sleep the right */
+/* amount of time over the long run. Note that while "subtotal" isn't */
+/* reinitialized, it really doesn't matter for such a gross hack as random */
+/* scheduling pauses will easily introduce occasional one second delays. */
+int /* returns TCL_XXX */
+exp_dsleep(interp,sec)
+Tcl_Interp *interp;
+double sec;
+{
+ static double subtotal = 0;
+ int seconds;
+
+ subtotal += sec;
+ if (subtotal < 1) return TCL_OK;
+ seconds = subtotal;
+ subtotal -= seconds;
+ restart:
+ if (Tcl_AsyncReady()) {
+ int rc = Tcl_AsyncInvoke(interp,TCL_OK);
+ if (rc != TCL_OK) return(rc);
+ }
+ sleep(seconds);
+ return TCL_OK;
+}
+
+#if 0
+/* There is no portable way to do sub-second sleeps on such a system, so */
+/* do the next best thing (without a busy loop) and fake it: sleep the right */
+/* amount of time over the long run. Note that while "subtotal" isn't */
+/* reinitialized, it really doesn't matter for such a gross hack as random */
+/* scheduling pauses will easily introduce occasional one second delays. */
+int /* returns TCL_XXX */
+exp_usleep(interp,usec)
+Tcl_Interp *interp;
+long usec; /* microseconds */
+{
+ static subtotal = 0;
+ int seconds;
+
+ subtotal += usec;
+ if (subtotal < 1000000) return TCL_OK;
+ seconds = subtotal/1000000;
+ subtotal = subtotal%1000000;
+ restart:
+ if (Tcl_AsyncReady()) {
+ int rc = Tcl_AsyncInvoke(interp,TCL_OK);
+ if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc));
+ }
+ sleep(seconds);
+ return TCL_OK;
+}
+#endif /*0*/
+
+/* set things up for later calls to event handler */
+void
+exp_init_event()
+{
+ exp_event_exit = 0;
+}
diff --git a/expect/exp_poll.c b/expect/exp_poll.c
new file mode 100644
index 00000000000..9815ef03a5f
--- /dev/null
+++ b/expect/exp_poll.c
@@ -0,0 +1,880 @@
+/* exp_poll.c - This file contains UNIX specific procedures for
+ * poll-based notifier, which is the lowest-level part of the Tcl
+ * event loop. This file works together with ../generic/tclNotify.c.
+ *
+ * Design and implementation of this program was paid for by U.S. tax
+ * dollars. Therefore it is public domain. However, the author and
+ * NIST would appreciate credit if this program or parts of it are
+ * used.
+ *
+ * Written by Don Libes, NIST, 2/6/90
+ * Rewritten by Don Libes, 2/96 for new Tcl notifier paradigm.
+ * Rewritten again by Don Libes, 8/97 for yet another Tcl notifier paradigm.
+ */
+
+#include "tclInt.h"
+#include "tclPort.h"
+#include <signal.h>
+
+#include <poll.h>
+#include <sys/types.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+/* Some systems require that the poll array be non-empty so provide a
+ * 1-elt array for starters. It will be ignored as soon as it grows
+ * larger.
+ */
+
+static struct pollfd initialFdArray;
+static struct pollfd *fdArray = &initialFdArray;
+static int fdsInUse = 0; /* space in use */
+static int fdsMaxSpace = 1; /* space that has actually been allocated */
+
+#if TCL_MAJOR_VERSION >= 8
+
+/*
+ * tclUnixNotify.c --
+ *
+ * This file contains the implementation of the select-based
+ * Unix-specific notifier, which is the lowest-level part of the
+ * Tcl event loop. This file works together with
+ * ../generic/tclNotify.c.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * SCCS: @(#) tclUnixNotfy.c 1.42 97/07/02 20:55:44
+ */
+
+/*
+ * This structure is used to keep track of the notifier info for a
+ * a registered file.
+ */
+
+typedef struct FileHandler {
+ int fd;
+ int mask; /* Mask of desired events: TCL_READABLE,
+ * etc. */
+ int readyMask; /* Mask of events that have been seen since the
+ * last time file handlers were invoked for
+ * this file. */
+ Tcl_FileProc *proc; /* Procedure to call, in the style of
+ * Tcl_CreateFileHandler. */
+ ClientData clientData; /* Argument to pass to proc. */
+ int pollArrayIndex; /* index into poll array */
+ struct FileHandler *nextPtr;/* Next in list of all files we care about. */
+} FileHandler;
+
+/*
+ * The following structure is what is added to the Tcl event queue when
+ * file handlers are ready to fire.
+ */
+
+typedef struct FileHandlerEvent {
+ Tcl_Event header; /* Information that is standard for
+ * all events. */
+ int fd; /* File descriptor that is ready. Used
+ * to find the FileHandler structure for
+ * the file (can't point directly to the
+ * FileHandler structure because it could
+ * go away while the event is queued). */
+} FileHandlerEvent;
+
+/*
+ * The following static structure contains the state information for the
+ * select based implementation of the Tcl notifier.
+ */
+
+static struct {
+ FileHandler *firstFileHandlerPtr;
+ /* Pointer to head of file handler list. */
+ fd_mask checkMasks[3*MASK_SIZE];
+ /* This array is used to build up the masks
+ * to be used in the next call to select.
+ * Bits are set in response to calls to
+ * Tcl_CreateFileHandler. */
+ fd_mask readyMasks[3*MASK_SIZE];
+ /* This array reflects the readable/writable
+ * conditions that were found to exist by the
+ * last call to select. */
+ int numFdBits; /* Number of valid bits in checkMasks
+ * (one more than highest fd for which
+ * Tcl_WatchFile has been called). */
+} notifier;
+
+/*
+ * The following static indicates whether this module has been initialized.
+ */
+
+static int initialized = 0;
+
+/*
+ * Static routines defined in this file.
+ */
+
+static void InitNotifier _ANSI_ARGS_((void));
+static void NotifierExitHandler _ANSI_ARGS_((
+ ClientData clientData));
+static int FileHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
+ int flags));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InitNotifier --
+ *
+ * Initializes the notifier state.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Creates a new exit handler.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+InitNotifier()
+{
+ initialized = 1;
+ memset(&notifier, 0, sizeof(notifier));
+ Tcl_CreateExitHandler(NotifierExitHandler, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NotifierExitHandler --
+ *
+ * This function is called to cleanup the notifier state before
+ * Tcl is unloaded.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Destroys the notifier window.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+NotifierExitHandler(clientData)
+ ClientData clientData; /* Not used. */
+{
+ initialized = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetTimer --
+ *
+ * This procedure sets the current notifier timer value. This
+ * interface is not implemented in this notifier because we are
+ * always running inside of Tcl_DoOneEvent.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetTimer(timePtr)
+ Tcl_Time *timePtr; /* Timeout value, may be NULL. */
+{
+ /*
+ * The interval timer doesn't do anything in this implementation,
+ * because the only event loop is via Tcl_DoOneEvent, which passes
+ * timeout values to Tcl_WaitForEvent.
+ */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateFileHandler --
+ *
+ * This procedure registers a file handler with the Xt notifier.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Creates a new file handler structure and registers one or more
+ * input procedures with Xt.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_CreateFileHandler(fd, mask, proc, clientData)
+ int fd; /* Handle of stream to watch. */
+ int mask; /* OR'ed combination of TCL_READABLE,
+ * TCL_WRITABLE, and TCL_EXCEPTION:
+ * indicates conditions under which
+ * proc should be called. */
+ Tcl_FileProc *proc; /* Procedure to call for each
+ * selected event. */
+ ClientData clientData; /* Arbitrary data to pass to proc. */
+{
+ FileHandler *filePtr;
+ int index, bit;
+ int cur_fd_index;
+
+ if (!initialized) {
+ InitNotifier();
+ }
+
+ for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;
+ filePtr = filePtr->nextPtr) {
+ if (filePtr->fd == fd) {
+ break;
+ }
+ }
+ if (filePtr == NULL) {
+ filePtr = (FileHandler*) ckalloc(sizeof(FileHandler)); /* MLK */
+ filePtr->fd = fd;
+ filePtr->readyMask = 0;
+ filePtr->nextPtr = notifier.firstFileHandlerPtr;
+ notifier.firstFileHandlerPtr = filePtr;
+ }
+ filePtr->proc = proc;
+ filePtr->clientData = clientData;
+#if NOTUSED
+ /* remaining junk is left over from select implementation - DEL */
+
+ filePtr->mask = mask;
+
+ /*
+ * Update the check masks for this file.
+ */
+
+ index = fd/(NBBY*sizeof(fd_mask));
+ bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
+ if (mask & TCL_READABLE) {
+ notifier.checkMasks[index] |= bit;
+ } else {
+ notifier.checkMasks[index] &= ~bit;
+ }
+ if (mask & TCL_WRITABLE) {
+ (notifier.checkMasks+MASK_SIZE)[index] |= bit;
+ } else {
+ (notifier.checkMasks+MASK_SIZE)[index] &= ~bit;
+ }
+ if (mask & TCL_EXCEPTION) {
+ (notifier.checkMasks+2*(MASK_SIZE))[index] |= bit;
+ } else {
+ (notifier.checkMasks+2*(MASK_SIZE))[index] &= ~bit;
+ }
+ if (notifier.numFdBits <= fd) {
+ notifier.numFdBits = fd+1;
+ }
+#endif /* notused */
+
+ filePtr->pollArrayIndex = fdsInUse;
+ cur_fd_index = fdsInUse;
+
+ fdsInUse++;
+ if (fdsInUse > fdsMaxSpace) {
+ if (fdArray != &initialFdArray) ckfree((char *)fdArray);
+ fdArray = (struct pollfd *)ckalloc(fdsInUse*sizeof(struct pollfd));
+ fdsMaxSpace = fdsInUse;
+ }
+
+ fdArray[cur_fd_index].fd = fd;
+
+ /* I know that POLLIN/OUT is right. But I have no idea if POLLPRI
+ * corresponds well to TCL_EXCEPTION.
+ */
+
+ if (mask & TCL_READABLE) {
+ fdArray[cur_fd_index].events = POLLIN;
+ }
+ if (mask & TCL_WRITABLE) {
+ fdArray[cur_fd_index].events = POLLOUT;
+ }
+ if (mask & TCL_EXCEPTION) {
+ fdArray[cur_fd_index].events = POLLPRI;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteFileHandler --
+ *
+ * Cancel a previously-arranged callback arrangement for
+ * a file.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * If a callback was previously registered on file, remove it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteFileHandler(fd)
+ int fd; /* Stream id for which to remove callback procedure. */
+{
+ FileHandler *filePtr, *prevPtr, *lastPtr;
+ int index, bit, mask, i;
+ int cur_fd_index;
+
+ if (!initialized) {
+ InitNotifier();
+ }
+
+ /*
+ * Find the entry for the given file (and return if there
+ * isn't one).
+ */
+
+ for (prevPtr = NULL, filePtr = notifier.firstFileHandlerPtr; ;
+ prevPtr = filePtr, filePtr = filePtr->nextPtr) {
+ if (filePtr == NULL) {
+ return;
+ }
+ if (filePtr->fd == fd) {
+ break;
+ }
+ }
+
+#if NOTUSED
+ /* remaining junk is left over from select implementation - DEL */
+
+ /*
+ * Update the check masks for this file.
+ */
+
+ index = fd/(NBBY*sizeof(fd_mask));
+ bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
+
+ if (filePtr->mask & TCL_READABLE) {
+ notifier.checkMasks[index] &= ~bit;
+ }
+ if (filePtr->mask & TCL_WRITABLE) {
+ (notifier.checkMasks+MASK_SIZE)[index] &= ~bit;
+ }
+ if (filePtr->mask & TCL_EXCEPTION) {
+ (notifier.checkMasks+2*(MASK_SIZE))[index] &= ~bit;
+ }
+
+ /*
+ * Find current max fd.
+ */
+
+ if (fd+1 == notifier.numFdBits) {
+ for (notifier.numFdBits = 0; index >= 0; index--) {
+ mask = notifier.checkMasks[index]
+ | (notifier.checkMasks+MASK_SIZE)[index]
+ | (notifier.checkMasks+2*(MASK_SIZE))[index];
+ if (mask) {
+ for (i = (NBBY*sizeof(fd_mask)); i > 0; i--) {
+ if (mask & (1 << (i-1))) {
+ break;
+ }
+ }
+ notifier.numFdBits = index * (NBBY*sizeof(fd_mask)) + i;
+ break;
+ }
+ }
+ }
+#endif /* notused */
+
+ /*
+ * Clean up information in the callback record.
+ */
+
+ if (prevPtr == NULL) {
+ notifier.firstFileHandlerPtr = filePtr->nextPtr;
+ } else {
+ prevPtr->nextPtr = filePtr->nextPtr;
+ }
+
+ /* back to poll-specific code - DEL */
+
+ cur_fd_index = filePtr->pollArrayIndex;
+ fdsInUse--;
+
+ /* if this one is last, do nothing special */
+ /* else swap with one at end of array */
+
+ if (cur_fd_index != fdsInUse) {
+ int lastfd_in_array = fdArray[fdsInUse].fd;
+ memcpy(&fdArray[cur_fd_index],&fdArray[fdsInUse],sizeof(struct pollfd));
+
+ /* update index to reflect new location in array */
+ /* first find link corresponding to last element in array */
+
+ for (lastPtr = notifier.firstFileHandlerPtr; filePtr; lastPtr = lastPtr->nextPtr) {
+ if (lastPtr->fd == lastfd_in_array) {
+ lastPtr->pollArrayIndex = cur_fd_index;
+ break;
+ }
+ }
+ }
+
+ fdsInUse--;
+
+ ckfree((char *) filePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileHandlerEventProc --
+ *
+ * This procedure is called by Tcl_ServiceEvent when a file event
+ * reaches the front of the event queue. This procedure is
+ * responsible for actually handling the event by invoking the
+ * callback for the file handler.
+ *
+ * Results:
+ * Returns 1 if the event was handled, meaning it should be removed
+ * from the queue. Returns 0 if the event was not handled, meaning
+ * it should stay on the queue. The only time the event isn't
+ * handled is if the TCL_FILE_EVENTS flag bit isn't set.
+ *
+ * Side effects:
+ * Whatever the file handler's callback procedure does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileHandlerEventProc(evPtr, flags)
+ Tcl_Event *evPtr; /* Event to service. */
+ int flags; /* Flags that indicate what events to
+ * handle, such as TCL_FILE_EVENTS. */
+{
+ FileHandler *filePtr;
+ FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;
+ int mask;
+
+ if (!(flags & TCL_FILE_EVENTS)) {
+ return 0;
+ }
+
+ /*
+ * Search through the file handlers to find the one whose handle matches
+ * the event. We do this rather than keeping a pointer to the file
+ * handler directly in the event, so that the handler can be deleted
+ * while the event is queued without leaving a dangling pointer.
+ */
+
+ for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;
+ filePtr = filePtr->nextPtr) {
+ if (filePtr->fd != fileEvPtr->fd) {
+ continue;
+ }
+
+ /*
+ * The code is tricky for two reasons:
+ * 1. The file handler's desired events could have changed
+ * since the time when the event was queued, so AND the
+ * ready mask with the desired mask.
+ * 2. The file could have been closed and re-opened since
+ * the time when the event was queued. This is why the
+ * ready mask is stored in the file handler rather than
+ * the queued event: it will be zeroed when a new
+ * file handler is created for the newly opened file.
+ */
+
+ mask = filePtr->readyMask & filePtr->mask;
+ filePtr->readyMask = 0;
+ if (mask != 0) {
+ (*filePtr->proc)(filePtr->clientData, mask);
+ }
+ break;
+ }
+ return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WaitForEvent --
+ *
+ * This function is called by Tcl_DoOneEvent to wait for new
+ * events on the message queue. If the block time is 0, then
+ * Tcl_WaitForEvent just polls without blocking.
+ *
+ * Results:
+ * Returns -1 if the select would block forever, otherwise
+ * returns 0.
+ *
+ * Side effects:
+ * Queues file events that are detected by the select.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_WaitForEvent(timePtr)
+ Tcl_Time *timePtr; /* Maximum block time, or NULL. */
+{
+ FileHandler *filePtr;
+ FileHandlerEvent *fileEvPtr;
+#if 0
+ struct timeval timeout, *timeoutPtr;
+#endif
+ int timeout;
+ struct timeval *timeoutPtr;
+
+ int bit, index, mask, numFound;
+
+ if (!initialized) {
+ InitNotifier();
+ }
+
+ /*
+ * Set up the timeout structure. Note that if there are no events to
+ * check for, we return with a negative result rather than blocking
+ * forever.
+ */
+
+ if (timePtr) {
+#if 0
+ timeout.tv_sec = timePtr->sec;
+ timeout.tv_usec = timePtr->usec;
+ timeoutPtr = &timeout;
+#endif
+ timeout = timePtr->sec*1000 + timePtr->usec/1000;
+
+ } else if (notifier.numFdBits == 0) {
+ return -1;
+ } else {
+ timeoutPtr = NULL;
+ }
+
+ numFound = poll(fdArray,fdsInUse,timeout);
+#if 0
+ memcpy((VOID *) notifier.readyMasks, (VOID *) notifier.checkMasks,
+ 3*MASK_SIZE*sizeof(fd_mask));
+ numFound = select(notifier.numFdBits,
+ (SELECT_MASK *) &notifier.readyMasks[0],
+ (SELECT_MASK *) &notifier.readyMasks[MASK_SIZE],
+ (SELECT_MASK *) &notifier.readyMasks[2*MASK_SIZE], timeoutPtr);
+
+ /*
+ * Some systems don't clear the masks after an error, so
+ * we have to do it here.
+ */
+
+ if (numFound == -1) {
+ memset((VOID *) notifier.readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
+ }
+#endif
+
+ /*
+ * Queue all detected file events before returning.
+ */
+
+ for (filePtr = notifier.firstFileHandlerPtr;
+ (filePtr != NULL) && (numFound > 0);
+ filePtr = filePtr->nextPtr) {
+ index = filePtr->pollArrayIndex;
+ mask = 0;
+
+ if (fdArray[index].revents & POLLIN) {
+ mask |= TCL_READABLE;
+ }
+ if (fdArray[index].revents & POLLOUT) {
+ mask |= TCL_WRITABLE;
+ }
+ /* I have no idea if this is right ... */
+ if (fdArray[index].revents & (POLLPRI|POLLERR|POLLHUP|POLLNVAL)) {
+ mask |= TCL_EXCEPTION;
+ }
+
+#if 0
+ index = filePtr->fd / (NBBY*sizeof(fd_mask));
+ bit = 1 << (filePtr->fd % (NBBY*sizeof(fd_mask)));
+ mask = 0;
+
+ if (notifier.readyMasks[index] & bit) {
+ mask |= TCL_READABLE;
+ }
+ if ((notifier.readyMasks+MASK_SIZE)[index] & bit) {
+ mask |= TCL_WRITABLE;
+ }
+ if ((notifier.readyMasks+2*(MASK_SIZE))[index] & bit) {
+ mask |= TCL_EXCEPTION;
+ }
+#endif
+
+ if (!mask) {
+ continue;
+ } else {
+ numFound--;
+ }
+
+ /*
+ * Don't bother to queue an event if the mask was previously
+ * non-zero since an event must still be on the queue.
+ */
+
+ if (filePtr->readyMask == 0) {
+ fileEvPtr = (FileHandlerEvent *) ckalloc(
+ sizeof(FileHandlerEvent));
+ fileEvPtr->header.proc = FileHandlerEventProc;
+ fileEvPtr->fd = filePtr->fd;
+ Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
+ }
+ filePtr->readyMask = mask;
+ }
+ return 0;
+}
+
+#else /* TCL_MAJOR_VERSION < 8 */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WatchFile --
+ *
+ * Arrange for Tcl_DoOneEvent to include this file in the masks
+ * for the next call to select. This procedure is invoked by
+ * event sources, which are in turn invoked by Tcl_DoOneEvent
+ * before it invokes select.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ *
+ * The notifier will generate a file event when the I/O channel
+ * given by fd next becomes ready in the way indicated by mask.
+ * If fd is already registered then the old mask will be replaced
+ * with the new one. Once the event is sent, the notifier will
+ * not send any more events about the fd until the next call to
+ * Tcl_NotifyFile.
+ *
+ * Assumption for poll implementation: Tcl_WatchFile is presumed NOT
+ * to be called on the same file descriptior without intervening calls
+ * to Tcl_DoOneEvent.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_WatchFile(file, mask)
+ Tcl_File file; /* Generic file handle for a stream. */
+ int mask; /* OR'ed combination of TCL_READABLE,
+ * TCL_WRITABLE, and TCL_EXCEPTION:
+ * indicates conditions to wait for
+ * in select. */
+{
+ int fd, type;
+ int cur_fd_index = fdsInUse;
+
+ fd = (int) Tcl_GetFileInfo(file, &type);
+
+ if (type != TCL_UNIX_FD) {
+ panic("Tcl_WatchFile: unexpected file type");
+ }
+
+ fdsInUse++;
+ if (fdsInUse > fdsMaxSpace) {
+ if (fdArray != &initialFdArray) ckfree((char *)fdArray);
+ fdArray = (struct pollfd *)ckalloc(fdsInUse*sizeof(struct pollfd));
+ fdsMaxSpace = fdsInUse;
+ }
+
+ fdArray[cur_fd_index].fd = fd;
+
+ /* I know that POLLIN/OUT is right. But I have no idea if POLLPRI
+ * corresponds well to TCL_EXCEPTION.
+ */
+
+ if (mask & TCL_READABLE) {
+ fdArray[cur_fd_index].events = POLLIN;
+ }
+ if (mask & TCL_WRITABLE) {
+ fdArray[cur_fd_index].events = POLLOUT;
+ }
+ if (mask & TCL_EXCEPTION) {
+ fdArray[cur_fd_index].events = POLLPRI;
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FileReady --
+ *
+ * Indicates what conditions (readable, writable, etc.) were
+ * present on a file the last time the notifier invoked select.
+ * This procedure is typically invoked by event sources to see
+ * if they should queue events.
+ *
+ * Results:
+ * The return value is 0 if none of the conditions specified by mask
+ * was true for fd the last time the system checked. If any of the
+ * conditions were true, then the return value is a mask of those
+ * that were true.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FileReady(file, mask)
+ Tcl_File file; /* Generic file handle for a stream. */
+ int mask; /* OR'ed combination of TCL_READABLE,
+ * TCL_WRITABLE, and TCL_EXCEPTION:
+ * indicates conditions caller cares about. */
+{
+ int index, result, type, fd;
+ fd_mask bit;
+
+ fd = (int) Tcl_GetFileInfo(file, &type);
+ if (type != TCL_UNIX_FD) {
+ panic("Tcl_FileReady: unexpected file type");
+ }
+
+ result = 0;
+ if ((mask & TCL_READABLE) && (fdArray[fd].revents & POLLIN)) {
+ result |= TCL_READABLE;
+ }
+ if ((mask & TCL_WRITABLE) && (fdArray[fd].revents & POLLOUT)) {
+ result |= TCL_WRITABLE;
+ }
+ /* I have no idea if this is right ... */
+ if ((mask & TCL_EXCEPTION) &&
+ (fdArray[fd].revents & (POLLPRI|POLLERR|POLLHUP|POLLNVAL))) {
+ result |= TCL_EXCEPTION;
+ }
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WaitForEvent --
+ *
+ * This procedure does the lowest level wait for events in a
+ * platform-specific manner. It uses information provided by
+ * previous calls to Tcl_WatchFile, plus the timePtr argument,
+ * to determine what to wait for and how long to wait.
+ *
+ * Results:
+ * 7.6 The return value is normally TCL_OK. However, if there are
+ * no events to wait for (e.g. no files and no timers) so that
+ * the procedure would block forever, then it returns TCL_ERROR.
+ *
+ * Side effects:
+ * May put the process to sleep for a while, depending on timePtr.
+ * When this procedure returns, an event of interest to the application
+ * has probably, but not necessarily, occurred.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_WaitForEvent(timePtr)
+ Tcl_Time *timePtr; /* Specifies the maximum amount of time
+ * that this procedure should block before
+ * returning. The time is given as an
+ * interval, not an absolute wakeup time.
+ * NULL means block forever. */
+{
+ int timeout;
+ struct timeval *timeoutPtr;
+
+ /* no need to clear revents */
+ if (timePtr == NULL) {
+ if (!fdsInUse) return (TCL_ERROR);
+ timeout = -1;
+ } else {
+ timeout = timePtr->sec*1000 + timePtr->usec/1000;
+ }
+
+ poll(fdArray,fdsInUse,timeout);
+
+ fdsInUse = 0;
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Sleep --
+ *
+ * Delay execution for the specified number of milliseconds.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Time passes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_Sleep(ms)
+ int ms; /* Number of milliseconds to sleep. */
+{
+ static struct timeval delay;
+ Tcl_Time before, after;
+
+ /*
+ * The only trick here is that select appears to return early
+ * under some conditions, so we have to check to make sure that
+ * the right amount of time really has elapsed. If it's too
+ * early, go back to sleep again.
+ */
+
+ TclGetTime(&before);
+ after = before;
+ after.sec += ms/1000;
+ after.usec += (ms%1000)*1000;
+ if (after.usec > 1000000) {
+ after.usec -= 1000000;
+ after.sec += 1;
+ }
+ while (1) {
+ delay.tv_sec = after.sec - before.sec;
+ delay.tv_usec = after.usec - before.usec;
+ if (delay.tv_usec < 0) {
+ delay.tv_usec += 1000000;
+ delay.tv_sec -= 1;
+ }
+
+ /*
+ * Special note: must convert delay.tv_sec to int before comparing
+ * to zero, since delay.tv_usec is unsigned on some platforms.
+ */
+
+ if ((((int) delay.tv_sec) < 0)
+ || ((delay.tv_usec == 0) && (delay.tv_sec == 0))) {
+ break;
+ }
+
+ /* poll understands milliseconds, sigh */
+ poll(fdArray,0,delay.tv_sec*1000 + delay.tv_usec/1000);
+ TclGetTime(&before);
+ }
+}
+
+#endif /* TCL_MAJOR_VERSION < 8 */
+
diff --git a/expect/exp_printify.c b/expect/exp_printify.c
new file mode 100644
index 00000000000..f2f263f9822
--- /dev/null
+++ b/expect/exp_printify.c
@@ -0,0 +1,56 @@
+/* exp_printify - printable versions of random ASCII strings
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include "expect_cf.h"
+#include "tcl.h"
+#ifdef NO_STDLIB_H
+#include "../compat/stdlib.h"
+#else
+#include <stdlib.h> /* for malloc */
+#endif
+#include <ctype.h>
+
+/* generate printable versions of random ASCII strings. Primarily used */
+/* by cmdExpect when -d forces it to print strings it is examining. */
+char *
+exp_printify(s)
+char *s;
+{
+ static int destlen = 0;
+ static char *dest = 0;
+ char *d; /* ptr into dest */
+ unsigned int need;
+
+ if (s == 0) return("<null>");
+
+ /* worst case is every character takes 4 to printify */
+ need = strlen(s)*4 + 1;
+ if (need > destlen) {
+ if (dest) ckfree(dest);
+ dest = ckalloc(need);
+ destlen = need;
+ }
+
+ for (d = dest;*s;s++) {
+ if (*s == '\r') {
+ strcpy(d,"\\r"); d += 2;
+ } else if (*s == '\n') {
+ strcpy(d,"\\n"); d += 2;
+ } else if (*s == '\t') {
+ strcpy(d,"\\t"); d += 2;
+ } else if (isascii(*s) && isprint(*s)) {
+ *d = *s; d += 1;
+ } else {
+ sprintf(d,"\\x%02x",*s & 0xff); d += 4;
+ }
+ }
+ *d = '\0';
+ return(dest);
+}
diff --git a/expect/exp_printify.h b/expect/exp_printify.h
new file mode 100644
index 00000000000..6eabe87c60c
--- /dev/null
+++ b/expect/exp_printify.h
@@ -0,0 +1,6 @@
+#ifndef __EXP_PRINTIFY_H__
+#define __EXP_PRINTIFY_H__
+
+char *exp_printify();
+
+#endif /* __EXP_PRINTIFY_H__ */
diff --git a/expect/exp_prog.h b/expect/exp_prog.h
new file mode 100644
index 00000000000..bd6ab8ae9fd
--- /dev/null
+++ b/expect/exp_prog.h
@@ -0,0 +1,19 @@
+/* exp_prog.h - private symbols common to both expect program and library
+
+Written by: Don Libes, libes@cme.nist.gov, NIST, 12/3/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+#ifndef _EXPECT_PROG_H
+#define _EXPECT_PROG_H
+
+#include "expect_tcl.h"
+#include "exp_int.h"
+
+/* yes, I have a weak mind */
+#define streq(x,y) (0 == strcmp((x),(y)))
+
+#endif /* _EXPECT_PROG_H */
diff --git a/expect/exp_pty.c b/expect/exp_pty.c
new file mode 100644
index 00000000000..3a1d17f5a90
--- /dev/null
+++ b/expect/exp_pty.c
@@ -0,0 +1,275 @@
+/* exp_pty.c - generic routines to allocate and test ptys
+
+Written by: Don Libes, NIST, 3/9/93
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include "expect_cf.h"
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#else
+# include <fcntl.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#include <signal.h>
+#include <setjmp.h>
+#include <sys/file.h>
+#define EXP_AVOID_INCLUDING_TCL_H 1
+#include "expect_comm.h"
+#include "exp_rename.h"
+#include "exp_pty.h"
+
+#include <errno.h>
+
+void debuglog();
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#ifdef O_NOCTTY
+#define RDWR ((O_RDWR)|(O_NOCTTY))
+#else
+#define RDWR O_RDWR
+#endif
+
+static int locked = FALSE;
+static char lock[] = "/tmp/ptylock.XXXX"; /* XX is replaced by pty id */
+static char locksrc[50] = "/tmp/expect.pid"; /* pid is replaced by real pid */
+ /* locksrc is used as the link source, i.e., something to link from */
+
+static int i_read_errno;/* place to save errno, if i_read() == -1, so it
+ doesn't get overwritten before we get to read it */
+static jmp_buf env; /* for interruptable read() */
+static int env_valid = FALSE; /* whether we can longjmp or not */
+
+/* sigalarm_handler and i_read are here just for supporting the sanity */
+/* checking of pty slave devices. I have only seen this happen on BSD */
+/* systems, but it may need to be done to the other pty implementations */
+/* as well. */
+
+/* Note that this code is virtually replicated from other code in expect */
+/* At some point, I'll dump one, but not until I'm satisfied no other */
+/* changes are needed */
+
+/*ARGSUSED*/
+static RETSIGTYPE
+sigalarm_handler(n)
+int n; /* unused, for compatibility with STDC */
+{
+#ifdef REARM_SIG
+ signal(SIGALRM,sigalarm_handler);
+#endif
+
+ /* check env_valid first to protect us from the alarm occurring */
+ /* in the window between i_read and alarm(0) */
+ if (env_valid) longjmp(env,1);
+}
+
+/* interruptable read */
+static int
+i_read(fd,buffer,length,timeout)
+int fd;
+char *buffer;
+int length;
+int timeout;
+{
+ int cc = -2;
+
+ /* since setjmp insists on returning 1 upon longjmp(,0), */
+ /* longjmp(,2) instead. */
+
+ /* restart read if setjmp returns 0 (first time) or 2. */
+ /* abort if setjmp returns 1. */
+
+ alarm(timeout);
+
+ if (1 != setjmp(env)) {
+ env_valid = TRUE;
+ cc = read(fd,buffer,length);
+ }
+ env_valid = FALSE;
+ i_read_errno = errno; /* errno can be overwritten by the */
+ /* time we return */
+ alarm(0);
+ return(cc);
+}
+
+static RETSIGTYPE (*oldAlarmHandler)();
+static RETSIGTYPE (*oldHupHandler)();
+static time_t current_time; /* time when testing began */
+
+/* if TRUE, begin testing, else end testing */
+/* returns -1 for failure, 0 for success */
+int
+exp_pty_test_start()
+{
+ int lfd; /* locksrc file descriptor */
+
+ oldAlarmHandler = signal(SIGALRM,sigalarm_handler);
+#ifndef O_NOCTTY
+ /* Ignore hangup signals generated by pty testing */
+ /* when running in background with no control tty. */
+ /* Very few systems don't define O_NOCTTY. Only one */
+ /* I know of is Next. */
+ oldAlarmHandler = signal(SIGHUP,SIG_IGN);
+#endif
+
+ time(&current_time);
+
+ /* recreate locksrc to prevent locks from 'looking old', so */
+ /* that they are not deleted (later on in this code) */
+ sprintf(locksrc,"/tmp/expect.%d",getpid());
+ (void) unlink(locksrc);
+ if (-1 == (lfd = creat(locksrc,0777))) {
+ static char buf[256];
+ exp_pty_error = buf;
+ sprintf(exp_pty_error,"can't create %s, errno = %d\n",locksrc, errno);
+ return(-1);
+ }
+ close(lfd);
+ return 0;
+}
+
+void
+exp_pty_test_end()
+{
+ signal(SIGALRM,oldAlarmHandler);
+#ifndef O_NOCTTY
+ signal(SIGALRM,oldHupHandler);
+#endif
+ (void) unlink(locksrc);
+}
+
+/* returns non-negative if successful */
+int
+exp_pty_test(master_name,slave_name,bank,num)
+char *master_name;
+char *slave_name;
+int bank;
+char *num; /* string representation of number */
+{
+ int master, slave;
+ int cc;
+ char c;
+
+ /* make a lock file to prevent others (for now only */
+ /* expects) from allocating pty while we are playing */
+ /* with it. This allows us to rigorously test the */
+ /* pty is usable. */
+ if (exp_pty_lock(bank,num) == 0) {
+ debuglog("pty master (%s) is locked...skipping\r\n",master_name);
+ return(-1);
+ }
+ /* verify no one else is using slave by attempting */
+ /* to read eof from master side */
+ if (0 > (master = open(master_name,RDWR))) return(-1);
+
+#ifdef __QNX__
+
+ /* QNX ptys don't have a lot of the same properties such as
+ read 0 at EOF, etc */
+ /* if 1 should pacify C compiler without using nested ifdefs */
+ if (1) return master;
+#endif
+
+#ifdef HAVE_PTYTRAP
+ if (access(slave_name, R_OK|W_OK) != 0) {
+ debuglog("could not open slave for pty master (%s)...skipping\r\n",
+ master_name);
+ (void) close(master);
+ return -1;
+ }
+ return(master);
+#else
+ if (0 > (slave = open(slave_name,RDWR))) {
+ (void) close(master);
+ return -1;
+ }
+ (void) close(slave);
+ cc = i_read(master,&c,1,10);
+ (void) close(master);
+ if (!(cc == 0 || cc == -1)) {
+ debuglog("%s slave open, skipping\r\n",slave_name);
+ locked = FALSE; /* leave lock file around so Expect's avoid */
+ /* retrying this pty for near future */
+ return -1;
+ }
+
+ /* verify no one else is using master by attempting */
+ /* to read eof from slave side */
+ if (0 > (master = open(master_name,RDWR))) return(-1);
+ if (0 > (slave = open(slave_name,RDWR))) {
+ (void) close(master);
+ return -1;
+ }
+ (void) close(master);
+ cc = i_read(slave,&c,1,10);
+ (void) close(slave);
+ if (!(cc == 0 || cc == -1)) {
+ debuglog("%s master open, skipping\r\n",master_name);
+ return -1;
+ }
+
+ /* seems ok, let's use it */
+ debuglog("using master pty %s\n",master_name);
+ return(open(master_name,RDWR));
+#endif
+}
+
+void
+exp_pty_unlock()
+{
+ if (locked) {
+ (void) unlink(lock);
+ locked = FALSE;
+ }
+}
+
+/* returns 1 if successfully locked, 0 otherwise */
+int
+exp_pty_lock(bank,num)
+int bank;
+char *num; /* string representation of number */
+{
+ struct stat statbuf;
+
+ if (locked) {
+ unlink(lock);
+ locked = FALSE;
+ }
+
+ sprintf(lock,"/tmp/ptylock.%c%s",bank,num);
+
+ if ((0 == stat(lock,&statbuf)) &&
+ (statbuf.st_mtime+3600 < current_time)) {
+ (void) unlink(lock);
+ }
+
+ if (-1 == (link(locksrc,lock))) locked = FALSE;
+ else locked = TRUE;
+
+ return locked;
+}
+
diff --git a/expect/exp_pty.h b/expect/exp_pty.h
new file mode 100644
index 00000000000..61e60c415b3
--- /dev/null
+++ b/expect/exp_pty.h
@@ -0,0 +1,17 @@
+/* exp_pty.h - declarations for pty allocation and testing
+
+Written by: Don Libes, NIST, 3/9/93
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+int exp_pty_test_start();
+void exp_pty_test_end();
+int exp_pty_test();
+void exp_pty_unlock();
+int exp_pty_lock();
+
+extern char *exp_pty_slave_name;
diff --git a/expect/exp_regexp.c b/expect/exp_regexp.c
new file mode 100644
index 00000000000..46f2456f695
--- /dev/null
+++ b/expect/exp_regexp.c
@@ -0,0 +1,1253 @@
+/*
+ * regcomp and regexec -- regsub and regerror are elsewhere
+ *
+ * Copyright (c) 1986 by University of Toronto.
+ * Written by Henry Spencer. Not derived from licensed software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose on any computer system, and to redistribute it freely,
+ * subject to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of
+ * this software, no matter how awful, even if they arise
+ * from defects in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either
+ * by explicit claim or by omission.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not
+ * be misrepresented as being the original software.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions. Serious changes in
+ * regular-expression syntax might require a total rethink.
+ *
+ * *** NOTE: this code has been altered slightly for use in Tcl. ***
+ * *** The only change is to use ckalloc and ckfree instead of ***
+ * *** malloc and free. ***
+
+ * *** and again for Expect!!! - DEL
+
+ * *** More minor corrections stolen from tcl7.5p1/regexp.c - DEL
+
+ */
+
+#include "tcl.h"
+#include "expect_cf.h"
+#include "exp_prog.h"
+#include "tclRegexp.h"
+#include "exp_regexp.h"
+#include "string.h"
+
+#define NOTSTATIC /* was at one time, but Expect needs access */
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases. They are:
+ *
+ * regstart char that must begin a match; '\0' if none obvious
+ * reganch is the match anchored (at beginning-of-line only)?
+ * regmust string (pointer into program) that match must include, or NULL
+ * regmlen length of regmust string
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot. Regmust permits fast rejection
+ * of lines that cannot possibly match. The regmust tests are costly enough
+ * that regcomp() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup). Regmlen is
+ * supplied because the test in regexec() needs it and regcomp() is computing
+ * it anyway.
+ */
+
+/*
+ * Structure for regexp "program". This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology). Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand. "Next" pointers of
+ * all nodes except BRANCH implement concatenation; a "next" pointer with
+ * a BRANCH on both ends of it is connecting two alternatives. (Here we
+ * have one of the subtle syntax dependencies: an individual BRANCH (as
+ * opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence.) The operand of some types of node is
+ * a literal string; for others, it is a node leading into a sub-FSM. In
+ * particular, the operand of a BRANCH node is the first node of the branch.
+ * (NB this is *not* a tree structure: the tail of the branch connects
+ * to the thing following the set of BRANCHes.) The opcodes are:
+ */
+
+/* definition number opnd? meaning */
+#define END 0 /* no End of program. */
+#define BOL 1 /* no Match "" at beginning of line. */
+#define EOL 2 /* no Match "" at end of line. */
+#define ANY 3 /* no Match any one character. */
+#define ANYOF 4 /* str Match any character in this string. */
+#define ANYBUT 5 /* str Match any character not in this string. */
+#define BRANCH 6 /* node Match this alternative, or the next... */
+#define BACK 7 /* no Match "", "next" ptr points backward. */
+#define EXACTLY 8 /* str Match this string. */
+#define NOTHING 9 /* no Match empty string. */
+#define STAR 10 /* node Match this (simple) thing 0 or more times. */
+#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
+#define OPEN 20 /* no Mark this point in input as start of #n. */
+ /* OPEN+1 is number 1, etc. */
+#define CLOSE (OPEN+NSUBEXP) /* no Analogous to OPEN. */
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH The set of branches constituting a single choice are hooked
+ * together with their "next" pointers, since precedence prevents
+ * anything being concatenated to any individual branch. The
+ * "next" pointer of the last BRANCH in a choice points to the
+ * thing following the whole choice. This is also where the
+ * final "next" pointer of each individual branch points; each
+ * branch starts with the operand node of a BRANCH node.
+ *
+ * BACK Normal "next" pointers all implicitly point forward; BACK
+ * exists to make loop structures possible.
+ *
+ * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
+ * BRANCH structures using BACK. Simple cases (one character
+ * per match) are implemented with STAR and PLUS for speed
+ * and to minimize recursive plunges.
+ *
+ * OPEN,CLOSE ...are numbered at compile time.
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit pieces, high order first. The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node. (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+#define OP(p) (*(p))
+#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
+#define OPERAND(p) ((p) + 3)
+
+/*
+ * See regmagic.h for one further detail of program structure.
+ */
+
+
+/*
+ * Utility definitions.
+ */
+#ifndef CHARBITS
+#define UCHARAT(p) ((int)*(unsigned char *)(p))
+#else
+#define UCHARAT(p) ((int)*(p)&CHARBITS)
+#endif
+
+#define FAIL(m) { regerror(m); return(NULL); }
+#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
+#define META "^$.[()|?+*\\"
+
+/*
+ * Flags to be passed up and down.
+ */
+#define HASWIDTH 01 /* Known never to match null string. */
+#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
+#define SPSTART 04 /* Starts with * or +. */
+#define WORST 0 /* Worst case. */
+
+/*
+ * Global work variables for regcomp().
+ */
+static char *regparse; /* Input-scan pointer. */
+static int regnpar; /* () count. */
+static char regdummy;
+static char *regcode; /* Code-emit pointer; &regdummy = don't. */
+static long regsize; /* Code size. */
+
+/*
+ * The first byte of the regexp internal "program" is actually this magic
+ * number; the start node begins in the second byte.
+ */
+#define MAGIC 0234
+
+
+/*
+ * Forward declarations for regcomp()'s friends.
+ */
+#ifndef STATIC
+#define STATIC static
+#endif
+STATIC char *reg();
+STATIC char *regbranch();
+STATIC char *regpiece();
+STATIC char *regatom();
+STATIC char *regnode();
+STATIC char *regnext();
+STATIC void regc();
+STATIC void reginsert();
+STATIC void regtail();
+STATIC void regoptail();
+#ifdef STRCSPN
+STATIC int strcspn();
+#endif
+
+/* regcomp originally appeared here - DEL */
+
+/*
+ - reg - regular expression, i.e. main body or parenthesized thing
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+static char *
+reg(paren, flagp)
+int paren; /* Parenthesized? */
+int *flagp;
+{
+ register char *ret;
+ register char *br;
+ register char *ender;
+ register int parno = 0;
+ int flags;
+
+ *flagp = HASWIDTH; /* Tentatively. */
+
+ /* Make an OPEN node, if parenthesized. */
+ if (paren) {
+ if (regnpar >= NSUBEXP)
+ FAIL("too many ()");
+ parno = regnpar;
+ regnpar++;
+ ret = regnode(OPEN+parno);
+ } else
+ ret = NULL;
+
+ /* Pick up the branches, linking them together. */
+ br = regbranch(&flags);
+ if (br == NULL)
+ return(NULL);
+ if (ret != NULL)
+ regtail(ret, br); /* OPEN -> first. */
+ else
+ ret = br;
+ if (!(flags&HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags&SPSTART;
+ while (*regparse == '|') {
+ regparse++;
+ br = regbranch(&flags);
+ if (br == NULL)
+ return(NULL);
+ regtail(ret, br); /* BRANCH -> BRANCH. */
+ if (!(flags&HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags&SPSTART;
+ }
+
+ /* Make a closing node, and hook it on the end. */
+ ender = regnode((paren) ? CLOSE+parno : END);
+ regtail(ret, ender);
+
+ /* Hook the tails of the branches to the closing node. */
+ for (br = ret; br != NULL; br = regnext(br))
+ regoptail(br, ender);
+
+ /* Check for proper termination. */
+ if (paren && *regparse++ != ')') {
+ FAIL("unmatched ()");
+ } else if (!paren && *regparse != '\0') {
+ if (*regparse == ')') {
+ FAIL("unmatched ()");
+ } else
+ FAIL("junk on end"); /* "Can't happen". */
+ /* NOTREACHED */
+ }
+
+ return(ret);
+}
+
+/*
+ - regbranch - one alternative of an | operator
+ *
+ * Implements the concatenation operator.
+ */
+static char *
+regbranch(flagp)
+int *flagp;
+{
+ register char *ret;
+ register char *chain;
+ register char *latest;
+ int flags;
+
+ *flagp = WORST; /* Tentatively. */
+
+ ret = regnode(BRANCH);
+ chain = NULL;
+ while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
+ latest = regpiece(&flags);
+ if (latest == NULL)
+ return(NULL);
+ *flagp |= flags&HASWIDTH;
+ if (chain == NULL) /* First piece. */
+ *flagp |= flags&SPSTART;
+ else
+ regtail(chain, latest);
+ chain = latest;
+ }
+ if (chain == NULL) /* Loop ran zero times. */
+ (void) regnode(NOTHING);
+
+ return(ret);
+}
+
+/*
+ - regpiece - something followed by possible [*+?]
+ *
+ * Note that the branching code sequences used for ? and the general cases
+ * of * and + are somewhat optimized: they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+static char *
+regpiece(flagp)
+int *flagp;
+{
+ register char *ret;
+ register char op;
+ register char *next;
+ int flags;
+
+ ret = regatom(&flags);
+ if (ret == NULL)
+ return(NULL);
+
+ op = *regparse;
+ if (!ISMULT(op)) {
+ *flagp = flags;
+ return(ret);
+ }
+
+ if (!(flags&HASWIDTH) && op != '?')
+ FAIL("*+ operand could be empty");
+ *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
+
+ if (op == '*' && (flags&SIMPLE))
+ reginsert(STAR, ret);
+ else if (op == '*') {
+ /* Emit x* as (x&|), where & means "self". */
+ reginsert(BRANCH, ret); /* Either x */
+ regoptail(ret, regnode(BACK)); /* and loop */
+ regoptail(ret, ret); /* back */
+ regtail(ret, regnode(BRANCH)); /* or */
+ regtail(ret, regnode(NOTHING)); /* null. */
+ } else if (op == '+' && (flags&SIMPLE))
+ reginsert(PLUS, ret);
+ else if (op == '+') {
+ /* Emit x+ as x(&|), where & means "self". */
+ next = regnode(BRANCH); /* Either */
+ regtail(ret, next);
+ regtail(regnode(BACK), ret); /* loop back */
+ regtail(next, regnode(BRANCH)); /* or */
+ regtail(ret, regnode(NOTHING)); /* null. */
+ } else if (op == '?') {
+ /* Emit x? as (x|) */
+ reginsert(BRANCH, ret); /* Either x */
+ regtail(ret, regnode(BRANCH)); /* or */
+ next = regnode(NOTHING); /* null. */
+ regtail(ret, next);
+ regoptail(ret, next);
+ }
+ regparse++;
+ if (ISMULT(*regparse))
+ FAIL("nested *?+");
+
+ return(ret);
+}
+
+/*
+ - regatom - the lowest level
+ *
+ * Optimization: gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run. Backslashed characters are exceptions, each becoming a
+ * separate node; the code is simpler that way and it's not worth fixing.
+ */
+static char *
+regatom(flagp)
+int *flagp;
+{
+ register char *ret;
+ int flags;
+
+ *flagp = WORST; /* Tentatively. */
+
+ switch (*regparse++) {
+ case '^':
+ ret = regnode(BOL);
+ break;
+ case '$':
+ ret = regnode(EOL);
+ break;
+ case '.':
+ ret = regnode(ANY);
+ *flagp |= HASWIDTH|SIMPLE;
+ break;
+ case '[': {
+ register int clss;
+ register int classend;
+
+ if (*regparse == '^') { /* Complement of range. */
+ ret = regnode(ANYBUT);
+ regparse++;
+ } else
+ ret = regnode(ANYOF);
+ if (*regparse == ']' || *regparse == '-')
+ regc(*regparse++);
+ while (*regparse != '\0' && *regparse != ']') {
+ if (*regparse == '-') {
+ regparse++;
+ if (*regparse == ']' || *regparse == '\0')
+ regc('-');
+ else {
+ clss = UCHARAT(regparse-2)+1;
+ classend = UCHARAT(regparse);
+ if (clss > classend+1)
+ FAIL("invalid [] range");
+ for (; clss <= classend; clss++)
+ regc((char)clss);
+ regparse++;
+ }
+ } else
+ regc(*regparse++);
+ }
+ regc('\0');
+ if (*regparse != ']')
+ FAIL("unmatched []");
+ regparse++;
+ *flagp |= HASWIDTH|SIMPLE;
+ }
+ break;
+ case '(':
+ ret = reg(1, &flags);
+ if (ret == NULL)
+ return(NULL);
+ *flagp |= flags&(HASWIDTH|SPSTART);
+ break;
+ case '\0':
+ case '|':
+ case ')':
+ FAIL("internal urp"); /* Supposed to be caught earlier. */
+ /* NOTREACHED */
+ break;
+ case '?':
+ case '+':
+ case '*':
+ FAIL("?+* follows nothing");
+ /* NOTREACHED */
+ break;
+ case '\\':
+ if (*regparse == '\0')
+ FAIL("trailing \\");
+ ret = regnode(EXACTLY);
+ regc(*regparse++);
+ regc('\0');
+ *flagp |= HASWIDTH|SIMPLE;
+ break;
+ default: {
+ register int len;
+ register char ender;
+
+ regparse--;
+ len = strcspn(regparse, META);
+ if (len <= 0)
+ FAIL("internal disaster");
+ ender = *(regparse+len);
+ if (len > 1 && ISMULT(ender))
+ len--; /* Back off clear of ?+* operand. */
+ *flagp |= HASWIDTH;
+ if (len == 1)
+ *flagp |= SIMPLE;
+ ret = regnode(EXACTLY);
+ while (len > 0) {
+ regc(*regparse++);
+ len--;
+ }
+ regc('\0');
+ }
+ break;
+ }
+
+ return(ret);
+}
+
+/*
+ - regnode - emit a node
+ */
+static char * /* Location. */
+regnode(op)
+int op;
+{
+ register char *ret;
+ register char *ptr;
+
+ ret = regcode;
+ if (ret == &regdummy) {
+ regsize += 3;
+ return(ret);
+ }
+
+ ptr = ret;
+ *ptr++ = (char)op;
+ *ptr++ = '\0'; /* Null "next" pointer. */
+ *ptr++ = '\0';
+ regcode = ptr;
+
+ return(ret);
+}
+
+/*
+ - regc - emit (if appropriate) a byte of code
+ */
+static void
+regc(b)
+int b;
+{
+ if (regcode != &regdummy)
+ *regcode++ = (char)b;
+ else
+ regsize++;
+}
+
+/*
+ - reginsert - insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+static void
+reginsert(op, opnd)
+int op;
+char *opnd;
+{
+ register char *src;
+ register char *dst;
+ register char *place;
+
+ if (regcode == &regdummy) {
+ regsize += 3;
+ return;
+ }
+
+ src = regcode;
+ regcode += 3;
+ dst = regcode;
+ while (src > opnd)
+ *--dst = *--src;
+
+ place = opnd; /* Op node, where operand used to be. */
+ *place++ = (char)op;
+ *place++ = '\0';
+ *place = '\0';
+}
+
+/*
+ - regtail - set the next-pointer at the end of a node chain
+ */
+static void
+regtail(p, val)
+char *p;
+char *val;
+{
+ register char *scan;
+ register char *temp;
+ register int offset;
+
+ if (p == &regdummy)
+ return;
+
+ /* Find last node. */
+ scan = p;
+ for (;;) {
+ temp = regnext(scan);
+ if (temp == NULL)
+ break;
+ scan = temp;
+ }
+
+ if (OP(scan) == BACK)
+ offset = scan - val;
+ else
+ offset = val - scan;
+ *(scan+1) = (char)(offset>>8)&0377;
+ *(scan+2) = (char)offset&0377;
+}
+
+/*
+ - regoptail - regtail on operand of first argument; nop if operandless
+ */
+static void
+regoptail(p, val)
+char *p;
+char *val;
+{
+ /* "Operandless" and "op != BRANCH" are synonymous in practice. */
+ if (p == NULL || p == &regdummy || OP(p) != BRANCH)
+ return;
+ regtail(OPERAND(p), val);
+}
+
+/*
+ * regexec and friends
+ */
+
+/*
+ * Global work variables for regexec().
+ */
+static char *reginput; /* String-input pointer. */
+NOTSTATIC char *regbol; /* Beginning of input, for ^ check. */
+static char **regstartp; /* Pointer to startp array. */
+static char **regendp; /* Ditto for endp. */
+
+/*
+ * Forwards.
+ */
+
+NOTSTATIC int regtry();
+STATIC int regmatch();
+STATIC int regrepeat();
+
+#ifdef DEBUG
+int regnarrate = 0;
+void regdump();
+STATIC char *regprop();
+#endif
+
+#if 0
+/*
+ - regexec - match a regexp against a string
+ */
+int
+regexec(prog, string, stringlength, matchlength)
+register regexp *prog;
+register char *string; /* note: CURRENTLY ASSUMED TO BE NULL-TERMINATED!!! */
+int stringlength; /* length of string */
+int *matchlength; /* number of chars matched (or to be skipped) */
+ /* set when MATCH or CANT_MATCH */
+{
+ register char *s;
+ extern char *strchr();
+
+ /* Be paranoid... */
+ if (prog == NULL || string == NULL) {
+ regerror("NULL parameter");
+ return(EXP_TCLERROR);
+ }
+
+ /* Check validity of program. */
+ if (UCHARAT(prog->program) != MAGIC) {
+ regerror("corrupted program");
+ return(EXP_KM_ERROR);
+ }
+
+#if THIS_RUINS_EXP
+/* no need for this shortcut anyway */
+ /* If there is a "must appear" string, look for it. */
+ if (prog->regmust != NULL) {
+ s = string;
+ while ((s = strchr(s, prog->regmust[0])) != NULL) {
+ if (strncmp(s, prog->regmust, prog->regmlen) == 0)
+ break; /* Found it. */
+ s++;
+ }
+ if (s == NULL) /* Not present. */
+ return(0);
+ }
+#endif
+
+ /* Mark beginning of line for ^ . */
+ regbol = string;
+
+ /* Simplest case: anchored match need be tried only once. */
+ if (prog->reganch) {
+ int r = regtry(prog,string,matchlength);
+ if (r == CANT_MATCH) *matchlength = stringlength;
+ return(r);
+ }
+
+ /* Messy cases: unanchored match. */
+ s = string;
+ if (prog->regstart != '\0') {
+ register char *s2 = s;
+
+ /* We know what char it must start with. */
+ while (1) {
+ int r;
+
+ s2 = strchr(s2,prog->regstart);
+ if (s2 == 0) {
+ *matchlength = stringlength;
+ return(CANT_MATCH);
+ }
+ r = regtry(prog,s2,matchlength);
+ if (r == CANT_MATCH) {
+ s2++;
+ continue;
+ }
+ if (s2 == s) return(r);
+ *matchlength = s2-s;
+ return CANT_MATCH;
+ }
+ } else {
+ /* We don't -- general case. */
+ register char *s2 = s;
+ int r = regtry(prog,s,matchlength);
+ if (r == EXP_MATCH) return(r);
+ else if (r == EXP_CANMATCH) return(r);
+ /* at this point, we know some characters at front */
+ /* of string don't match */
+ for (s2++;*s2;s2++) {
+ r = regtry(prog,s2,matchlength);
+ if (r == CANT_MATCH) continue;
+ /* if we match or can_match, say cant_match and */
+ /* record the number of chars at front that don't match */
+ *matchlength = s2-s;
+ return(CANT_MATCH);
+ }
+ /* made it thru string with CANT_MATCH all the way */
+ *matchlength = stringlength;
+ return(CANT_MATCH);
+ }
+}
+#endif
+
+/*
+ - regtry - try match at specific point
+ */
+/* return CAN_MATCH, CANT_MATCH or MATCH */
+int /* 0 failure, 1 success */
+regtry(prog, string, matchlength)
+regexp *prog;
+char *string;
+int *matchlength; /* only set for MATCH */
+{
+ register int i;
+ register char **sp;
+ register char **ep;
+ int r; /* result of regmatch */
+
+ reginput = string;
+ regstartp = prog->startp;
+ regendp = prog->endp;
+
+ sp = prog->startp;
+ ep = prog->endp;
+ for (i = NSUBEXP; i > 0; i--) {
+ *sp++ = NULL;
+ *ep++ = NULL;
+ }
+ r = regmatch(prog->program + 1);
+ if (EXP_MATCH == r) {
+ prog->startp[0] = string;
+ prog->endp[0] = reginput;
+ *matchlength = reginput-string;
+ return(EXP_MATCH);
+ }
+ return(r); /* CAN_MATCH or CANT_MATCH */
+}
+
+/*
+ - regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple: check to see whether the current
+ * node matches, call self recursively to see whether the rest matches,
+ * and then act accordingly. In practice we make some effort to avoid
+ * recursion, in particular by going through "ordinary" nodes (that don't
+ * need to know whether the rest of the match failed) by a loop instead of
+ * by recursion.
+ */
+/* returns CAN, CANT or MATCH */
+static int /* 0 failure, 1 success */
+regmatch(prog)
+char *prog;
+{
+ register char *scan; /* Current node. */
+ char *next; /* Next node. */
+#ifndef strchr /* May be #defined to something else */
+ extern char *strchr();
+#endif
+
+ scan = prog;
+#ifdef DEBUG
+ if (scan != NULL && regnarrate)
+ fprintf(stderr, "%s(\n", regprop(scan));
+#endif
+ while (scan != NULL) {
+#ifdef DEBUG
+ if (regnarrate)
+ fprintf(stderr, "%s...\n", regprop(scan));
+#endif
+ next = regnext(scan);
+
+ switch (OP(scan)) {
+ case BOL:
+ if (reginput != regbol)
+/* return(0);*/
+ return(EXP_CANTMATCH);
+ break;
+ case EOL:
+ if (*reginput != '\0')
+/* return(0);*/
+/* note this implies that "$" must match everything received to this point! */
+ return(EXP_CANTMATCH);
+ break;
+ case ANY:
+ if (*reginput == '\0')
+/* return(0);*/
+ return(EXP_CANMATCH);
+ reginput++;
+ break;
+ case EXACTLY: {
+/* register int len;*/
+ register char *opnd;
+
+ opnd = OPERAND(scan);
+
+ /* this section of code is totally rewritten - DEL */
+ /* group of literal chars in pattern */
+ /* compare each one */
+ do {
+ if (*opnd != *reginput) {
+ if (*reginput == '\0') {
+ return EXP_CANMATCH;
+ } else return EXP_CANTMATCH;
+ }
+
+ reginput++;
+ opnd++;
+ } while (*opnd != '\0');
+ }
+ break;
+ case ANYOF:
+/* if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
+ return(0);
+*/
+ if (*reginput == '\0')
+ return(EXP_CANMATCH);
+ if (strchr(OPERAND(scan),*reginput) == NULL)
+ return(EXP_CANTMATCH);
+ reginput++;
+ break;
+ case ANYBUT:
+/* if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
+ return(0);
+*/
+ if (*reginput == '\0')
+ return(EXP_CANMATCH);
+ if (strchr(OPERAND(scan),*reginput) != NULL)
+ return(EXP_CANTMATCH);
+ reginput++;
+ break;
+ case NOTHING:
+ break;
+ case BACK:
+ break;
+ case OPEN+1:
+ case OPEN+2:
+ case OPEN+3:
+ case OPEN+4:
+ case OPEN+5:
+ case OPEN+6:
+ case OPEN+7:
+ case OPEN+8:
+ case OPEN+9: {
+ register int no;
+ register char *save;
+ int r; /* result of regmatch */
+
+ doOpen:
+ no = OP(scan) - OPEN;
+ save = reginput;
+
+ r = regmatch(next);
+ if (r == EXP_MATCH) {
+ /*
+ * Don't set startp if some later
+ * invocation of the same parentheses
+ * already has.
+ */
+ if (regstartp[no] == NULL)
+ regstartp[no] = save;
+ }
+ return(r);
+ }
+ /* NOTREACHED */
+ break;
+ case CLOSE+1:
+ case CLOSE+2:
+ case CLOSE+3:
+ case CLOSE+4:
+ case CLOSE+5:
+ case CLOSE+6:
+ case CLOSE+7:
+ case CLOSE+8:
+ case CLOSE+9: {
+ register int no;
+ register char *save;
+ int r; /* result of regmatch */
+
+ doClose:
+ no = OP(scan) - CLOSE;
+ save = reginput;
+
+ r = regmatch(next);
+ if (r == EXP_MATCH) {
+ /*
+ * Don't set endp if some later
+ * invocation of the same parentheses
+ * already has.
+ */
+ if (regendp[no] == NULL)
+ regendp[no] = save;
+ }
+ return(r);
+ }
+ /* NOTREACHED */
+ break;
+ case BRANCH: {
+ register char *save;
+ int match_status;
+
+ if (OP(next) != BRANCH) /* No choice. */
+ next = OPERAND(scan); /* Avoid recursion. */
+ else {
+ match_status = EXP_CANTMATCH;
+
+ do {
+ int r;
+
+ save = reginput;
+ r = regmatch(OPERAND(scan));
+ if (r == EXP_MATCH) return(r);
+ if (r == EXP_CANMATCH) {
+ match_status = r;
+ }
+ reginput = save;
+ scan = regnext(scan);
+ } while (scan != NULL && OP(scan) == BRANCH);
+ return(match_status);
+ /* NOTREACHED */
+ }
+ }
+ /* NOTREACHED */
+ break;
+ case STAR:
+ case PLUS: {
+ register char nextch;
+ register int no;
+ register char *save;
+ register int min;
+ int match_status;
+
+ /*
+ * Lookahead to avoid useless match attempts
+ * when we know what character comes next.
+ */
+ match_status = EXP_CANTMATCH;
+ nextch = '\0';
+ if (OP(next) == EXACTLY)
+ nextch = *OPERAND(next);
+ min = (OP(scan) == STAR) ? 0 : 1;
+ save = reginput;
+ no = regrepeat(OPERAND(scan));
+ while (no >= min) {
+ /* If it could work, try it. */
+ /* 3rd condition allows for CAN_MATCH */
+ if (nextch == '\0' || *reginput == nextch || *reginput == '\0') {
+ int r = regmatch(next);
+ if (r == EXP_MATCH)
+ return(EXP_MATCH);
+ if (r == EXP_CANMATCH)
+ match_status = r;
+ }
+ /* Couldn't or didn't -- back up. */
+ no--;
+ reginput = save + no;
+ }
+ return(match_status);
+ }
+ /* NOTREACHED */
+ break;
+ case END:
+ return(EXP_MATCH); /* Success! */
+ /* NOTREACHED */
+ break;
+ default:
+ if (OP(scan) > OPEN && OP(scan) < OPEN+NSUBEXP) {
+ goto doOpen;
+ } else if (OP(scan) > CLOSE && OP(scan) < CLOSE+NSUBEXP) {
+ goto doClose;
+ }
+ regerror("memory corruption");
+ return(EXP_TCLERROR);
+ /* NOTREACHED */
+ break;
+ }
+
+ scan = next;
+ }
+
+ /*
+ * We get here only if there's trouble -- normally "case END" is
+ * the terminating point.
+ */
+ regerror("corrupted pointers");
+ return(EXP_TCLERROR);
+}
+
+/*
+ - regrepeat - repeatedly match something simple, report how many
+ */
+static int
+regrepeat(p)
+char *p;
+{
+ register int count = 0;
+ register char *scan;
+ register char *opnd;
+#ifndef strchr /* May be #defined to something else */
+/*DEL*/ extern char *strchr();
+#endif
+
+ scan = reginput;
+ opnd = OPERAND(p);
+ switch (OP(p)) {
+ case ANY:
+ count = strlen(scan);
+ scan += count;
+ break;
+ case EXACTLY:
+ while (*opnd == *scan) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYOF:
+ while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYBUT:
+ while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
+ count++;
+ scan++;
+ }
+ break;
+ default: /* Oh dear. Called inappropriately. */
+ regerror("internal foulup");
+ count = 0; /* Best compromise. */
+ break;
+ }
+ reginput = scan;
+
+ return(count);
+}
+
+/*
+ - regnext - dig the "next" pointer out of a node
+ */
+static char *
+regnext(p)
+register char *p;
+{
+ register int offset;
+
+ if (p == &regdummy)
+ return(NULL);
+
+ offset = NEXT(p);
+ if (offset == 0)
+ return(NULL);
+
+ if (OP(p) == BACK)
+ return(p-offset);
+ else
+ return(p+offset);
+}
+
+#ifdef DEBUG
+
+STATIC char *regprop();
+
+/*
+ - regdump - dump a regexp onto stdout in vaguely comprehensible form
+ */
+void
+regdump(r)
+regexp *r;
+{
+ register char *s;
+ register char op = EXACTLY; /* Arbitrary non-END op. */
+ register char *next;
+ extern char *strchr();
+
+
+ s = r->program + 1;
+ while (op != END) { /* While that wasn't END last time... */
+ op = OP(s);
+ printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
+ next = regnext(s);
+ if (next == NULL) /* Next ptr. */
+ printf("(0)");
+ else
+ printf("(%d)", (s-r->program)+(next-s));
+ s += 3;
+ if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
+ /* Literal string, where present. */
+ while (*s != '\0') {
+ putchar(*s);
+ s++;
+ }
+ s++;
+ }
+ putchar('\n');
+ }
+
+ /* Header fields of interest. */
+ if (r->regstart != '\0')
+ printf("start `%c' ", r->regstart);
+ if (r->reganch)
+ printf("anchored ");
+ if (r->regmust != NULL)
+ printf("must have \"%s\"", r->regmust);
+ printf("\n");
+}
+
+/*
+ - regprop - printable representation of opcode
+ */
+static char *
+regprop(op)
+char *op;
+{
+ register char *p;
+ static char buf[50];
+
+ (void) strcpy(buf, ":");
+
+ switch (OP(op)) {
+ case BOL:
+ p = "BOL";
+ break;
+ case EOL:
+ p = "EOL";
+ break;
+ case ANY:
+ p = "ANY";
+ break;
+ case ANYOF:
+ p = "ANYOF";
+ break;
+ case ANYBUT:
+ p = "ANYBUT";
+ break;
+ case BRANCH:
+ p = "BRANCH";
+ break;
+ case EXACTLY:
+ p = "EXACTLY";
+ break;
+ case NOTHING:
+ p = "NOTHING";
+ break;
+ case BACK:
+ p = "BACK";
+ break;
+ case END:
+ p = "END";
+ break;
+ case OPEN+1:
+ case OPEN+2:
+ case OPEN+3:
+ case OPEN+4:
+ case OPEN+5:
+ case OPEN+6:
+ case OPEN+7:
+ case OPEN+8:
+ case OPEN+9:
+ sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
+ p = NULL;
+ break;
+ case CLOSE+1:
+ case CLOSE+2:
+ case CLOSE+3:
+ case CLOSE+4:
+ case CLOSE+5:
+ case CLOSE+6:
+ case CLOSE+7:
+ case CLOSE+8:
+ case CLOSE+9:
+ sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
+ p = NULL;
+ break;
+ case STAR:
+ p = "STAR";
+ break;
+ case PLUS:
+ p = "PLUS";
+ break;
+ default:
+ if (OP(op) > OPEN && OP(op) < OPEN+NSUBEXP) {
+ sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
+ p = NULL;
+ break;
+ } else if (OP(op) > CLOSE && OP(op) < CLOSE+NSUBEXP) {
+ sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
+ p = NULL;
+ } else {
+ TclRegError("corrupted opcode");
+ }
+ break;
+ }
+ if (p != NULL)
+ (void) strcat(buf, p);
+ return(buf);
+}
+#endif
+
+/*
+ * The following is provided for those people who do not have strcspn() in
+ * their C libraries. They should get off their butts and do something
+ * about it; at least one public-domain implementation of those (highly
+ * useful) string routines has been published on Usenet.
+ */
+#ifdef STRCSPN
+/*
+ * strcspn - find length of initial segment of s1 consisting entirely
+ * of characters not from s2
+ */
+
+static int
+strcspn(s1, s2)
+char *s1;
+char *s2;
+{
+ register char *scan1;
+ register char *scan2;
+ register int count;
+
+ count = 0;
+ for (scan1 = s1; *scan1 != '\0'; scan1++) {
+ for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
+ if (*scan1 == *scan2++)
+ return(count);
+ count++;
+ }
+ return(count);
+}
+#endif
diff --git a/expect/exp_regexp.h b/expect/exp_regexp.h
new file mode 100644
index 00000000000..1107a7b17c7
--- /dev/null
+++ b/expect/exp_regexp.h
@@ -0,0 +1,8 @@
+/* access to regexp internals */
+#define regbol exp_regbol
+#define regtry exp_regtry
+#define regexec exp_regexec
+#define regerror TclRegError
+extern char *regbol;
+int regtry();
+
diff --git a/expect/exp_rename.h b/expect/exp_rename.h
new file mode 100644
index 00000000000..be67efb7a07
--- /dev/null
+++ b/expect/exp_rename.h
@@ -0,0 +1,22 @@
+/* translate.h - preface globals that appear in the expect library
+with "exp_" so we don't conflict with the user. This saves me having
+to use exp_XXX throughout the expect program itself, which was written
+well before the library when I didn't have to worry about name conflicts.
+
+Written by: Don Libes, NIST, 12/3/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+#define errorlog exp_errorlog
+#define debuglog exp_debuglog
+#define is_debugging exp_is_debugging
+#define logfile exp_logfile
+#define debugfile exp_debugfile
+#define loguser exp_loguser
+#define logfile_all exp_logfile_all
+
+#define getptymaster exp_getptymaster
+#define getptyslave exp_getptyslave
diff --git a/expect/exp_select.c b/expect/exp_select.c
new file mode 100644
index 00000000000..c404cf20a28
--- /dev/null
+++ b/expect/exp_select.c
@@ -0,0 +1,290 @@
+/* exp_select.c - select() interface for Expect
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+/* suppress file-empty warnings produced by some compilers */
+void exp_unused() {}
+
+#if 0 /* WHOLE FILE!!!! */
+#include "expect_cf.h"
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYSSELECT_H
+# include <sys/select.h> /* Intel needs this for timeval */
+#endif
+
+#ifdef HAVE_PTYTRAP
+# include <sys/ptyio.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef _AIX
+/* AIX has some unusual definition of FD_SET */
+#include <sys/select.h>
+#endif
+
+#if !defined( FD_SET ) && defined( HAVE_SYS_BSDTYPES_H )
+ /* like AIX, ISC has it's own definition of FD_SET */
+# include <sys/bsdtypes.h>
+#endif /* ! FD_SET && HAVE_SYS_BSDTYPES_H */
+
+#include "tcl.h"
+#include "exp_prog.h"
+#include "exp_command.h" /* for struct exp_f defs */
+#include "exp_event.h"
+
+#ifdef HAVE_SYSCONF_H
+#include <sys/sysconfig.h>
+#endif
+
+#ifndef FD_SET
+#define FD_SET(fd,fdset) (fdset)->fds_bits[0] |= (1<<(fd))
+#define FD_CLR(fd,fdset) (fdset)->fds_bits[0] &= ~(1<<(fd))
+#define FD_ZERO(fdset) (fdset)->fds_bits[0] = 0
+#define FD_ISSET(fd,fdset) (((fdset)->fds_bits[0]) & (1<<(fd)))
+#ifndef AUX2
+typedef struct fd_set {
+ long fds_bits[1];
+ /* any implementation so pathetic as to not define FD_SET will just */
+ /* have to suffer with only 32 bits worth of fds */
+} fd_set;
+#endif /* AUX2 */
+#endif
+
+static struct timeval zerotime = {0, 0};
+static struct timeval anytime = {0, 0}; /* can be changed by user */
+
+/* returns status, one of EOF, TIMEOUT, ERROR or DATA */
+int
+exp_get_next_event(interp,masters, n,master_out,timeout,key)
+Tcl_Interp *interp;
+int *masters;
+int n; /* # of masters */
+int *master_out; /* 1st event master, not set if none */
+int timeout; /* seconds */
+int key;
+{
+ static rr = 0; /* round robin ptr */
+
+ int i; /* index into in-array */
+ struct timeval *t;
+
+ fd_set rdrs;
+ fd_set excep;
+/* FIXME: This is really gross, but the folks at Lynx said their select is
+ * way hosed and to ignore all exceptions.
+ */
+#ifdef __Lynx__
+#define EXCEP 0
+#else
+#define EXCEP &excep
+#endif
+
+ for (i=0;i<n;i++) {
+ struct exp_f *f;
+ int m;
+
+ rr++;
+ if (rr >= n) rr = 0;
+
+ m = masters[rr];
+ f = exp_fs + m;
+
+ if (f->key != key) {
+ f->key = key;
+ f->force_read = FALSE;
+ *master_out = m;
+ return(EXP_DATA_OLD);
+ } else if ((!f->force_read) && (f->size != 0)) {
+ *master_out = m;
+ return(EXP_DATA_OLD);
+ }
+ }
+
+ if (timeout >= 0) {
+ t = &anytime;
+ t->tv_sec = timeout;
+ } else {
+ t = NULL;
+ }
+
+ restart:
+ if (Tcl_AsyncReady()) {
+ int rc = Tcl_AsyncInvoke(interp,TCL_OK);
+ if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc));
+
+ /* anything in the environment could have changed */
+ return EXP_RECONFIGURE;
+ }
+
+ FD_ZERO(&rdrs);
+ FD_ZERO(&excep);
+ for (i = 0;i < n;i++) {
+ FD_SET(masters[i],&rdrs);
+ FD_SET(masters[i],&excep);
+ }
+
+ /* The reason all fd masks are (seemingly) redundantly cast to */
+ /* SELECT_MASK_TYPE is that the HP defines its mask in terms of */
+ /* of int * and yet defines FD_SET in terms of fd_set. */
+
+ if (-1 == select(exp_fd_max+1,
+ (SELECT_MASK_TYPE *)&rdrs,
+ (SELECT_MASK_TYPE *)0,
+ (SELECT_MASK_TYPE *)EXCEP,
+ t)) {
+ /* window refreshes trigger EINTR, ignore */
+ if (errno == EINTR) goto restart;
+ else if (errno == EBADF) {
+ /* someone is rotten */
+ for (i=0;i<n;i++) {
+ fd_set suspect;
+ FD_ZERO(&suspect);
+ FD_SET(masters[i],&suspect);
+ if (-1 == select(exp_fd_max+1,
+ (SELECT_MASK_TYPE *)&suspect,
+ (SELECT_MASK_TYPE *)0,
+ (SELECT_MASK_TYPE *)0,
+ &zerotime)) {
+ exp_error(interp,"invalid spawn_id (%d)\r",masters[i]);
+ return(EXP_TCLERROR);
+ }
+ }
+ } else {
+ /* not prepared to handle anything else */
+ exp_error(interp,"select: %s\r",Tcl_PosixError(interp));
+ return(EXP_TCLERROR);
+ }
+ }
+
+ for (i=0;i<n;i++) {
+ rr++;
+ if (rr >= n) rr = 0; /* ">" catches previous readys that */
+ /* used more fds then we're using now */
+
+ if (FD_ISSET(masters[rr],&rdrs)) {
+ *master_out = masters[rr];
+ return(EXP_DATA_NEW);
+/*#ifdef HAVE_PTYTRAP*/
+ } else if (FD_ISSET(masters[rr], &excep)) {
+#ifndef HAVE_PTYTRAP
+ *master_out = masters[rr];
+ return(EXP_EOF);
+#else
+ struct request_info ioctl_info;
+ if (ioctl(masters[rr],TIOCREQCHECK,&ioctl_info) < 0) {
+ exp_debuglog("ioctl error on TIOCREQCHECK: %s",Tcl_ErrnoMsg(errno));
+ break;
+ }
+ if (ioctl_info.request == TIOCCLOSE) {
+ /* eof */
+ *master_out = masters[rr];
+ return(EXP_EOF);
+ }
+ if (ioctl(masters[rr], TIOCREQSET, &ioctl_info) < 0)
+ exp_debuglog("ioctl error on TIOCREQSET after ioctl or open on slave: %s", Tcl_ErrnoMsg(errno));
+ /* presumably, we trapped an open here */
+ goto restart;
+#endif /* HAVE_PTYTRAP */
+ }
+ }
+ return(EXP_TIMEOUT);
+}
+
+/*ARGSUSED*/
+int
+exp_get_next_event_info(interp,fd,ready_mask)
+Tcl_Interp *interp;
+int fd;
+int ready_mask;
+{
+ /* this function is only used when running with Tk */
+ /* hence, it is merely a stub in this file but to */
+ /* pacify lint, return something */
+ return 0;
+}
+
+int /* returns TCL_XXX */
+exp_dsleep(interp,sec)
+Tcl_Interp *interp;
+double sec;
+{
+ struct timeval t;
+
+ t.tv_sec = sec;
+ t.tv_usec = (sec - t.tv_sec) * 1000000L;
+ restart:
+ if (Tcl_AsyncReady()) {
+ int rc = Tcl_AsyncInvoke(interp,TCL_OK);
+ if (rc != TCL_OK) return rc;
+ }
+ if (-1 == select(1,
+ (SELECT_MASK_TYPE *)0,
+ (SELECT_MASK_TYPE *)0,
+ (SELECT_MASK_TYPE *)0,
+ &t)
+ && errno == EINTR)
+ goto restart;
+ return TCL_OK;
+}
+
+#if 0
+int /* returns TCL_XXX */
+exp_usleep(interp,usec)
+Tcl_Interp *interp;
+long usec; /* microseconds */
+{
+ struct timeval t;
+
+ t.tv_sec = usec/1000000L;
+ t.tv_usec = usec%1000000L;
+ restart:
+ if (Tcl_AsyncReady()) {
+ int rc = Tcl_AsyncInvoke(interp,TCL_OK);
+ if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc));
+ }
+ if (-1 == select(1,
+ (SELECT_MASK_TYPE *)0,
+ (SELECT_MASK_TYPE *)0,
+ (SELECT_MASK_TYPE *)0,
+ &t)
+ && errno == EINTR)
+ goto restart;
+ return TCL_OK;
+}
+#endif /*0*/
+
+/* set things up for later calls to event handler */
+void
+exp_init_event()
+{
+#if 0
+#ifdef _SC_OPEN_MAX
+ maxfds = sysconf(_SC_OPEN_MAX);
+#else
+ maxfds = getdtablesize();
+#endif
+#endif
+
+ exp_event_exit = 0;
+}
+#endif /* WHOLE FILE !!!! */
diff --git a/expect/exp_simple.c b/expect/exp_simple.c
new file mode 100644
index 00000000000..3380a38f1e5
--- /dev/null
+++ b/expect/exp_simple.c
@@ -0,0 +1,467 @@
+/*
+ * tclUnixNotify.c --
+ *
+ * This file contains Unix-specific procedures for the notifier,
+ * which is the lowest-level part of the Tcl event loop. This file
+ * works together with ../generic/tclNotify.c.
+ *
+ * Copyright (c) 1995 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+static char sccsid[] = "@(#) tclUnixNotify.c 1.27 96/01/19 10:30:23";
+
+#include "tclInt.h"
+#include "tclPort.h"
+#include <signal.h>
+
+/*
+ * The information below is used to provide read, write, and
+ * exception masks to select during calls to Tcl_DoOneEvent.
+ */
+
+static fd_mask checkMasks[3*MASK_SIZE];
+ /* This array is used to build up the masks
+ * to be used in the next call to select.
+ * Bits are set in response to calls to
+ * Tcl_WatchFile. */
+static fd_mask readyMasks[3*MASK_SIZE];
+ /* This array reflects the readable/writable
+ * conditions that were found to exist by the
+ * last call to select. */
+static int numFdBits; /* Number of valid bits in checkMasks
+ * (one more than highest fd for which
+ * Tcl_WatchFile has been called). */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WatchFile --
+ *
+ * Arrange for Tcl_DoOneEvent to include this file in the masks
+ * for the next call to select. This procedure is invoked by
+ * event sources, which are in turn invoked by Tcl_DoOneEvent
+ * before it invokes select.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ *
+ * The notifier will generate a file event when the I/O channel
+ * given by fd next becomes ready in the way indicated by mask.
+ * If fd is already registered then the old mask will be replaced
+ * with the new one. Once the event is sent, the notifier will
+ * not send any more events about the fd until the next call to
+ * Tcl_NotifyFile.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_WatchFile(file, mask)
+ Tcl_File file; /* Generic file handle for a stream. */
+ int mask; /* OR'ed combination of TCL_READABLE,
+ * TCL_WRITABLE, and TCL_EXCEPTION:
+ * indicates conditions to wait for
+ * in select. */
+{
+ int fd, type, index;
+ fd_mask bit;
+
+ fd = (int) Tcl_GetFileInfo(file, &type);
+
+ if (type != TCL_UNIX_FD) {
+ panic("Tcl_WatchFile: unexpected file type");
+ }
+
+ if (fd >= FD_SETSIZE) {
+ panic("Tcl_WatchFile can't handle file id %d", fd);
+ }
+
+ index = fd/(NBBY*sizeof(fd_mask));
+ bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
+ if (mask & TCL_READABLE) {
+ checkMasks[index] |= bit;
+ }
+ if (mask & TCL_WRITABLE) {
+ (checkMasks+MASK_SIZE)[index] |= bit;
+ }
+ if (mask & TCL_EXCEPTION) {
+ (checkMasks+2*(MASK_SIZE))[index] |= bit;
+ }
+ if (numFdBits <= fd) {
+ numFdBits = fd+1;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FileReady --
+ *
+ * Indicates what conditions (readable, writable, etc.) were
+ * present on a file the last time the notifier invoked select.
+ * This procedure is typically invoked by event sources to see
+ * if they should queue events.
+ *
+ * Results:
+ * The return value is 0 if none of the conditions specified by mask
+ * was true for fd the last time the system checked. If any of the
+ * conditions were true, then the return value is a mask of those
+ * that were true.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FileReady(file, mask)
+ Tcl_File file; /* Generic file handle for a stream. */
+ int mask; /* OR'ed combination of TCL_READABLE,
+ * TCL_WRITABLE, and TCL_EXCEPTION:
+ * indicates conditions caller cares about. */
+{
+ int index, result, type, fd;
+ fd_mask bit;
+
+ fd = (int) Tcl_GetFileInfo(file, &type);
+ if (type != TCL_UNIX_FD) {
+ panic("Tcl_FileReady: unexpected file type");
+ }
+
+ index = fd/(NBBY*sizeof(fd_mask));
+ bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
+ result = 0;
+ if ((mask & TCL_READABLE) && (readyMasks[index] & bit)) {
+ result |= TCL_READABLE;
+ }
+ if ((mask & TCL_WRITABLE) && ((readyMasks+MASK_SIZE)[index] & bit)) {
+ result |= TCL_WRITABLE;
+ }
+ if ((mask & TCL_EXCEPTION) && ((readyMasks+(2*MASK_SIZE))[index] & bit)) {
+ result |= TCL_EXCEPTION;
+ }
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WaitForEvent --
+ *
+ * This procedure does the lowest level wait for events in a
+ * platform-specific manner. It uses information provided by
+ * previous calls to Tcl_WatchFile, plus the timePtr argument,
+ * to determine what to wait for and how long to wait.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May put the process to sleep for a while, depending on timePtr.
+ * When this procedure returns, an event of interest to the application
+ * has probably, but not necessarily, occurred.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_WaitForEvent(timePtr)
+ Tcl_Time *timePtr; /* Specifies the maximum amount of time
+ * that this procedure should block before
+ * returning. The time is given as an
+ * interval, not an absolute wakeup time.
+ * NULL means block forever. */
+{
+ struct timeval timeout, *timeoutPtr;
+ int numFound;
+
+ memcpy((VOID *) readyMasks, (VOID *) checkMasks,
+ 3*MASK_SIZE*sizeof(fd_mask));
+ if (timePtr == NULL) {
+ timeoutPtr = NULL;
+ } else {
+ timeoutPtr = &timeout;
+ timeout.tv_sec = timePtr->sec;
+ timeout.tv_usec = timePtr->usec;
+ }
+ numFound = select(numFdBits, (SELECT_MASK *) &readyMasks[0],
+ (SELECT_MASK *) &readyMasks[MASK_SIZE],
+ (SELECT_MASK *) &readyMasks[2*MASK_SIZE], timeoutPtr);
+
+ /*
+ * Some systems don't clear the masks after an error, so
+ * we have to do it here.
+ */
+
+ if (numFound == -1) {
+ memset((VOID *) readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
+ }
+
+ /*
+ * Reset the check masks in preparation for the next call to
+ * select.
+ */
+
+ numFdBits = 0;
+ memset((VOID *) checkMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Sleep --
+ *
+ * Delay execution for the specified number of milliseconds.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Time passes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_Sleep(ms)
+ int ms; /* Number of milliseconds to sleep. */
+{
+ static struct timeval delay;
+ Tcl_Time before, after;
+
+ /*
+ * The only trick here is that select appears to return early
+ * under some conditions, so we have to check to make sure that
+ * the right amount of time really has elapsed. If it's too
+ * early, go back to sleep again.
+ */
+
+ TclGetTime(&before);
+ after = before;
+ after.sec += ms/1000;
+ after.usec += (ms%1000)*1000;
+ if (after.usec > 1000000) {
+ after.usec -= 1000000;
+ after.sec += 1;
+ }
+ while (1) {
+ delay.tv_sec = after.sec - before.sec;
+ delay.tv_usec = after.usec - before.usec;
+ if (delay.tv_usec < 0) {
+ delay.tv_usec += 1000000;
+ delay.tv_sec -= 1;
+ }
+
+ /*
+ * Special note: must convert delay.tv_sec to int before comparing
+ * to zero, since delay.tv_usec is unsigned on some platforms.
+ */
+
+ if ((((int) delay.tv_sec) < 0)
+ || ((delay.tv_usec == 0) && (delay.tv_sec == 0))) {
+ break;
+ }
+ (void) select(0, (SELECT_MASK *) 0, (SELECT_MASK *) 0,
+ (SELECT_MASK *) 0, &delay);
+ TclGetTime(&before);
+ }
+}
+
+
+
+
+
+
+
+#if 0 /* WHOLE FILE */
+
+
+
+/* interact (with only one process) - give user keyboard control
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+/* This file exists for deficient versions of UNIX that lack select,
+poll, or some other multiplexing hook. Instead, this code uses two
+processes per spawned process. One sends characters from the spawnee
+to the spawner; a second send chars the other way.
+
+This will work on any UNIX system. The only sacrifice is that it
+doesn't support multiple processes. Eventually, it should catch
+SIGCHLD on dead processes and do the right thing. But it is pretty
+gruesome to imagine so many processes to do all this. If you change
+it successfully, please mail back the changes to me. - Don
+*/
+
+#include "expect_cf.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#include "tcl.h"
+#include "exp_prog.h"
+#include "exp_command.h" /* for struct exp_f defs */
+#include "exp_event.h"
+
+/*ARGSUSED*/
+void
+exp_arm_background_filehandler(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_disarm_background_filehandler(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_disarm_background_filehandler_force(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_unblock_background_filehandler(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_block_background_filehandler(m)
+int m;
+{
+}
+
+/*ARGSUSED*/
+void
+exp_event_disarm(fd)
+int fd;
+{
+}
+
+/* returns status, one of EOF, TIMEOUT, ERROR or DATA */
+/*ARGSUSED*/
+int
+exp_get_next_event(interp,masters, n,master_out,timeout,key)
+Tcl_Interp *interp;
+int *masters;
+int n; /* # of masters */
+int *master_out; /* 1st event master, not set if none */
+int timeout; /* seconds */
+int key;
+{
+ int m;
+ struct exp_f *f;
+
+ if (n > 1) {
+ exp_error(interp,"expect not compiled with multiprocess support");
+ /* select a different INTERACT_TYPE in Makefile */
+ return(TCL_ERROR);
+ }
+
+ m = *master_out = masters[0];
+ f = exp_fs + m;
+
+ if (f->key != key) {
+ f->key = key;
+ f->force_read = FALSE;
+ return(EXP_DATA_OLD);
+ } else if ((!f->force_read) && (f->size != 0)) {
+ return(EXP_DATA_OLD);
+ }
+
+ return(EXP_DATA_NEW);
+}
+
+/*ARGSUSED*/
+int
+exp_get_next_event_info(interp,fd,ready_mask)
+Tcl_Interp *interp;
+int fd;
+int ready_mask;
+{
+}
+
+/* There is no portable way to do sub-second sleeps on such a system, so */
+/* do the next best thing (without a busy loop) and fake it: sleep the right */
+/* amount of time over the long run. Note that while "subtotal" isn't */
+/* reinitialized, it really doesn't matter for such a gross hack as random */
+/* scheduling pauses will easily introduce occasional one second delays. */
+int /* returns TCL_XXX */
+exp_dsleep(interp,sec)
+Tcl_Interp *interp;
+double sec;
+{
+ static double subtotal = 0;
+ int seconds;
+
+ subtotal += sec;
+ if (subtotal < 1) return TCL_OK;
+ seconds = subtotal;
+ subtotal -= seconds;
+ restart:
+ if (Tcl_AsyncReady()) {
+ int rc = Tcl_AsyncInvoke(interp,TCL_OK);
+ if (rc != TCL_OK) return(rc);
+ }
+ sleep(seconds);
+ return TCL_OK;
+}
+
+#if 0
+/* There is no portable way to do sub-second sleeps on such a system, so */
+/* do the next best thing (without a busy loop) and fake it: sleep the right */
+/* amount of time over the long run. Note that while "subtotal" isn't */
+/* reinitialized, it really doesn't matter for such a gross hack as random */
+/* scheduling pauses will easily introduce occasional one second delays. */
+int /* returns TCL_XXX */
+exp_usleep(interp,usec)
+Tcl_Interp *interp;
+long usec; /* microseconds */
+{
+ static subtotal = 0;
+ int seconds;
+
+ subtotal += usec;
+ if (subtotal < 1000000) return TCL_OK;
+ seconds = subtotal/1000000;
+ subtotal = subtotal%1000000;
+ restart:
+ if (Tcl_AsyncReady()) {
+ int rc = Tcl_AsyncInvoke(interp,TCL_OK);
+ if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc));
+ }
+ sleep(seconds);
+ return TCL_OK;
+}
+#endif /*0*/
+
+/* set things up for later calls to event handler */
+void
+exp_init_event()
+{
+ exp_event_exit = 0;
+}
+
+#endif /* WHOLE FILE! */
diff --git a/expect/exp_strf.c b/expect/exp_strf.c
new file mode 100644
index 00000000000..9f6779c89e2
--- /dev/null
+++ b/expect/exp_strf.c
@@ -0,0 +1,616 @@
+/* exp_strp.c - functions for exp_timestamp */
+/*
+ * strftime.c
+ *
+ * Public-domain implementation of ANSI C library routine.
+ *
+ * It's written in old-style C for maximal portability.
+ * However, since I'm used to prototypes, I've included them too.
+ *
+ * If you want stuff in the System V ascftime routine, add the SYSV_EXT define.
+ * For extensions from SunOS, add SUNOS_EXT.
+ * For stuff needed to implement the P1003.2 date command, add POSIX2_DATE.
+ * For VMS dates, add VMS_EXT.
+ * For complete POSIX semantics, add POSIX_SEMANTICS.
+ *
+ * The code for %c, %x, and %X now follows the 1003.2 specification for
+ * the POSIX locale.
+ * This version ignores LOCALE information.
+ * It also doesn't worry about multi-byte characters.
+ * So there.
+ *
+ * This file is also shipped with GAWK (GNU Awk), gawk specific bits of
+ * code are included if GAWK is defined.
+ *
+ * Arnold Robbins <arnold@skeeve.atl.ga.us>
+ * January, February, March, 1991
+ * Updated March, April 1992
+ * Updated April, 1993
+ * Updated February, 1994
+ * Updated May, 1994
+ * Updated January 1995
+ * Updated September 1995
+ *
+ * Fixes from ado@elsie.nci.nih.gov
+ * February 1991, May 1992
+ * Fixes from Tor Lillqvist tml@tik.vtt.fi
+ * May, 1993
+ * Further fixes from ado@elsie.nci.nih.gov
+ * February 1994
+ * %z code from chip@chinacat.unicom.com
+ * Applied September 1995
+ *
+ *
+ * Modified by Don Libes for Expect, 10/93 and 12/95.
+ * Forced POSIX semantics.
+ * Replaced inline/min/max stuff with a single range function.
+ * Removed tzset stuff.
+ * Commented out tzname stuff.
+ *
+ * According to Arnold, the current version of this code can ftp'd from
+ * ftp.mathcs.emory.edu:/pub/arnold/strftime.shar.gz
+ *
+ */
+
+#include "expect_cf.h"
+#include "tcl.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include "string.h"
+
+/* according to Karl Vogel, time.h is insufficient on Pyramid */
+/* following is recommended by autoconf */
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+
+
+#include <sys/types.h>
+
+#define SYSV_EXT 1 /* stuff in System V ascftime routine */
+#define POSIX2_DATE 1 /* stuff in Posix 1003.2 date command */
+
+#if defined(POSIX2_DATE) && ! defined(SYSV_EXT)
+#define SYSV_EXT 1
+#endif
+
+#if defined(POSIX2_DATE)
+#define adddecl(stuff) stuff
+#else
+#define adddecl(stuff)
+#endif
+
+#ifndef __STDC__
+#define const
+
+extern char *getenv();
+static int weeknumber();
+adddecl(static int iso8601wknum();)
+#else
+
+#ifndef strchr
+extern char *strchr(const char *str, int ch);
+#endif
+extern char *getenv(const char *v);
+static int weeknumber(const struct tm *timeptr, int firstweekday);
+adddecl(static int iso8601wknum(const struct tm *timeptr);)
+#endif
+
+/* attempt to use strftime to compute timezone, else fallback to */
+/* less portable ways */
+#if !defined(HAVE_STRFTIME)
+# if defined(HAVE_SV_TIMEZONE)
+extern char *tzname[2];
+extern int daylight;
+# else
+# if defined(HAVE_TIMEZONE)
+
+char *
+zone_name (tp)
+struct tm *tp;
+{
+ char *timezone ();
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday (&tv, &tz);
+
+ return timezone (tz.tz_minuteswest, tp->tm_isdst);
+}
+
+# endif /* HAVE_TIMEZONE */
+# endif /* HAVE_SV_TIMEZONE */
+#endif /* HAVE_STRFTIME */
+
+static int
+range(low,item,hi)
+int low, item, hi;
+{
+ if (item < low) return low;
+ if (item > hi) return hi;
+ return item;
+}
+
+/* strftime --- produce formatted time */
+
+void
+/*size_t*/
+#ifndef __STDC__
+exp_strftime(/*s,*/ format, timeptr, dstring)
+/*char *s;*/
+char *format;
+const struct tm *timeptr;
+Tcl_DString *dstring;
+#else
+/*exp_strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)*/
+exp_strftime(char *format, const struct tm *timeptr,Tcl_DString *dstring)
+#endif
+{
+ int copied; /* used to suppress copying when called recursively */
+
+#if 0
+ char *endp = s + maxsize;
+ char *start = s;
+#endif
+ char *percentptr;
+
+ char tbuf[100];
+ int i;
+
+ /* various tables, useful in North America */
+ static char *days_a[] = {
+ "Sun", "Mon", "Tue", "Wed",
+ "Thu", "Fri", "Sat",
+ };
+ static char *days_l[] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday",
+ };
+ static char *months_a[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+ };
+ static char *months_l[] = {
+ "January", "February", "March", "April",
+ "May", "June", "July", "August", "September",
+ "October", "November", "December",
+ };
+ static char *ampm[] = { "AM", "PM", };
+
+/* for (; *format && s < endp - 1; format++) {*/
+ for (; *format ; format++) {
+ tbuf[0] = '\0';
+ copied = 0; /* has not been copied yet */
+ percentptr = strchr(format,'%');
+ if (percentptr == 0) {
+ Tcl_DStringAppend(dstring,format,-1);
+ goto out;
+ } else if (percentptr != format) {
+ Tcl_DStringAppend(dstring,format,percentptr - format);
+ format = percentptr;
+ }
+#if 0
+ if (*format != '%') {
+ *s++ = *format;
+ continue;
+ }
+#endif
+ again:
+ switch (*++format) {
+ case '\0':
+ Tcl_DStringAppend(dstring,"%",1);
+#if 0
+ *s++ = '%';
+#endif
+ goto out;
+
+ case '%':
+ Tcl_DStringAppend(dstring,"%",1);
+ copied = 1;
+ break;
+#if 0
+ *s++ = '%';
+ continue;
+#endif
+
+ case 'a': /* abbreviated weekday name */
+ if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
+ strcpy(tbuf, "?");
+ else
+ strcpy(tbuf, days_a[timeptr->tm_wday]);
+ break;
+
+ case 'A': /* full weekday name */
+ if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
+ strcpy(tbuf, "?");
+ else
+ strcpy(tbuf, days_l[timeptr->tm_wday]);
+ break;
+
+#ifdef SYSV_EXT
+ case 'h': /* abbreviated month name */
+#endif
+ case 'b': /* abbreviated month name */
+ if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
+ strcpy(tbuf, "?");
+ else
+ strcpy(tbuf, months_a[timeptr->tm_mon]);
+ break;
+
+ case 'B': /* full month name */
+ if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
+ strcpy(tbuf, "?");
+ else
+ strcpy(tbuf, months_l[timeptr->tm_mon]);
+ break;
+
+ case 'c': /* appropriate date and time representation */
+ sprintf(tbuf, "%s %s %2d %02d:%02d:%02d %d",
+ days_a[range(0, timeptr->tm_wday, 6)],
+ months_a[range(0, timeptr->tm_mon, 11)],
+ range(1, timeptr->tm_mday, 31),
+ range(0, timeptr->tm_hour, 23),
+ range(0, timeptr->tm_min, 59),
+ range(0, timeptr->tm_sec, 61),
+ timeptr->tm_year + 1900);
+ break;
+
+ case 'd': /* day of the month, 01 - 31 */
+ i = range(1, timeptr->tm_mday, 31);
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'H': /* hour, 24-hour clock, 00 - 23 */
+ i = range(0, timeptr->tm_hour, 23);
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'I': /* hour, 12-hour clock, 01 - 12 */
+ i = range(0, timeptr->tm_hour, 23);
+ if (i == 0)
+ i = 12;
+ else if (i > 12)
+ i -= 12;
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'j': /* day of the year, 001 - 366 */
+ sprintf(tbuf, "%03d", timeptr->tm_yday + 1);
+ break;
+
+ case 'm': /* month, 01 - 12 */
+ i = range(0, timeptr->tm_mon, 11);
+ sprintf(tbuf, "%02d", i + 1);
+ break;
+
+ case 'M': /* minute, 00 - 59 */
+ i = range(0, timeptr->tm_min, 59);
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'p': /* am or pm based on 12-hour clock */
+ i = range(0, timeptr->tm_hour, 23);
+ if (i < 12)
+ strcpy(tbuf, ampm[0]);
+ else
+ strcpy(tbuf, ampm[1]);
+ break;
+
+ case 'S': /* second, 00 - 61 */
+ i = range(0, timeptr->tm_sec, 61);
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'U': /* week of year, Sunday is first day of week */
+ sprintf(tbuf, "%02d", weeknumber(timeptr, 0));
+ break;
+
+ case 'w': /* weekday, Sunday == 0, 0 - 6 */
+ i = range(0, timeptr->tm_wday, 6);
+ sprintf(tbuf, "%d", i);
+ break;
+
+ case 'W': /* week of year, Monday is first day of week */
+ sprintf(tbuf, "%02d", weeknumber(timeptr, 1));
+ break;
+
+ case 'x': /* appropriate date representation */
+ sprintf(tbuf, "%s %s %2d %d",
+ days_a[range(0, timeptr->tm_wday, 6)],
+ months_a[range(0, timeptr->tm_mon, 11)],
+ range(1, timeptr->tm_mday, 31),
+ timeptr->tm_year + 1900);
+ break;
+
+ case 'X': /* appropriate time representation */
+ sprintf(tbuf, "%02d:%02d:%02d",
+ range(0, timeptr->tm_hour, 23),
+ range(0, timeptr->tm_min, 59),
+ range(0, timeptr->tm_sec, 61));
+ break;
+
+ case 'y': /* year without a century, 00 - 99 */
+ i = timeptr->tm_year % 100;
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'Y': /* year with century */
+ sprintf(tbuf, "%d", 1900 + timeptr->tm_year);
+ break;
+
+ case 'Z': /* time zone name or abbrevation */
+#if defined(HAVE_STRFTIME)
+ strftime(tbuf,sizeof tbuf,"%Z",timeptr);
+#else
+# if defined(HAVE_SV_TIMEZONE)
+ i = 0;
+ if (daylight && timeptr->tm_isdst)
+ i = 1;
+ strcpy(tbuf, tzname[i]);
+# else
+ strcpy(tbuf, zone_name (timeptr));
+# if defined(HAVE_TIMEZONE)
+# endif /* HAVE_TIMEZONE */
+ /* no timezone available */
+ /* feel free to add others here */
+# endif /* HAVE_SV_TIMEZONE */
+#endif /* HAVE STRFTIME */
+ break;
+
+#ifdef SYSV_EXT
+ case 'n': /* same as \n */
+ tbuf[0] = '\n';
+ tbuf[1] = '\0';
+ break;
+
+ case 't': /* same as \t */
+ tbuf[0] = '\t';
+ tbuf[1] = '\0';
+ break;
+
+ case 'D': /* date as %m/%d/%y */
+ exp_strftime("%m/%d/%y", timeptr, dstring);
+ copied = 1;
+/* exp_strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);*/
+ break;
+
+ case 'e': /* day of month, blank padded */
+ sprintf(tbuf, "%2d", range(1, timeptr->tm_mday, 31));
+ break;
+
+ case 'r': /* time as %I:%M:%S %p */
+ exp_strftime("%I:%M:%S %p", timeptr, dstring);
+ copied = 1;
+/* exp_strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr);*/
+ break;
+
+ case 'R': /* time as %H:%M */
+ exp_strftime("%H:%M", timeptr, dstring);
+ copied = 1;
+/* exp_strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);*/
+ break;
+
+ case 'T': /* time as %H:%M:%S */
+ exp_strftime("%H:%M:%S", timeptr, dstring);
+ copied = 1;
+/* exp_strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);*/
+ break;
+#endif
+
+#ifdef POSIX2_DATE
+ case 'C':
+ sprintf(tbuf, "%02d", (timeptr->tm_year + 1900) / 100);
+ break;
+
+
+ case 'E':
+ case 'O':
+ /* POSIX locale extensions, ignored for now */
+ goto again;
+ case 'V': /* week of year according ISO 8601 */
+ sprintf(tbuf, "%02d", iso8601wknum(timeptr));
+ break;
+
+ case 'u':
+ /* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
+ sprintf(tbuf, "%d", timeptr->tm_wday == 0 ? 7 :
+ timeptr->tm_wday);
+ break;
+#endif /* POSIX2_DATE */
+ default:
+ tbuf[0] = '%';
+ tbuf[1] = *format;
+ tbuf[2] = '\0';
+ break;
+ }
+ if (!copied)
+ Tcl_DStringAppend(dstring,tbuf,-1);
+#if 0
+ i = strlen(tbuf);
+ if (i) {
+ if (s + i < endp - 1) {
+ strcpy(s, tbuf);
+ s += i;
+ } else
+ return 0;
+#endif
+ }
+out:;
+#if 0
+ if (s < endp && *format == '\0') {
+ *s = '\0';
+ return (s - start);
+ } else
+ return 0;
+#endif
+}
+
+/* isleap --- is a year a leap year? */
+
+#ifndef __STDC__
+static int
+isleap(year)
+int year;
+#else
+static int
+isleap(int year)
+#endif
+{
+ return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
+}
+
+#ifdef POSIX2_DATE
+/* iso8601wknum --- compute week number according to ISO 8601 */
+
+#ifndef __STDC__
+static int
+iso8601wknum(timeptr)
+const struct tm *timeptr;
+#else
+static int
+iso8601wknum(const struct tm *timeptr)
+#endif
+{
+ /*
+ * From 1003.2:
+ * If the week (Monday to Sunday) containing January 1
+ * has four or more days in the new year, then it is week 1;
+ * otherwise it is the highest numbered week of the previous
+ * (52 or 53) year, and the next week is week 1.
+ *
+ * ADR: This means if Jan 1 was Monday through Thursday,
+ * it was week 1, otherwise week 53.
+ *
+ * XPG4 erroneously included POSIX.2 rationale text in the
+ * main body of the standard. Thus it requires week 53.
+ */
+
+ int weeknum, jan1day, diff;
+
+ /* get week number, Monday as first day of the week */
+ weeknum = weeknumber(timeptr, 1);
+
+ /*
+ * With thanks and tip of the hatlo to tml@tik.vtt.fi
+ *
+ * What day of the week does January 1 fall on?
+ * We know that
+ * (timeptr->tm_yday - jan1.tm_yday) MOD 7 ==
+ * (timeptr->tm_wday - jan1.tm_wday) MOD 7
+ * and that
+ * jan1.tm_yday == 0
+ * and that
+ * timeptr->tm_wday MOD 7 == timeptr->tm_wday
+ * from which it follows that. . .
+ */
+ jan1day = timeptr->tm_wday - (timeptr->tm_yday % 7);
+ if (jan1day < 0)
+ jan1day += 7;
+
+ /*
+ * If Jan 1 was a Monday through Thursday, it was in
+ * week 1. Otherwise it was last year's highest week, which is
+ * this year's week 0.
+ *
+ * What does that mean?
+ * If Jan 1 was Monday, the week number is exactly right, it can
+ * never be 0.
+ * If it was Tuesday through Thursday, the weeknumber is one
+ * less than it should be, so we add one.
+ * Otherwise, Friday, Saturday or Sunday, the week number is
+ * OK, but if it is 0, it needs to be 52 or 53.
+ */
+ switch (jan1day) {
+ case 1: /* Monday */
+ break;
+ case 2: /* Tuesday */
+ case 3: /* Wednesday */
+ case 4: /* Thursday */
+ weeknum++;
+ break;
+ case 5: /* Friday */
+ case 6: /* Saturday */
+ case 0: /* Sunday */
+ if (weeknum == 0) {
+#ifdef USE_BROKEN_XPG4
+ /* XPG4 (as of March 1994) says 53 unconditionally */
+ weeknum = 53;
+#else
+ /* get week number of last week of last year */
+ struct tm dec31ly; /* 12/31 last year */
+ dec31ly = *timeptr;
+ dec31ly.tm_year--;
+ dec31ly.tm_mon = 11;
+ dec31ly.tm_mday = 31;
+ dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1;
+ dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900);
+ weeknum = iso8601wknum(& dec31ly);
+#endif
+ }
+ break;
+ }
+
+ if (timeptr->tm_mon == 11) {
+ /*
+ * The last week of the year
+ * can be in week 1 of next year.
+ * Sigh.
+ *
+ * This can only happen if
+ * M T W
+ * 29 30 31
+ * 30 31
+ * 31
+ */
+ int wday, mday;
+
+ wday = timeptr->tm_wday;
+ mday = timeptr->tm_mday;
+ if ( (wday == 1 && (mday >= 29 && mday <= 31))
+ || (wday == 2 && (mday == 30 || mday == 31))
+ || (wday == 3 && mday == 31))
+ weeknum = 1;
+ }
+
+ return weeknum;
+}
+#endif
+
+/* weeknumber --- figure how many weeks into the year */
+
+/* With thanks and tip of the hatlo to ado@elsie.nci.nih.gov */
+
+#ifndef __STDC__
+static int
+weeknumber(timeptr, firstweekday)
+const struct tm *timeptr;
+int firstweekday;
+#else
+static int
+weeknumber(const struct tm *timeptr, int firstweekday)
+#endif
+{
+ int wday = timeptr->tm_wday;
+ int ret;
+
+ if (firstweekday == 1) {
+ if (wday == 0) /* sunday */
+ wday = 6;
+ else
+ wday--;
+ }
+ ret = ((timeptr->tm_yday + 7 - wday) / 7);
+ if (ret < 0)
+ ret = 0;
+ return ret;
+}
diff --git a/expect/exp_trap.c b/expect/exp_trap.c
new file mode 100644
index 00000000000..27a479648b6
--- /dev/null
+++ b/expect/exp_trap.c
@@ -0,0 +1,558 @@
+/* exp_trap.c - Expect's trap command
+
+Written by: Don Libes, NIST, 9/1/93
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include "expect_cf.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+/* Use _NSIG if NSIG not present */
+#ifndef NSIG
+#ifdef _NSIG
+#define NSIG _NSIG
+#endif
+#endif
+
+#if defined(SIGCLD) && !defined(SIGCHLD)
+#define SIGCHLD SIGCLD
+#endif
+
+#include "tcl.h"
+
+#include "exp_rename.h"
+#include "exp_prog.h"
+#include "exp_command.h"
+#include "exp_log.h"
+
+#ifdef TCL_DEBUGGER
+#include "Dbg.h"
+#endif
+
+#define NO_SIG 0
+
+static struct trap {
+ char *action; /* Tcl command to execute upon sig */
+ /* Each is handled by the eval_trap_action */
+ int mark; /* TRUE if signal has occurred */
+ Tcl_Interp *interp; /* interp to use or 0 if we should use the */
+ /* interpreter active at the time the sig */
+ /* is processed */
+ int code; /* return our new code instead of code */
+ /* available when signal is processed */
+ char *name; /* name of signal */
+ int reserved; /* if unavailable for trapping */
+} traps[NSIG];
+
+int sigchld_count = 0; /* # of sigchlds caught but not yet processed */
+
+static int eval_trap_action();
+
+static int got_sig; /* this records the last signal received */
+ /* it is only a hint and can be wiped out */
+ /* by multiple signals, but it will always */
+ /* be left with a valid signal that is */
+ /* pending */
+
+static Tcl_AsyncHandler async_handler;
+
+static char *
+signal_to_string(sig)
+int sig;
+{
+ if (sig <= 0 || sig > NSIG) return("SIGNAL OUT OF RANGE");
+ return(traps[sig].name);
+}
+
+/* current sig being processed by user sig handler */
+static int current_sig = NO_SIG;
+
+int exp_nostack_dump = FALSE; /* TRUE if user has requested unrolling of */
+ /* stack with no trace */
+
+
+
+/*ARGSUSED*/
+static int
+tophalf(clientData,interp,code)
+ClientData clientData;
+Tcl_Interp *interp;
+int code;
+{
+ struct trap *trap; /* last trap processed */
+ int rc;
+ int i;
+ Tcl_Interp *sig_interp;
+/* extern Tcl_Interp *exp_interp;*/
+
+ exp_debuglog("sighandler: handling signal(%d)\r\n",got_sig);
+
+ if (got_sig <= 0 || got_sig >= NSIG) {
+ errorlog("caught impossible signal %d\r\n",got_sig);
+ abort();
+ }
+
+ /* start to work on this sig. got_sig can now be overwritten */
+ /* and it won't cause a problem */
+ current_sig = got_sig;
+ trap = &traps[current_sig];
+
+ trap->mark = FALSE;
+
+ /* decrement below looks dangerous */
+ /* Don't we need to temporarily block bottomhalf? */
+ if (current_sig == SIGCHLD) {
+ sigchld_count--;
+ exp_debuglog("sigchld_count-- == %d\n",sigchld_count);
+ }
+
+ if (!trap->action) {
+ /* In this one case, we let ourselves be called when no */
+ /* signaler predefined, since we are calling explicitly */
+ /* from another part of the program, and it is just simpler */
+ if (current_sig == 0) return code;
+ errorlog("caught unexpected signal: %s (%d)\r\n",
+ signal_to_string(current_sig),current_sig);
+ abort();
+ }
+
+ if (trap->interp) {
+ /* if trap requested original interp, use it */
+ sig_interp = trap->interp;
+ } else if (!interp) {
+ /* else if another interp is available, use it */
+ sig_interp = interp;
+ } else {
+ /* fall back to exp_interp */
+ sig_interp = exp_interp;
+ }
+
+ rc = eval_trap_action(sig_interp,current_sig,trap,code);
+ current_sig = NO_SIG;
+
+ /*
+ * scan for more signals to process
+ */
+
+ /* first check for additional SIGCHLDs */
+ if (sigchld_count) {
+ got_sig = SIGCHLD;
+ traps[SIGCHLD].mark = TRUE;
+ Tcl_AsyncMark(async_handler);
+ } else {
+ got_sig = -1;
+ for (i=1;i<NSIG;i++) {
+ if (traps[i].mark) {
+ got_sig = i;
+ Tcl_AsyncMark(async_handler);
+ break;
+ }
+ }
+ }
+ return rc;
+}
+
+#ifdef REARM_SIG
+int sigchld_sleep;
+static int rearm_sigchld = FALSE; /* TRUE if sigchld needs to be */
+ /* rearmed (i.e., because it has
+ /* just gone off) */
+static int rearming_sigchld = FALSE;
+#endif
+
+/* called upon receipt of a user-declared signal */
+static void
+bottomhalf(sig)
+int sig;
+{
+#ifdef REARM_SIG
+ /*
+ * tiny window of death if same signal should arrive here
+ * before we've reinstalled it
+ */
+
+ /* In SV, sigchld must be rearmed after wait to avoid recursion */
+ if (sig != SIGCHLD) {
+ signal(sig,bottomhalf);
+ } else {
+ /* request rearm */
+ rearm_sigchld = TRUE;
+ if (rearming_sigchld) sigchld_sleep = TRUE;
+ }
+#endif
+
+ traps[sig].mark = TRUE;
+ got_sig = sig; /* just a hint - can be wiped out by another */
+ Tcl_AsyncMark(async_handler);
+
+ /* if we are called while this particular async is being processed */
+ /* original async_proc will turn off "mark" so that when async_proc */
+ /* is recalled, it will see that nothing was left to do */
+
+ /* In case of SIGCHLD though, we must recall it as many times as
+ * we have received it.
+ */
+ if (sig == SIGCHLD) {
+ sigchld_count++;
+/* exp_debuglog(stderr,"sigchld_count++ == %d\n",sigchld_count);*/
+ }
+#if 0
+ /* if we are doing an i_read, restart it */
+ if (env_valid && (sig != 0)) longjmp(env,2);
+#endif
+}
+
+/*ARGSUSED*/
+void
+exp_rearm_sigchld(interp)
+Tcl_Interp *interp;
+{
+#ifdef REARM_SIG
+ if (rearm_sigchld) {
+ rearm_sigchld = FALSE;
+ rearming_sigchld = TRUE;
+ signal(SIGCHLD,bottomhalf);
+ }
+
+ rearming_sigchld = FALSE;
+
+ /* if the rearming immediately caused another SIGCHLD, slow down */
+ /* It's probably one of Tcl's intermediary pipeline processes that */
+ /* Tcl hasn't caught up with yet. */
+ if (sigchld_sleep) {
+ exp_dsleep(interp,0.2);
+ sigchld_sleep = FALSE;
+ }
+#endif
+}
+
+
+void
+exp_init_trap()
+{
+ int i;
+
+ for (i=1;i<NSIG;i++) {
+ traps[i].name = Tcl_SignalId(i);
+ traps[i].action = 0;
+ traps[i].reserved = FALSE;
+ }
+
+ /*
+ * fix up any special cases
+ */
+
+#if defined(SIGCLD)
+ /* Tcl names it SIGCLD, not good for portable scripts */
+ traps[SIGCLD].name = "SIGCHLD";
+#endif
+#if defined(SIGALRM)
+ traps[SIGALRM].reserved = TRUE;
+#endif
+#if defined(SIGKILL)
+ traps[SIGKILL].reserved = TRUE;
+#endif
+#if defined(SIGSTOP)
+ traps[SIGSTOP].reserved = TRUE;
+#endif
+
+ async_handler = Tcl_AsyncCreate(tophalf,(ClientData)0);
+
+}
+
+/* given signal index or name as string, */
+/* returns signal index or -1 if bad arg */
+int
+exp_string_to_signal(interp,s)
+Tcl_Interp *interp;
+char *s;
+{
+ int sig;
+ char *name;
+
+ /* try interpreting as an integer */
+ if (1 == sscanf(s,"%d",&sig)) {
+ if (sig > 0 && sig < NSIG) return sig;
+ } else {
+ /* try interpreting as a string */
+ for (sig=1;sig<NSIG;sig++) {
+ name = traps[sig].name;
+ if (streq(s,name) || streq(s,name+3)) return(sig);
+ }
+ }
+
+ exp_error(interp,"invalid signal %s",s);
+
+ return -1;
+}
+
+/*ARGSUSED*/
+int
+Exp_TrapCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ char *action = 0;
+ int n; /* number of signals in list */
+ char **list; /* list of signals */
+ int len; /* length of action */
+ int i;
+ int show_name = FALSE; /* if user asked for current sig by name */
+ int show_number = FALSE;/* if user asked for current sig by number */
+ int show_max = FALSE; /* if user asked for NSIG-1 */
+ int rc = TCL_OK;
+ int new_code = FALSE; /* if action result should overwrite orig */
+ Tcl_Interp *new_interp = interp;/* interp in which to evaluate */
+ /* action when signal occurs */
+
+ argc--; argv++;
+
+ while (*argv) {
+ if (streq(*argv,"-code")) {
+ argc--; argv++;
+ new_code = TRUE;
+ } else if (streq(*argv,"-interp")) {
+ argc--; argv++;
+ new_interp = 0;
+ } else if (streq(*argv,"-name")) {
+ argc--; argv++;
+ show_name = TRUE;
+ } else if (streq(*argv,"-number")) {
+ argc--; argv++;
+ show_number = TRUE;
+ } else if (streq(*argv,"-max")) {
+ argc--; argv++;
+ show_max = TRUE;
+ } else break;
+ }
+
+ if (show_name || show_number || show_max) {
+ if (argc > 0) goto usage_error;
+ if (show_max) {
+ sprintf(interp->result,"%d",NSIG-1);
+ return TCL_OK;
+ }
+
+ if (current_sig == NO_SIG) {
+ exp_error(interp,"no signal in progress");
+ return TCL_ERROR;
+ }
+ if (show_name) {
+ /* skip over "SIG" */
+ interp->result = signal_to_string(current_sig) + 3;
+ } else {
+ sprintf(interp->result,"%d",current_sig);
+ }
+ return TCL_OK;
+ }
+
+ if (argc == 0 || argc > 2) goto usage_error;
+
+ if (argc == 1) {
+ int sig = exp_string_to_signal(interp,*argv);
+ if (sig == -1) return TCL_ERROR;
+
+ if (traps[sig].action) {
+ Tcl_AppendResult(interp,traps[sig].action,(char *)0);
+ } else {
+ interp->result = "SIG_DFL";
+ }
+ return TCL_OK;
+ }
+
+ action = *argv;
+
+ /* argv[1] is the list of signals - crack it open */
+ if (TCL_OK != Tcl_SplitList(interp,argv[1],&n,&list)) {
+ errorlog("%s\r\n",interp->result);
+ goto usage_error;
+ }
+
+ for (i=0;i<n;i++) {
+ int sig = exp_string_to_signal(interp,list[i]);
+ if (sig == -1) {
+ rc = TCL_ERROR;
+ break;
+ }
+
+ if (traps[sig].reserved) {
+ exp_error(interp,"cannot trap %s",signal_to_string(sig));
+ rc = TCL_ERROR;
+ break;
+ }
+
+#if 0
+#ifdef TCL_DEBUGGER
+ if (sig == SIGINT && exp_tcl_debugger_available) {
+ exp_debuglog("trap: cannot trap SIGINT while using debugger\r\n");
+ continue;
+ }
+#endif /* TCL_DEBUGGER */
+#endif
+
+ exp_debuglog("trap: setting up signal %d (\"%s\")\r\n",sig,list[i]);
+
+ if (traps[sig].action) ckfree(traps[sig].action);
+
+ if (streq(action,"SIG_DFL")) {
+ /* should've been free'd by now if nec. */
+ traps[sig].action = 0;
+ signal(sig,SIG_DFL);
+#ifdef REARM_SIG
+ if (sig == SIGCHLD)
+ rearm_sigchld = FALSE;
+#endif /*REARM_SIG*/
+ } else {
+ len = 1 + strlen(action);
+ traps[sig].action = ckalloc(len);
+ memcpy(traps[sig].action,action,len);
+ traps[sig].interp = new_interp;
+ traps[sig].code = new_code;
+ if (streq(action,"SIG_IGN")) {
+ signal(sig,SIG_IGN);
+ } else signal(sig,bottomhalf);
+ }
+ }
+ ckfree((char *)list);
+ return(rc);
+ usage_error:
+ exp_error(interp,"usage: trap [command or SIG_DFL or SIG_IGN] {list of signals}");
+ return TCL_ERROR;
+}
+
+/* called by tophalf() to process the given signal */
+static int
+eval_trap_action(interp,sig,trap,oldcode)
+Tcl_Interp *interp;
+int sig;
+struct trap *trap;
+int oldcode;
+{
+ int code_flag;
+ int newcode;
+ Tcl_DString ei; /* errorInfo */
+ char *eip;
+ Tcl_DString ec; /* errorCode */
+ char *ecp;
+ Tcl_DString ir; /* interp->result */
+
+ exp_debuglog("async event handler: Tcl_Eval(%s)\r\n",trap->action);
+
+ /* save to prevent user from redefining trap->code while trap */
+ /* is executing */
+ code_flag = trap->code;
+
+ if (!code_flag) {
+ /*
+ * save return values
+ */
+ eip = Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY);
+ if (eip) {
+ Tcl_DStringInit(&ei);
+ eip = Tcl_DStringAppend(&ei,eip,-1);
+ }
+ ecp = Tcl_GetVar(interp,"errorCode",TCL_GLOBAL_ONLY);
+ if (ecp) {
+ Tcl_DStringInit(&ec);
+ ecp = Tcl_DStringAppend(&ec,ecp,-1);
+ }
+ /* I assume interp->result is always non-zero, right? */
+ Tcl_DStringInit(&ir);
+ Tcl_DStringAppend(&ir,interp->result,-1);
+ }
+
+ newcode = Tcl_GlobalEval(interp,trap->action);
+
+ /*
+ * if new code is to be ignored (usual case - see "else" below)
+ * allow only OK/RETURN from trap, otherwise complain
+ */
+
+ if (code_flag) {
+ exp_debuglog("return value = %d for trap %s, action %s\r\n",
+ newcode,signal_to_string(sig),trap->action);
+ if (*interp->result != 0) {
+ errorlog("%s\r\n",interp->result);
+
+ /*
+ * Check errorinfo and see if it contains -nostack.
+ * This shouldn't be necessary, but John changed the
+ * top level interp so that it distorts arbitrary
+ * return values into TCL_ERROR, so by the time we
+ * get back, we'll have lost the value of errorInfo
+ */
+
+ eip = Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY);
+ exp_nostack_dump =
+ (eip && (0 == strncmp("-nostack",eip,8)));
+ }
+ } else if (newcode != TCL_OK && newcode != TCL_RETURN) {
+ if (newcode != TCL_ERROR) {
+ exp_error(interp,"return value = %d for trap %s, action %s\r\n",newcode,signal_to_string(sig),trap->action);
+ }
+ Tcl_BackgroundError(interp);
+ }
+
+ if (!code_flag) {
+ /*
+ * restore values
+ */
+ Tcl_ResetResult(interp); /* turns off Tcl's internal */
+ /* flags: ERR_IN_PROGRESS, ERROR_CODE_SET */
+
+ if (eip) {
+ Tcl_AddErrorInfo(interp,eip);
+ Tcl_DStringFree(&ei);
+ } else {
+ Tcl_UnsetVar(interp,"errorInfo",0);
+ }
+
+ /* restore errorCode. Note that Tcl_AddErrorInfo (above) */
+ /* resets it to NONE. If the previous value is NONE, it's */
+ /* important to avoid calling Tcl_SetErrorCode since this */
+ /* with cause Tcl to set its internal ERROR_CODE_SET flag. */
+ if (ecp) {
+ if (!streq("NONE",ecp))
+ Tcl_SetErrorCode(interp,ecp,(char *)0);
+ Tcl_DStringFree(&ec);
+ } else {
+ Tcl_UnsetVar(interp,"errorCode",0);
+ }
+
+ Tcl_DStringResult(interp,&ir);
+ Tcl_DStringFree(&ir);
+
+ newcode = oldcode;
+
+ /* note that since newcode gets overwritten here by old code */
+ /* it is possible to return in the middle of a trap by using */
+ /* "return" (or "continue" for that matter)! */
+ }
+ return newcode;
+}
+
+static struct exp_cmd_data
+cmd_data[] = {
+{"trap", exp_proc(Exp_TrapCmd), (ClientData)EXP_SPAWN_ID_BAD, 0},
+{0}};
+
+void
+exp_init_trap_cmds(interp)
+Tcl_Interp *interp;
+{
+ exp_create_commands(interp,cmd_data);
+}
+
diff --git a/expect/exp_tstamp.h b/expect/exp_tstamp.h
new file mode 100644
index 00000000000..5cadc7d9336
--- /dev/null
+++ b/expect/exp_tstamp.h
@@ -0,0 +1,2 @@
+EXTERN void exp_timestamp _ANSI_ARGS_((Tcl_Interp *,time_t *,
+ char *));
diff --git a/expect/exp_tty.c b/expect/exp_tty.c
new file mode 100644
index 00000000000..7ad512b03a3
--- /dev/null
+++ b/expect/exp_tty.c
@@ -0,0 +1,764 @@
+/* exp_tty.c - tty support routines */
+
+#include "expect_cf.h"
+#include <stdio.h>
+#include <signal.h>
+#include "string.h"
+
+#ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#else
+# include <fcntl.h>
+#endif
+
+#include <sys/stat.h>
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#include <sys/types.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#if defined(SIGCLD) && !defined(SIGCHLD)
+#define SIGCHLD SIGCLD
+#endif
+
+#include "tcl.h"
+#include "exp_prog.h"
+#include "exp_rename.h"
+#include "exp_tty_in.h"
+#include "exp_log.h"
+#include "exp_command.h"
+
+static int is_raw = FALSE;
+static int is_noecho = FALSE;
+
+int exp_ioctled_devtty = FALSE;
+int exp_stdin_is_tty;
+int exp_stdout_is_tty;
+
+/*static*/ extern exp_tty exp_tty_current, exp_tty_cooked;
+#define tty_current exp_tty_current
+#define tty_cooked exp_tty_cooked
+
+int
+exp_israw()
+{
+ return is_raw;
+}
+
+int
+exp_isecho()
+{
+ return !is_noecho;
+}
+
+/* if set == 1, set it to raw, else unset it */
+void
+exp_tty_raw(set)
+int set;
+{
+ if (set == 1) {
+ is_raw = TRUE;
+#if defined(HAVE_TERMIOS) || defined(HAVE_TERMIO) /* had POSIX too */
+ tty_current.c_iflag = 0;
+ tty_current.c_oflag = 0;
+ tty_current.c_lflag &= ECHO; /* disable everything but echo */
+ tty_current.c_cc[VMIN] = 1;
+ tty_current.c_cc[VTIME] = 0;
+ } else {
+ tty_current.c_iflag = tty_cooked.c_iflag;
+ tty_current.c_oflag = tty_cooked.c_oflag;
+/* tty_current.c_lflag = tty_cooked.c_lflag;*/
+/* attempt 2 tty_current.c_lflag = tty_cooked.c_lflag & ~ECHO;*/
+ /* retain current echo setting */
+ tty_current.c_lflag = (tty_cooked.c_lflag & ~ECHO) | (tty_current.c_lflag & ECHO);
+ tty_current.c_cc[VMIN] = tty_cooked.c_cc[VMIN];
+ tty_current.c_cc[VTIME] = tty_cooked.c_cc[VTIME];
+#else
+# if defined(HAVE_SGTTYB)
+ tty_current.sg_flags |= RAW;
+ } else {
+ tty_current.sg_flags = tty_cooked.sg_flags;
+# endif
+#endif
+ is_raw = FALSE;
+ }
+}
+
+void
+exp_tty_echo(set)
+int set;
+{
+ if (set == 1) {
+ is_noecho = FALSE;
+#if defined(HAVE_TERMIOS) || defined(HAVE_TERMIO) /* had POSIX too */
+ tty_current.c_lflag |= ECHO;
+ } else {
+ tty_current.c_lflag &= ~ECHO;
+#else
+ tty_current.sg_flags |= ECHO;
+ } else {
+ tty_current.sg_flags &= ~ECHO;
+#endif
+ is_noecho = TRUE;
+ }
+}
+
+int
+exp_tty_set_simple(tty)
+exp_tty *tty;
+{
+#ifdef HAVE_TCSETATTR
+ return(tcsetattr(exp_dev_tty, TCSADRAIN,tty));
+#else
+ return(ioctl (exp_dev_tty, TCSETSW ,tty));
+#endif
+}
+
+int
+exp_tty_get_simple(tty)
+exp_tty *tty;
+{
+#ifdef HAVE_TCSETATTR
+ return(tcgetattr(exp_dev_tty, tty));
+#else
+ return(ioctl (exp_dev_tty, TCGETS, tty));
+#endif
+}
+
+/* returns 0 if nothing changed */
+/* if something changed, the out parameters are changed as well */
+int
+exp_tty_raw_noecho(interp,tty_old,was_raw,was_echo)
+Tcl_Interp *interp;
+exp_tty *tty_old;
+int *was_raw, *was_echo;
+{
+ if (exp_disconnected) return(0);
+ if (is_raw && is_noecho) return(0);
+ if (exp_dev_tty == -1) return(0);
+
+ *tty_old = tty_current; /* save old parameters */
+ *was_raw = is_raw;
+ *was_echo = !is_noecho;
+ debuglog("tty_raw_noecho: was raw = %d echo = %d\r\n",is_raw,!is_noecho);
+
+ exp_tty_raw(1);
+ exp_tty_echo(-1);
+
+ if (exp_tty_set_simple(&tty_current) == -1) {
+ errorlog("ioctl(raw): %s\r\n",Tcl_PosixError(interp));
+ exp_exit(interp,1);
+ }
+
+ exp_ioctled_devtty = TRUE;
+ return(1);
+}
+
+/* returns 0 if nothing changed */
+/* if something changed, the out parameters are changed as well */
+int
+exp_tty_cooked_echo(interp,tty_old,was_raw,was_echo)
+Tcl_Interp *interp;
+exp_tty *tty_old;
+int *was_raw, *was_echo;
+{
+ if (exp_disconnected) return(0);
+ if (!is_raw && !is_noecho) return(0);
+ if (exp_dev_tty == -1) return(0);
+
+ *tty_old = tty_current; /* save old parameters */
+ *was_raw = is_raw;
+ *was_echo = !is_noecho;
+ debuglog("tty_cooked_echo: was raw = %d echo = %d\r\n",is_raw,!is_noecho);
+
+ exp_tty_raw(-1);
+ exp_tty_echo(1);
+
+ if (exp_tty_set_simple(&tty_current) == -1) {
+ errorlog("ioctl(noraw): %s\r\n",Tcl_PosixError(interp));
+ exp_exit(interp,1);
+ }
+ exp_ioctled_devtty = TRUE;
+
+ return(1);
+}
+
+void
+exp_tty_set(interp,tty,raw,echo)
+Tcl_Interp *interp;
+exp_tty *tty;
+int raw;
+int echo;
+{
+ if (exp_tty_set_simple(tty) == -1) {
+ errorlog("ioctl(set): %s\r\n",Tcl_PosixError(interp));
+ exp_exit(interp,1);
+ }
+ is_raw = raw;
+ is_noecho = !echo;
+ tty_current = *tty;
+ debuglog("tty_set: raw = %d, echo = %d\r\n",is_raw,!is_noecho);
+ exp_ioctled_devtty = TRUE;
+}
+
+#if 0
+/* avoids scoping problems */
+void
+exp_update_cooked_from_current() {
+ tty_cooked = tty_current;
+}
+
+int
+exp_update_real_tty_from_current() {
+ return(exp_tty_set_simple(&tty_current));
+}
+
+int
+exp_update_current_from_real_tty() {
+ return(exp_tty_get_simple(&tty_current));
+}
+#endif
+
+void
+exp_init_stdio()
+{
+ exp_stdin_is_tty = isatty(0);
+ exp_stdout_is_tty = isatty(1);
+
+ setbuf(stdout,(char *)0); /* unbuffer stdout */
+}
+
+/*ARGSUSED*/
+void
+exp_tty_break(interp,fd)
+Tcl_Interp *interp;
+int fd;
+{
+#ifdef POSIX
+ tcsendbreak(fd,0);
+#else
+# ifdef TIOCSBRK
+ ioctl(fd,TIOCSBRK,0);
+ exp_dsleep(interp,0.25); /* sleep for at least a quarter of a second */
+ ioctl(fd,TIOCCBRK,0);
+# else
+ /* dunno how to do this - ignore */
+# endif
+#endif
+}
+
+/* take strings with newlines and insert carriage-returns. This allows user */
+/* to write send_user strings without always putting in \r. */
+/* If len == 0, use strlen to compute it */
+/* NB: if terminal is not in raw mode, nothing is done. */
+char *
+exp_cook(s,len)
+char *s;
+int *len; /* current and new length of s */
+{
+ static int destlen = 0;
+ static char *dest = 0;
+ char *d; /* ptr into dest */
+ unsigned int need;
+
+ if (s == 0) return("<null>");
+
+ if (!is_raw) return(s);
+
+ /* worst case is every character takes 2 to represent */
+ need = 1 + 2*(len?*len:strlen(s));
+ if (need > destlen) {
+ if (dest) ckfree(dest);
+ dest = ckalloc(need);
+ destlen = need;
+ }
+
+ for (d = dest;*s;s++) {
+ if (*s == '\n') {
+ *d++ = '\r';
+ *d++ = '\n';
+ } else {
+ *d++ = *s;
+ }
+ }
+ *d = '\0';
+ if (len) *len = d-dest;
+ return(dest);
+}
+
+/* this stupidity because Tcl needs commands in writable space */
+static char exec_cmd[] = "exec";
+static char stty_cmd[] = "/bin/stty";
+
+static int /* returns TCL_whatever */
+exec_stty(interp,argc,argv,devtty)
+Tcl_Interp *interp;
+int argc;
+char **argv;
+int devtty; /* if true, redirect to /dev/tty */
+{
+ char **new_argv;
+ int i;
+ int rc;
+
+ /* insert "system" at front, null at end, */
+ /* and optional redirect in middle, hence "+3" */
+ new_argv = (char **)ckalloc((3+argc)*sizeof(char *));
+ new_argv[0] = exec_cmd;
+ new_argv[1] = stty_cmd;
+ for (i=1;i<argc;i++) {
+ new_argv[i+1] = argv[i];
+ }
+ if (devtty) new_argv[++i] =
+#ifdef STTY_READS_STDOUT
+ ">/dev/tty";
+#else
+ "</dev/tty";
+#endif
+
+ new_argv[i+1] = (char *)0;
+
+ Tcl_ResetResult(interp);
+
+ /* normally, I wouldn't set one of Tcl's own variables, but in this */
+ /* case, I only only want to see if Tcl resets it to non-NONE, */
+ /* and I don't know any other way of doing it */
+ Tcl_SetVar(interp,"errorCode","NONE",0);
+ rc = Tcl_ExecCmd((ClientData)0,interp,argc+1+devtty,new_argv);
+
+ ckfree((char *)new_argv);
+
+ /* if stty-reads-stdout, stty will fail since Exec */
+ /* will detect the stderr. Only by examining errorCode */
+ /* can we tell if a real error occurred. */
+
+#ifdef STTY_READS_STDOUT
+ if (rc == TCL_ERROR) {
+ char *ec = Tcl_GetVar(interp,"errorCode",TCL_GLOBAL_ONLY);
+ if (ec && !streq(ec,"NONE")) return TCL_ERROR;
+ }
+#endif
+ return TCL_OK;
+}
+
+/*ARGSUSED*/
+static int
+Exp_SttyCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ /* redirection symbol is not counted as a stty arg in terms */
+ /* of recognition. */
+ int saw_unknown_stty_arg = FALSE;
+ int saw_known_stty_arg = FALSE;
+ int no_args = TRUE;
+
+ int rc = TCL_OK;
+ int cooked = FALSE;
+ int was_raw, was_echo;
+
+
+ char **redirect; /* location of "<" */
+ char *infile = 0;
+ int fd; /* (slave) fd of infile */
+ int master = -1; /* master fd of infile */
+ char **argv0 = argv;
+
+ for (argv=argv0+1;*argv;argv++) {
+ if (argv[0][0] == '<') {
+ redirect = argv;
+ infile = *(argv+1);
+ if (!infile) {
+ errorlog("usage: < ttyname");
+ return TCL_ERROR;
+ }
+ if (streq(infile,"/dev/tty")) {
+ infile = 0;
+ *argv = 0;
+ *(argv+1) = 0;
+ argc -= 2;
+ } else {
+ master = exp_trap_off(infile);
+ if (-1 == (fd = open(infile,2))) {
+ errorlog("couldn't open %s: %s",
+ infile,Tcl_PosixError(interp));
+ return TCL_ERROR;
+ }
+ }
+ break;
+ }
+ }
+
+ if (!infile) { /* work on /dev/tty */
+ was_raw = exp_israw();
+ was_echo = exp_isecho();
+
+ exp_ioctled_devtty = TRUE;
+
+ for (argv=argv0+1;*argv;argv++) {
+ if (streq(*argv,"raw") ||
+ streq(*argv,"-cooked")) {
+ exp_tty_raw(1);
+ saw_known_stty_arg = TRUE;
+ no_args = FALSE;
+ } else if (streq(*argv,"-raw") ||
+ streq(*argv,"cooked")) {
+ cooked = TRUE;
+ exp_tty_raw(-1);
+ saw_known_stty_arg = TRUE;
+ no_args = FALSE;
+ } else if (streq(*argv,"echo")) {
+ exp_tty_echo(1);
+ saw_known_stty_arg = TRUE;
+ no_args = FALSE;
+ } else if (streq(*argv,"-echo")) {
+ exp_tty_echo(-1);
+ saw_known_stty_arg = TRUE;
+ no_args = FALSE;
+ } else if (streq(*argv,"rows")) {
+ if (*(argv+1)) {
+ exp_win_rows_set(*(argv+1));
+ argv++;
+ no_args = FALSE;
+ } else {
+ exp_win_rows_get(interp->result);
+ return TCL_OK;
+ }
+ } else if (streq(*argv,"columns")) {
+ if (*(argv+1)) {
+ exp_win_columns_set(*(argv+1));
+ argv++;
+ no_args = FALSE;
+ } else {
+ exp_win_columns_get(interp->result);
+ return TCL_OK;
+ }
+ } else {
+ saw_unknown_stty_arg = TRUE;
+ }
+ }
+ /* if any unknown args, let real stty try */
+ if (saw_unknown_stty_arg || no_args) {
+ /* let real stty try */
+ rc = exec_stty(interp,argc,argv0,1);
+
+ /* find out what weird options user asked for */
+ if (exp_tty_get_simple(&tty_current) == -1) {
+ exp_error(interp,"stty: ioctl(get): %s\r\n",Tcl_PosixError(interp));
+ rc = TCL_ERROR;
+ }
+ if (cooked) {
+ /* find out user's new defn of 'cooked' */
+ tty_cooked = tty_current;
+ }
+ } else if (saw_known_stty_arg) {
+ if (exp_tty_set_simple(&tty_current) == -1) {
+ if (exp_disconnected || (exp_dev_tty == -1) || !isatty(exp_dev_tty)) {
+ errorlog("stty: impossible in this context\n");
+ errorlog("are you disconnected or in a batch, at, or cron script?");
+ /* user could've conceivably closed /dev/tty as well */
+ }
+ exp_error(interp,"stty: ioctl(user): %s\r\n",Tcl_PosixError(interp));
+ rc = TCL_ERROR;
+ }
+ }
+
+ /* if no result, make a crude one */
+ if (interp->result[0] == '\0') {
+ sprintf(interp->result,"%sraw %secho",
+ (was_raw?"":"-"),
+ (was_echo?"":"-"));
+ }
+ } else {
+ /* a different tty */
+
+ /* temporarily zap redirect */
+ char *redirect_save = *redirect;
+ *redirect = 0;
+
+ for (argv=argv0+1;*argv;argv++) {
+ if (streq(*argv,"rows")) {
+ if (*(argv+1)) {
+ exp_win2_rows_set(fd,*(argv+1));
+ argv++;
+ no_args = FALSE;
+ } else {
+ exp_win2_rows_get(fd,interp->result);
+ goto done;
+ }
+ } else if (streq(*argv,"columns")) {
+ if (*(argv+1)) {
+ exp_win2_columns_set(fd,*(argv+1));
+ argv++;
+ no_args = FALSE;
+ } else {
+ exp_win2_columns_get(fd,interp->result);
+ goto done;
+ }
+ } else if (streq(*argv,"<")) {
+ break;
+ } else {
+ saw_unknown_stty_arg = TRUE;
+ break;
+ }
+ }
+
+ /* restore redirect */
+ *redirect = redirect_save;
+
+ close(fd); /* no more use for this, from now on */
+ /* pass by name */
+
+ if (saw_unknown_stty_arg || no_args) {
+#ifdef STTY_READS_STDOUT
+ /* switch "<" to ">" */
+ char original_redirect_char = (*redirect)[0];
+ (*redirect)[0] = '>';
+ /* stderr unredirected so we can get it directly! */
+#endif
+ rc = exec_stty(interp,argc,argv0,0);
+#ifdef STTY_READS_STDOUT
+ /* restore redirect - don't know if necessary */
+ (*redirect)[0] = original_redirect_char;
+#endif
+ }
+ }
+ done:
+ exp_trap_on(master);
+
+ return rc;
+}
+
+/*ARGSUSED*/
+static int
+Exp_SystemCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int result = TCL_OK;
+ RETSIGTYPE (*old)(); /* save old sigalarm handler */
+#define MAX_ARGLIST 10240
+ int i;
+
+ WAIT_STATUS_TYPE waitStatus;
+ int systemStatus
+;
+ int abnormalExit = FALSE;
+ char buf[MAX_ARGLIST];
+ char *bufp = buf;
+ int total_len = 0, arg_len;
+
+ int stty_args_recognized = TRUE;
+ int cmd_is_stty = FALSE;
+ int cooked = FALSE;
+ int was_raw, was_echo;
+
+ if (argc == 1) return TCL_OK;
+
+ if (streq(argv[1],"stty")) {
+ debuglog("system stty is deprecated, use stty\r\n");
+
+ cmd_is_stty = TRUE;
+ was_raw = exp_israw();
+ was_echo = exp_isecho();
+ }
+
+ if (argc > 2 && cmd_is_stty) {
+ exp_ioctled_devtty = TRUE;
+
+ for (i=2;i<argc;i++) {
+ if (streq(argv[i],"raw") ||
+ streq(argv[i],"-cooked")) {
+ exp_tty_raw(1);
+ } else if (streq(argv[i],"-raw") ||
+ streq(argv[i],"cooked")) {
+ cooked = TRUE;
+ exp_tty_raw(-1);
+ } else if (streq(argv[i],"echo")) {
+ exp_tty_echo(1);
+ } else if (streq(argv[i],"-echo")) {
+ exp_tty_echo(-1);
+ } else stty_args_recognized = FALSE;
+ }
+
+ /* if unknown args, fall thru and let real stty have a go */
+ if (stty_args_recognized) {
+#ifdef HAVE_TCSETATTR
+ if (tcsetattr(exp_dev_tty,TCSADRAIN, &tty_current) == -1) {
+#else
+ if (ioctl(exp_dev_tty, TCSETSW, &tty_current) == -1) {
+#endif
+ if (exp_disconnected || (exp_dev_tty == -1) || !isatty(exp_dev_tty)) {
+ errorlog("system stty: impossible in this context\n");
+ errorlog("are you disconnected or in a batch, at, or cron script?");
+ /* user could've conceivably closed /dev/tty as well */
+ }
+ exp_error(interp,"system stty: ioctl(user): %s\r\n",Tcl_PosixError(interp));
+ return(TCL_ERROR);
+ }
+ if (cmd_is_stty) {
+ sprintf(interp->result,"%sraw %secho",
+ (was_raw?"":"-"),
+ (was_echo?"":"-"));
+ }
+ return(TCL_OK);
+ }
+ }
+
+ for (i = 1;i<argc;i++) {
+ total_len += (1 + (arg_len = strlen(argv[i])));
+ if (total_len > MAX_ARGLIST) {
+ exp_error(interp,"args too long (>=%d chars)",
+ total_len);
+ return(TCL_ERROR);
+ }
+ memcpy(bufp,argv[i],arg_len);
+ bufp += arg_len;
+ /* no need to check bounds, we accted for it earlier */
+ memcpy(bufp," ",1);
+ bufp += 1;
+ }
+
+ *(bufp-1) = '\0';
+ old = signal(SIGCHLD, SIG_DFL);
+ systemStatus = system(buf);
+ signal(SIGCHLD, old); /* restore signal handler */
+ debuglog("system(%s) = %d\r\n",buf,i);
+
+ if (systemStatus == -1) {
+ exp_error(interp,Tcl_PosixError(interp));
+ return TCL_ERROR;
+ }
+ *(int *)&waitStatus = systemStatus;
+
+ if (!stty_args_recognized) {
+ /* find out what weird options user asked for */
+#ifdef HAVE_TCSETATTR
+ if (tcgetattr(exp_dev_tty, &tty_current) == -1) {
+#else
+ if (ioctl(exp_dev_tty, TCGETS, &tty_current) == -1) {
+#endif
+ errorlog("ioctl(get): %s\r\n",Tcl_PosixError(interp));
+ exp_exit(interp,1);
+ }
+ if (cooked) {
+ /* find out user's new defn of 'cooked' */
+ tty_cooked = tty_current;
+ }
+ }
+
+ if (cmd_is_stty) {
+ sprintf(interp->result,"%sraw %secho",
+ (was_raw?"":"-"),
+ (was_echo?"":"-"));
+ }
+
+/* following macros stolen from Tcl's tclUnix.h file */
+/* we can't include the whole thing because it depends on other macros */
+/* that come out of Tcl's Makefile, sigh */
+
+#if 0
+
+#undef WIFEXITED
+#ifndef WIFEXITED
+# define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0)
+#endif
+
+#undef WEXITSTATUS
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
+#endif
+
+#undef WIFSIGNALED
+#ifndef WIFSIGNALED
+# define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff)))
+#endif
+
+#undef WTERMSIG
+#ifndef WTERMSIG
+# define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f)
+#endif
+
+#undef WIFSTOPPED
+#ifndef WIFSTOPPED
+# define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177)
+#endif
+
+#undef WSTOPSIG
+#ifndef WSTOPSIG
+# define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff)
+#endif
+
+#endif /* 0 */
+
+/* stolen from Tcl. Again, this is embedded in another routine */
+/* (CleanupChildren in tclUnixAZ.c) that we can't use directly. */
+
+ if (!WIFEXITED(waitStatus) || (WEXITSTATUS(waitStatus) != 0)) {
+ char msg1[20], msg2[20];
+ int pid = 0; /* fake a pid, since system() won't tell us */
+
+ result = TCL_ERROR;
+ sprintf(msg1, "%d", pid);
+ if (WIFEXITED(waitStatus)) {
+ sprintf(msg2, "%d", WEXITSTATUS(waitStatus));
+ Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2,
+ (char *) NULL);
+ abnormalExit = TRUE;
+ } else if (WIFSIGNALED(waitStatus)) {
+ char *p;
+
+ p = Tcl_SignalMsg((int) (WTERMSIG(waitStatus)));
+ Tcl_SetErrorCode(interp, "CHILDKILLED", msg1,
+ Tcl_SignalId((int) (WTERMSIG(waitStatus))), p,
+ (char *) NULL);
+ Tcl_AppendResult(interp, "child killed: ", p, "\n",
+ (char *) NULL);
+ } else if (WIFSTOPPED(waitStatus)) {
+ char *p;
+
+ p = Tcl_SignalMsg((int) (WSTOPSIG(waitStatus)));
+ Tcl_SetErrorCode(interp, "CHILDSUSP", msg1,
+ Tcl_SignalId((int) (WSTOPSIG(waitStatus))), p, (char *) NULL);
+ Tcl_AppendResult(interp, "child suspended: ", p, "\n",
+ (char *) NULL);
+ } else {
+ Tcl_AppendResult(interp,
+ "child wait status didn't make sense\n",
+ (char *) NULL);
+ }
+ }
+
+ if (abnormalExit && (*interp->result == 0)) {
+ Tcl_AppendResult(interp, "child process exited abnormally",
+ (char *) NULL);
+ }
+
+ return result;
+}
+
+static struct exp_cmd_data
+cmd_data[] = {
+{"stty", exp_proc(Exp_SttyCmd), 0, 0},
+{"system", exp_proc(Exp_SystemCmd), 0, 0},
+{0}};
+
+void
+exp_init_tty_cmds(interp)
+struct Tcl_Interp *interp;
+{
+ exp_create_commands(interp,cmd_data);
+}
diff --git a/expect/exp_tty.h b/expect/exp_tty.h
new file mode 100644
index 00000000000..cbbb9464959
--- /dev/null
+++ b/expect/exp_tty.h
@@ -0,0 +1,29 @@
+/* exp_tty.h - tty support definitions
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+#ifndef __EXP_TTY_H__
+#define __EXP_TTY_H__
+
+#include "expect_cf.h"
+
+extern int exp_dev_tty;
+extern int exp_ioctled_devtty;
+extern int exp_stdin_is_tty;
+extern int exp_stdout_is_tty;
+
+void exp_tty_raw();
+void exp_tty_echo();
+void exp_tty_break();
+int exp_tty_raw_noecho();
+int exp_israw();
+int exp_isecho();
+
+void exp_tty_set();
+int exp_tty_set_simple();
+int exp_tty_get_simple();
+
+#endif /* __EXP_TTY_H__ */
diff --git a/expect/exp_tty_comm.c b/expect/exp_tty_comm.c
new file mode 100644
index 00000000000..e7fff432eab
--- /dev/null
+++ b/expect/exp_tty_comm.c
@@ -0,0 +1,36 @@
+/* exp_tty_comm.c - tty support routines common to both Expect program
+ and library */
+
+#include "expect_cf.h"
+#include <stdio.h>
+
+#include "exp_tty_in.h"
+#include "exp_rename.h"
+#define EXP_AVOID_INCLUDING_TCL_H
+#include "expect_comm.h"
+#include "exp_log.h"
+
+#ifndef TRUE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+int exp_disconnected = FALSE; /* not disc. from controlling tty */
+
+/*static*/ exp_tty exp_tty_current, exp_tty_cooked;
+#define tty_current exp_tty_current
+#define tty_cooked exp_tty_cooked
+
+void
+exp_init_tty()
+{
+ extern exp_tty exp_tty_original;
+
+ /* save original user tty-setting in 'cooked', just in case user */
+ /* asks for it without earlier telling us what cooked means to them */
+ tty_cooked = exp_tty_original;
+
+ /* save our current idea of the terminal settings */
+ tty_current = exp_tty_original;
+}
+
diff --git a/expect/exp_tty_in.h b/expect/exp_tty_in.h
new file mode 100644
index 00000000000..d5f9a13412f
--- /dev/null
+++ b/expect/exp_tty_in.h
@@ -0,0 +1,100 @@
+/* exp_tty_in.h - internal tty support definitions */
+
+/* Definitions for handling termio inclusion are localized here */
+/* This file should be included only if direct access to tty structures are */
+/* required. This file is necessary to avoid mismatch between gcc's and */
+/* vendor's include files */
+
+/* Written by Rob Savoye <rob@cygnus.com>. Mon Feb 22 11:16:53 RMT 1993 */
+
+#ifndef __EXP_TTY_IN_H__
+#define __EXP_TTY_IN_H__
+
+#include "expect_cf.h"
+
+#ifdef __MACHTEN__
+#include "sys/types.h"
+#endif
+
+/*
+ * Set up some macros to isolate tty differences
+ */
+
+/* On some hosts, termio is incomplete (broken) and sgtty is a better
+choice. At the same time, termio has some definitions for modern
+stuff like window sizes that sgtty lacks - that's why termio.h
+is included even when we claim the basic style is sgtty
+*/
+
+/* test for pyramid may be unnecessary, but only Pyramid people have */
+/* complained - notably pclink@qus102.qld.npb.telecom.com.au (Rick) */
+#if defined(pyr) && defined(HAVE_TERMIO) && defined(HAVE_SGTTYB)
+#undef HAVE_SGTTYB
+#endif
+
+/* on ISC SVR3.2, termios is skeletal and termio is a better choice. */
+/* sgttyb must also be avoided because it redefines same things that */
+/* termio does */
+/* note that both SVR3.2 and AIX lacks TCGETS or TCGETA in termios.h */
+/* but SVR3.2 lacks both TCSETATTR and TCGETS/A */
+#if defined(HAVE_TERMIO) && defined(HAVE_TERMIOS) && !defined(HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H) && !defined(HAVE_TCSETATTR)
+# undef HAVE_TERMIOS
+# undef HAVE_SGTTYB
+#endif
+
+#if defined(HAVE_TERMIO) && !defined(HAVE_TERMIOS)
+# include <termio.h>
+# undef POSIX
+# define TERMINAL termio
+# ifndef TCGETS
+# define TCGETS TCGETA
+# define TCSETS TCSETA
+# define TCSETSW TCSETAW
+# define TCSETSF TCSETAF
+# endif
+#endif
+
+#if defined(HAVE_SGTTYB) && !defined(HAVE_TERMIOS)
+# undef HAVE_TERMIO
+# undef POSIX
+#ifndef TCGETS
+# define TCGETS TIOCGETP
+# define TCSETS TIOCSETP
+#endif
+#ifndef TCSETSW
+# define TCSETSW TIOCSETN
+#endif
+# define TERMINAL sgttyb
+# ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+# else
+# include <fcntl.h>
+# endif
+# include <sgtty.h>
+# include <sys/ioctl.h>
+#endif
+
+
+#if defined(HAVE_TERMIOS)
+# undef HAVE_TERMIO
+# undef HAVE_SGTTYB
+# include <termios.h>
+# define TERMINAL termios
+# if !defined(TCGETS) || !defined(TCSETS)
+# define TCGETS TCGETA
+# define TCSETS TCSETA
+# define TCSETSW TCSETAW
+# define TCSETSF TCSETAF
+# endif
+#endif
+
+/* This section was written by: Don Libes, NIST, 2/6/90 */
+
+typedef struct TERMINAL exp_tty;
+extern exp_tty exp_tty_original;
+extern exp_tty exp_tty_current;
+extern exp_tty exp_tty_cooked;
+
+#include "exp_tty.h"
+
+#endif /* __EXP_TTY_IN_H__ */
diff --git a/expect/exp_win.c b/expect/exp_win.c
new file mode 100644
index 00000000000..bc6bfdcf65a
--- /dev/null
+++ b/expect/exp_win.c
@@ -0,0 +1,205 @@
+/* exp_win.c - window support
+
+Written by: Don Libes, NIST, 10/25/93
+
+This file is in the public domain. However, the author and NIST
+would appreciate credit if you use this file or parts of it.
+
+*/
+
+#include "expect_cf.h"
+#include "tcl.h"
+
+#ifdef NO_STDLIB_H
+#include "../compat/stdlib.h"
+#else
+#include <stdlib.h>
+#endif
+
+/* _IBCS2 required on some Intel platforms to allow the include files */
+/* to produce a definition for winsize. */
+#define _IBCS2 1
+
+/*
+ * get everyone's window size definitions
+ *
+note that this is tricky because (of course) everyone puts them in
+different places. Worse, on some systems, some .h files conflict
+and cannot both be included even though both exist. This is the
+case, for example, on SunOS 4.1.3 using gcc where termios.h
+conflicts with sys/ioctl.h
+ */
+
+#ifdef HAVE_TERMIOS
+# include <termios.h>
+#else
+# include <sys/ioctl.h>
+#endif
+
+/* Sigh. On AIX 2.3, termios.h exists but does not define TIOCGWINSZ */
+/* Instead, it has to come from ioctl.h. However, As I said above, this */
+/* can't be cavalierly included on all machines, even when it exists. */
+#if defined(HAVE_TERMIOS) && !defined(HAVE_TIOCGWINSZ_IN_TERMIOS_H)
+# include <sys/ioctl.h>
+#endif
+
+/* SCO defines window size structure in PTEM and TIOCGWINSZ in termio.h */
+/* Sigh... */
+#if defined(HAVE_SYS_PTEM_H)
+# include <sys/types.h> /* for stream.h's caddr_t */
+# include <sys/stream.h> /* for ptem.h's mblk_t */
+# include <sys/ptem.h>
+#endif /* HAVE_SYS_PTEM_H */
+
+#include "exp_tty.h"
+#include "exp_win.h"
+
+#ifdef TIOCGWINSZ
+typedef struct winsize exp_winsize;
+#define columns ws_col
+#define rows ws_row
+#define EXP_WIN
+#endif
+
+#if !defined(EXP_WIN) && defined(TIOCGSIZE)
+typedef struct ttysize exp_winsize;
+#define columns ts_cols
+#define rows ts_lines
+#define EXP_WIN
+#endif
+
+#if !defined(EXP_WIN)
+typedef struct {
+ int columns;
+ int rows;
+} exp_winsize;
+#endif
+
+static exp_winsize winsize = {0, 0};
+static exp_winsize win2size = {0, 0};
+
+int exp_window_size_set(fd)
+int fd;
+{
+#ifdef TIOCSWINSZ
+ ioctl(fd,TIOCSWINSZ,&winsize);
+#endif
+#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
+ ioctl(fd,TIOCSSIZE,&winsize);
+#endif
+}
+
+int exp_window_size_get(fd)
+int fd;
+{
+#ifdef TIOCGWINSZ
+ ioctl(fd,TIOCGWINSZ,&winsize);
+#endif
+#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
+ ioctl(fd,TIOCGSIZE,&winsize);
+#endif
+#if !defined(EXP_WIN)
+ winsize.rows = 0;
+ winsize.columns = 0;
+#endif
+}
+
+void
+exp_win_rows_set(rows)
+char *rows;
+{
+ winsize.rows = atoi(rows);
+ exp_window_size_set(exp_dev_tty);
+}
+
+void
+exp_win_rows_get(rows)
+char *rows;
+{
+ exp_window_size_get(exp_dev_tty);
+ sprintf(rows,"%d",winsize.rows);
+}
+
+void
+exp_win_columns_set(columns)
+char *columns;
+{
+ winsize.columns = atoi(columns);
+ exp_window_size_set(exp_dev_tty);
+}
+
+void
+exp_win_columns_get(columns)
+char *columns;
+{
+ exp_window_size_get(exp_dev_tty);
+ sprintf(columns,"%d",winsize.columns);
+}
+
+/*
+ * separate copy of everything above - used for handling user stty requests
+ */
+
+int exp_win2_size_set(fd)
+int fd;
+{
+#ifdef TIOCSWINSZ
+ ioctl(fd,TIOCSWINSZ,&win2size);
+#endif
+#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
+ ioctl(fd,TIOCSSIZE,&win2size);
+#endif
+}
+
+int exp_win2_size_get(fd)
+int fd;
+{
+#ifdef TIOCGWINSZ
+ ioctl(fd,TIOCGWINSZ,&win2size);
+#endif
+#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
+ ioctl(fd,TIOCGSIZE,&win2size);
+#endif
+}
+
+void
+exp_win2_rows_set(fd,rows)
+int fd;
+char *rows;
+{
+ exp_win2_size_get(fd);
+ win2size.rows = atoi(rows);
+ exp_win2_size_set(fd);
+}
+
+void
+exp_win2_rows_get(fd,rows)
+int fd;
+char *rows;
+{
+ exp_win2_size_get(fd);
+ sprintf(rows,"%d",win2size.rows);
+#if !defined(EXP_WIN)
+ win2size.rows = 0;
+ win2size.columns = 0;
+#endif
+}
+
+void
+exp_win2_columns_set(fd,columns)
+int fd;
+char *columns;
+{
+ exp_win2_size_get(fd);
+ win2size.columns = atoi(columns);
+ exp_win2_size_set(fd);
+}
+
+void
+exp_win2_columns_get(fd,columns)
+int fd;
+char *columns;
+{
+ exp_win2_size_get(fd);
+ sprintf(columns,"%d",win2size.columns);
+}
diff --git a/expect/exp_win.h b/expect/exp_win.h
new file mode 100644
index 00000000000..391593ac589
--- /dev/null
+++ b/expect/exp_win.h
@@ -0,0 +1,20 @@
+/* exp_win.h - window support
+
+Written by: Don Libes, NIST, 10/25/93
+
+This file is in the public domain. However, the author and NIST
+would appreciate credit if you use this file or parts of it.
+*/
+
+int exp_window_size_set();
+int exp_window_size_get();
+
+void exp_win_rows_set();
+void exp_win_rows_get();
+void exp_win_columns_set();
+void exp_win_columns_get();
+
+void exp_win2_rows_set();
+void exp_win2_rows_get();
+void exp_win2_columns_set();
+void exp_win2_columns_get();
diff --git a/expect/expect.c b/expect/expect.c
new file mode 100644
index 00000000000..a105d944c33
--- /dev/null
+++ b/expect/expect.c
@@ -0,0 +1,3035 @@
+/* expect.c - expect commands
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <ctype.h> /* for isspace */
+#include <time.h> /* for time(3) */
+#if 0
+#include <setjmp.h>
+#endif
+
+#include "expect_cf.h"
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "tcl.h"
+
+#include "string.h"
+
+#include "tclRegexp.h"
+#include "exp_rename.h"
+#include "exp_prog.h"
+#include "exp_command.h"
+#include "exp_log.h"
+#include "exp_event.h"
+#include "exp_tty.h"
+#include "exp_tstamp.h" /* this should disappear when interact */
+ /* loses ref's to it */
+#ifdef TCL_DEBUGGER
+#include "Dbg.h"
+#endif
+
+/* CYGNUS LOCAL: dj/expect */
+#if defined(__CYGWIN__) || defined(__CYGWIN32__)
+/* Hack. expect is a mongrel win32/cygwin app, so we can't rely on tcl to
+ properly poll our descriptors. This define lets timeouts work. */
+#define SIMPLE_EVENT
+#endif
+/* END CYGNUS LOCAL: dj/expect */
+
+/* initial length of strings that we can guarantee patterns can match */
+int exp_default_match_max = 2000;
+#define INIT_EXPECT_TIMEOUT_LIT "10" /* seconds */
+#define INIT_EXPECT_TIMEOUT 10 /* seconds */
+int exp_default_parity = TRUE;
+int exp_default_rm_nulls = TRUE;
+
+/* user variable names */
+#define EXPECT_TIMEOUT "timeout"
+#define EXPECT_OUT "expect_out"
+
+/* 1 ecase struct is reserved for each case in the expect command. Note that
+eof/timeout don't use any of theirs, but the algorithm is simpler this way. */
+
+struct ecase { /* case for expect command */
+ struct exp_i *i_list;
+ char *pat; /* original pattern spec */
+ char *body; /* ptr to body to be executed upon match */
+#define PAT_EOF 1
+#define PAT_TIMEOUT 2
+#define PAT_DEFAULT 3
+#define PAT_FULLBUFFER 4
+#define PAT_GLOB 5 /* glob-style pattern list */
+#define PAT_RE 6 /* regular expression */
+#define PAT_EXACT 7 /* exact string */
+#define PAT_NULL 8 /* ASCII 0 */
+#define PAT_TYPES 9 /* used to size array of pattern type descriptions */
+ int use; /* PAT_XXX */
+ int simple_start;/* offset from start of buffer denoting where a */
+ /* glob or exact match begins */
+ int transfer; /* if false, leave matched chars in input stream */
+ int indices; /* if true, write indices */
+/* int iwrite;*/ /* if true write spawn_id */
+ int iread; /* if true, reread indirects */
+ int timestamp; /* if true, write timestamps */
+#define CASE_UNKNOWN 0
+#define CASE_NORM 1
+#define CASE_LOWER 2
+ int Case; /* convert case before doing match? */
+ regexp *re; /* if this is 0, then pattern match via glob */
+};
+
+/* descriptions of the pattern types, used for debugging */
+char *pattern_style[PAT_TYPES];
+
+struct exp_cases_descriptor {
+ int count;
+ struct ecase **cases;
+};
+
+/* This describes an Expect command */
+static
+struct exp_cmd_descriptor {
+ int cmdtype; /* bg, before, after */
+ int duration; /* permanent or temporary */
+ int timeout_specified_by_flag; /* if -timeout flag used */
+ int timeout; /* timeout period if flag used */
+ struct exp_cases_descriptor ecd;
+ struct exp_i *i_list;
+} exp_cmds[4];
+/* note that exp_cmds[FG] is just a fake, the real contents is stored
+ in some dynamically-allocated variable. We use exp_cmds[FG] mostly
+ as a well-known address and also as a convenience and so we allocate
+ just a few of its fields that we need. */
+
+static void
+exp_cmd_init(cmd,cmdtype,duration)
+struct exp_cmd_descriptor *cmd;
+int duration;
+int cmdtype;
+{
+ cmd->duration = duration;
+ cmd->cmdtype = cmdtype;
+ cmd->ecd.cases = 0;
+ cmd->ecd.count = 0;
+ cmd->i_list = 0;
+}
+
+static int i_read_errno;/* place to save errno, if i_read() == -1, so it
+ doesn't get overwritten before we get to read it */
+#if 0
+static jmp_buf env; /* for interruptable read() */
+ /* longjmp(env,1) times out the read */
+ /* longjmp(env,2) restarts the read */
+static int env_valid = FALSE; /* whether we can longjmp or not */
+#endif
+
+#ifdef SIMPLE_EVENT
+static int alarm_fired; /* if alarm occurs */
+#endif
+
+void exp_background_filehandlers_run_all();
+
+/* exp_indirect_updateX is called by Tcl when an indirect variable is set */
+static char *exp_indirect_update1(); /* 1-part Tcl variable names */
+static char *exp_indirect_update2(); /* 2-part Tcl variable names */
+
+static int exp_i_read _ANSI_ARGS_((Tcl_Interp *,int,int,int));
+
+#ifdef SIMPLE_EVENT
+/*ARGSUSED*/
+static RETSIGTYPE
+sigalarm_handler(n)
+int n; /* unused, for compatibility with STDC */
+{
+ alarm_fired = TRUE;
+#if 0
+ /* check env_valid first to protect us from the alarm occurring */
+ /* in the window between i_read and alarm(0) */
+ if (env_valid) longjmp(env,1);
+#endif /*0*/
+}
+#endif /*SIMPLE_EVENT*/
+
+#if 0
+/*ARGSUSED*/
+static RETSIGTYPE
+sigalarm_handler(n)
+int n; /* unused, for compatibility with STDC */
+{
+#ifdef REARM_SIG
+ signal(SIGALRM,sigalarm_handler);
+#endif
+
+ /* check env_valid first to protect us from the alarm occurring */
+ /* in the window between i_read and alarm(0) */
+ if (env_valid) longjmp(env,1);
+}
+#endif /*0*/
+
+#if 0
+
+/* upon interrupt, act like timeout */
+/*ARGSUSED*/
+static RETSIGTYPE
+sigint_handler(n)
+int n; /* unused, for compatibility with STDC */
+{
+#ifdef REARM_SIG
+ signal(SIGINT,sigint_handler);/* not nec. for BSD, but doesn't hurt */
+#endif
+
+#ifdef TCL_DEBUGGER
+ if (exp_tcl_debugger_available) {
+ /* if the debugger is active and we're reading something, */
+ /* force the debugger to go interactive now and when done, */
+ /* restart the read. */
+
+ Dbg_On(exp_interp,env_valid);
+
+ /* restart the read */
+ if (env_valid) longjmp(env,2);
+
+ /* if no read is in progess, just let debugger start at */
+ /* the next command. */
+ return;
+ }
+#endif
+
+#if 0
+/* the ability to timeout a read via ^C is hereby removed 8-Mar-1993 - DEL */
+
+ /* longjmp if we are executing a read inside of expect command */
+ if (env_valid) longjmp(env,1);
+#endif
+
+ /* if anywhere else in code, prepare to exit */
+ exp_exit(exp_interp,0);
+}
+#endif /*0*/
+
+/* remove nulls from s. Initially, the number of chars in s is c, */
+/* not strlen(s). This count does not include the trailing null. */
+/* returns number of nulls removed. */
+static int
+rm_nulls(s,c)
+char *s;
+int c;
+{
+ char *s2 = s; /* points to place in original string to put */
+ /* next non-null character */
+ int count = 0;
+ int i;
+
+ for (i=0;i<c;i++,s++) {
+ if (0 == *s) {
+ count++;
+ continue;
+ }
+ if (count) *s2 = *s;
+ s2++;
+ }
+ return(count);
+}
+
+/* free up everything in ecase */
+static void
+free_ecase(interp,ec,free_ilist)
+Tcl_Interp *interp;
+struct ecase *ec;
+int free_ilist; /* if we should free ilist */
+{
+ if (ec->re) ckfree((char *)ec->re);
+
+ if (ec->i_list->duration == EXP_PERMANENT) {
+ if (ec->pat) ckfree(ec->pat);
+ if (ec->body) ckfree(ec->body);
+ }
+
+ if (free_ilist) {
+ ec->i_list->ecount--;
+ if (ec->i_list->ecount == 0)
+ exp_free_i(interp,ec->i_list,exp_indirect_update2);
+ }
+
+ ckfree((char *)ec); /* NEW */
+}
+
+/* free up any argv structures in the ecases */
+static void
+free_ecases(interp,eg,free_ilist)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *eg;
+int free_ilist; /* if true, free ilists */
+{
+ int i;
+
+ if (!eg->ecd.cases) return;
+
+ for (i=0;i<eg->ecd.count;i++) {
+ free_ecase(interp,eg->ecd.cases[i],free_ilist);
+ }
+ ckfree((char *)eg->ecd.cases);
+
+ eg->ecd.cases = 0;
+ eg->ecd.count = 0;
+}
+
+
+#if 0
+/* no standard defn for this, and some systems don't even have it, so avoid */
+/* the whole quagmire by calling it something else */
+static char *exp_strdup(s)
+char *s;
+{
+ char *news = ckalloc(strlen(s) + 1);
+ strcpy(news,s);
+ return(news);
+}
+#endif
+
+/* In many places, there is no need to malloc a copy of a string, since it */
+/* will be freed before we return to Tcl */
+static void
+save_str(lhs,rhs,nosave)
+char **lhs; /* left hand side */
+char *rhs; /* right hand side */
+int nosave;
+{
+ if (nosave || (rhs == 0)) {
+ *lhs = rhs;
+ } else {
+ *lhs = ckalloc(strlen(rhs) + 1);
+ strcpy(*lhs,rhs);
+ }
+}
+
+/* return TRUE if string appears to be a set of arguments
+ The intent of this test is to support the ability of commands to have
+ all their args braced as one. This conflicts with the possibility of
+ actually intending to have a single argument.
+ The bad case is in expect which can have a single argument with embedded
+ \n's although it's rare. Examples that this code should handle:
+ \n FALSE (pattern)
+ \n\n FALSE
+ \n \n \n FALSE
+ foo FALSE
+ foo\n FALSE
+ \nfoo\n TRUE (set of args)
+ \nfoo\nbar TRUE
+
+ Current test is very cheap and almost always right :-)
+*/
+int
+exp_one_arg_braced(p)
+char *p;
+{
+ int seen_nl = FALSE;
+
+ for (;*p;p++) {
+ if (*p == '\n') {
+ seen_nl = TRUE;
+ continue;
+ }
+
+ if (!isspace(*p)) {
+ return(seen_nl);
+ }
+ }
+ return FALSE;
+}
+
+/* called to execute a command of only one argument - a hack to commands */
+/* to be called with all args surrounded by an outer set of braces */
+/* returns TCL_whatever */
+/*ARGSUSED*/
+int
+exp_eval_with_one_arg(clientData,interp,argv)
+ClientData clientData;
+Tcl_Interp *interp;
+char **argv;
+{
+ char *buf;
+ int rc;
+ char *a;
+
+ /* + 11 is for " -nobrace " and null at end */
+ buf = ckalloc(strlen(argv[0]) + strlen(argv[1]) + 11);
+ /* recreate statement (with -nobrace to prevent recursion) */
+ sprintf(buf,"%s -nobrace %s",argv[0],argv[1]);
+
+ /*
+ * replace top-level newlines with blanks
+ */
+
+ /* Should only be necessary to run over argv[1] and then sprintf */
+ /* that into the buffer, but the ICEM guys insist that writing */
+ /* back over the original arguments makes their Tcl compiler very */
+ /* unhappy. */
+ for (a=buf;*a;) {
+ extern char *TclWordEnd();
+
+ for (;isspace(*a);a++) {
+ if (*a == '\n') *a = ' ';
+ }
+#if TCL_MAJOR_VERSION < 8
+ a = TclWordEnd(a,0,(int *)0)+1;
+#else
+ a = TclWordEnd(a,&a[strlen(a)],0,(int *)0)+1;
+#endif
+ }
+
+ rc = Tcl_Eval(interp,buf);
+
+ ckfree(buf);
+ return(rc);
+}
+
+static void
+ecase_clear(ec)
+struct ecase *ec;
+{
+ ec->i_list = 0;
+ ec->pat = 0;
+ ec->body = 0;
+ ec->transfer = TRUE;
+ ec->indices = FALSE;
+/* ec->iwrite = FALSE;*/
+ ec->iread = FALSE;
+ ec->timestamp = FALSE;
+ ec->re = 0;
+ ec->Case = CASE_NORM;
+ ec->use = PAT_GLOB;
+}
+
+static struct ecase *
+ecase_new()
+{
+ struct ecase *ec = (struct ecase *)ckalloc(sizeof(struct ecase));
+
+ ecase_clear(ec);
+ return ec;
+}
+
+/*
+
+parse_expect_args parses the arguments to expect or its variants.
+It normally returns TCL_OK, and returns TCL_ERROR for failure.
+(It can't return i_list directly because there is no way to differentiate
+between clearing, say, expect_before and signalling an error.)
+
+eg (expect_global) is initialized to reflect the arguments parsed
+eg->ecd.cases is an array of ecases
+eg->ecd.count is the # of ecases
+eg->i_list is a linked list of exp_i's which represent the -i info
+
+Each exp_i is chained to the next so that they can be easily free'd if
+necessary. Each exp_i has a reference count. If the -i is not used
+(e.g., has no following patterns), the ref count will be 0.
+
+Each ecase points to an exp_i. Several ecases may point to the same exp_i.
+Variables named by indirect exp_i's are read for the direct values.
+
+If called from a foreground expect and no patterns or -i are given, a
+default exp_i is forced so that the command "expect" works right.
+
+The exp_i chain can be broken by the caller if desired.
+
+*/
+
+static int
+parse_expect_args(interp,eg,default_spawn_id,argc,argv)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *eg;
+int default_spawn_id; /* suggested master if called as expect_user or _tty */
+int argc;
+char **argv;
+{
+ int i;
+ char *arg;
+ struct ecase ec; /* temporary to collect args */
+
+ argv++;
+ argc--;
+
+ eg->timeout_specified_by_flag = FALSE;
+
+ ecase_clear(&ec);
+
+ /* Allocate an array to store the ecases. Force array even if 0 */
+ /* cases. This will often be too large (i.e., if there are flags) */
+ /* but won't affect anything. */
+
+ eg->ecd.cases = (struct ecase **)ckalloc(
+ sizeof(struct ecase *) * (1+(argc/2)));
+
+ eg->ecd.count = 0;
+
+ for (i = 0;i<argc;i++) {
+ arg = argv[i];
+
+ if (exp_flageq("timeout",arg,7)) {
+ ec.use = PAT_TIMEOUT;
+ } else if (exp_flageq("eof",arg,3)) {
+ ec.use = PAT_EOF;
+ } else if (exp_flageq("full_buffer",arg,11)) {
+ ec.use = PAT_FULLBUFFER;
+ } else if (exp_flageq("default",arg,7)) {
+ ec.use = PAT_DEFAULT;
+ } else if (exp_flageq("null",arg,4)) {
+ ec.use = PAT_NULL;
+ } else if (arg[0] == '-') {
+ arg++;
+ if (exp_flageq1('-',arg) /* "--" is deprecated */
+ || exp_flageq("glob",arg,2)) {
+ i++;
+ /* assignment here is not actually necessary */
+ /* since cases are initialized this way above */
+ /* ec.use = PAT_GLOB; */
+ } else if (exp_flageq("regexp",arg,2)) {
+ i++;
+ ec.use = PAT_RE;
+ TclRegError((char *)0);
+ if (!(ec.re = TclRegComp(argv[i]))) {
+ exp_error(interp,"bad regular expression: %s",
+ TclGetRegError());
+ goto error;
+ }
+ } else if (exp_flageq("exact",arg,2)) {
+ i++;
+ ec.use = PAT_EXACT;
+ } else if (exp_flageq("notransfer",arg,1)) {
+ ec.transfer = 0;
+ continue;
+ } else if (exp_flageq("nocase",arg,3)) {
+ ec.Case = CASE_LOWER;
+ continue;
+ } else if (exp_flageq1('i',arg)) {
+ i++;
+ if (i>=argc) {
+ exp_error(interp,"-i requires following spawn_id");
+ goto error;
+ }
+
+ ec.i_list = exp_new_i_complex(interp,argv[i],
+ eg->duration,exp_indirect_update2);
+
+ ec.i_list->cmdtype = eg->cmdtype;
+
+ /* link new i_list to head of list */
+ ec.i_list->next = eg->i_list;
+ eg->i_list = ec.i_list;
+
+ continue;
+ } else if (exp_flageq("indices",arg,2)) {
+ ec.indices = TRUE;
+ continue;
+ } else if (exp_flageq("iwrite",arg,2)) {
+/* ec.iwrite = TRUE;*/
+ continue;
+ } else if (exp_flageq("iread",arg,2)) {
+ ec.iread = TRUE;
+ continue;
+ } else if (exp_flageq("timestamp",arg,2)) {
+ ec.timestamp = TRUE;
+ continue;
+ } else if (exp_flageq("timeout",arg,2)) {
+ i++;
+ if (i>=argc) {
+ exp_error(interp,"-timeout requires following # of seconds");
+ goto error;
+ }
+
+ eg->timeout = atoi(argv[i]);
+ eg->timeout_specified_by_flag = TRUE;
+ continue;
+ } else if (exp_flageq("nobrace",arg,7)) {
+ /* nobrace does nothing but take up space */
+ /* on the command line which prevents */
+ /* us from re-expanding any command lines */
+ /* of one argument that looks like it should */
+ /* be expanded to multiple arguments. */
+ continue;
+ } else {
+ exp_error(interp,"usage: unrecognized flag <%s>",arg);
+ goto error;
+ }
+ }
+
+ /* if no -i, use previous one */
+ if (!ec.i_list) {
+ /* if no -i flag has occurred yet, use default */
+ if (!eg->i_list) {
+ if (default_spawn_id != EXP_SPAWN_ID_BAD) {
+ eg->i_list = exp_new_i_simple(default_spawn_id,eg->duration);
+ } else {
+ /* it'll be checked later, if used */
+ (void) exp_update_master(interp,&default_spawn_id,0,0);
+ eg->i_list = exp_new_i_simple(default_spawn_id,eg->duration);
+ }
+ }
+ ec.i_list = eg->i_list;
+ }
+ ec.i_list->ecount++;
+
+ /* save original pattern spec */
+ /* keywords such as "-timeout" are saved as patterns here */
+ /* useful for debugging but not otherwise used */
+ save_str(&ec.pat,argv[i],eg->duration == EXP_TEMPORARY);
+ save_str(&ec.body,argv[i+1],eg->duration == EXP_TEMPORARY);
+
+ i++;
+
+ *(eg->ecd.cases[eg->ecd.count] = ecase_new()) = ec;
+
+ /* clear out for next set */
+ ecase_clear(&ec);
+
+ eg->ecd.count++;
+ }
+
+ /* if no patterns at all have appeared force the current */
+ /* spawn id to be added to list anyway */
+
+ if (eg->i_list == 0) {
+ if (default_spawn_id != EXP_SPAWN_ID_BAD) {
+ eg->i_list = exp_new_i_simple(default_spawn_id,eg->duration);
+ } else {
+ /* it'll be checked later, if used */
+ (void) exp_update_master(interp,&default_spawn_id,0,0);
+ eg->i_list = exp_new_i_simple(default_spawn_id,eg->duration);
+ }
+ }
+
+ return(TCL_OK);
+
+ error:
+ /* very hard to free case_master_list here if it hasn't already */
+ /* been attached to a case, ugh */
+
+ /* note that i_list must be avail to free ecases! */
+ free_ecases(interp,eg,0);
+
+ /* undo temporary ecase */
+ /* free_ecase doesn't quite handle this right, so do it by hand */
+ if (ec.re) ckfree((char *)ec.re);
+ if (eg->duration == EXP_PERMANENT) {
+ if (ec.pat) ckfree(ec.pat);
+ if (ec.body) ckfree(ec.body);
+ }
+
+ if (eg->i_list)
+ exp_free_i(interp,eg->i_list,exp_indirect_update2);
+ return(TCL_ERROR);
+}
+
+#define EXP_IS_DEFAULT(x) ((x) == EXP_TIMEOUT || (x) == EXP_EOF)
+
+static char yes[] = "yes\r\n";
+static char no[] = "no\r\n";
+
+/* this describes status of a successful match */
+struct eval_out {
+ struct ecase *e; /* ecase that matched */
+ struct exp_f *f; /* struct exp_f that matched */
+ char *buffer; /* buffer that matched */
+ int match; /* # of chars in buffer that matched */
+ /* or # of chars in buffer at EOF */
+};
+
+
+/* like eval_cases, but handles only a single cases that needs a real */
+/* string match */
+/* returns EXP_X where X is MATCH, NOMATCH, FULLBUFFER, TCLERRROR */
+static int
+eval_case_string(interp,e,m,o,last_f,last_case,suffix)
+Tcl_Interp *interp;
+struct ecase *e;
+int m;
+struct eval_out *o; /* 'output' - i.e., final case of interest */
+/* next two args are for debugging, when they change, reprint buffer */
+struct exp_f **last_f;
+int *last_case;
+char *suffix;
+{
+ struct exp_f *f = exp_fs + m;
+ char *buffer;
+
+ /* if -nocase, use the lowerized buffer */
+ buffer = ((e->Case == CASE_NORM)?f->buffer:f->lower);
+
+ /* if master or case changed, redisplay debug-buffer */
+ if ((f != *last_f) || e->Case != *last_case) {
+ debuglog("\r\nexpect%s: does \"%s\" (spawn_id %d) match %s ",
+ suffix,
+ dprintify(buffer),f-exp_fs,
+ pattern_style[e->use]);
+ *last_f = f;
+ *last_case = e->Case;
+ }
+
+ if (e->use == PAT_RE) {
+ debuglog("\"%s\"? ",dprintify(e->pat));
+ TclRegError((char *)0);
+ if (buffer && TclRegExec(e->re,buffer,buffer)) {
+ o->e = e;
+ o->match = e->re->endp[0]-buffer;
+ o->buffer = buffer;
+ o->f = f;
+ debuglog(yes);
+ return(EXP_MATCH);
+ } else {
+ debuglog(no);
+ if (TclGetRegError()) {
+ exp_error(interp,"-re failed: %s",TclGetRegError());
+ return(EXP_TCLERROR);
+ }
+ }
+ } else if (e->use == PAT_GLOB) {
+ int match; /* # of chars that matched */
+
+ debuglog("\"%s\"? ",dprintify(e->pat));
+ if (buffer && (-1 != (match = Exp_StringMatch(
+ buffer,e->pat,&e->simple_start)))) {
+ o->e = e;
+ o->match = match;
+ o->buffer = buffer;
+ o->f = f;
+ debuglog(yes);
+ return(EXP_MATCH);
+ } else debuglog(no);
+ } else if (e->use == PAT_EXACT) {
+ char *p = strstr(buffer,e->pat);
+ debuglog("\"%s\"? ",dprintify(e->pat));
+ if (p) {
+ e->simple_start = p - buffer;
+ o->e = e;
+ o->match = strlen(e->pat);
+ o->buffer = buffer;
+ o->f = f;
+ debuglog(yes);
+ return(EXP_MATCH);
+ } else debuglog(no);
+ } else if (e->use == PAT_NULL) {
+ int i = 0;
+ debuglog("null? ");
+ for (;i<f->size;i++) {
+ if (buffer[i] == 0) {
+ o->e = e;
+ o->match = i+1; /* in this case, match is */
+ /* just the # of chars + 1 */
+ /* before the null */
+ o->buffer = buffer;
+ o->f = f;
+ debuglog(yes);
+ return EXP_MATCH;
+ }
+ }
+ debuglog(no);
+ } else if ((f->size == f->msize) && (f->size > 0)) {
+ debuglog("%s? ",e->pat);
+ o->e = e;
+ o->match = f->umsize;
+ o->buffer = f->buffer;
+ o->f = f;
+ debuglog(yes);
+ return(EXP_FULLBUFFER);
+ }
+ return(EXP_NOMATCH);
+}
+
+/* sets o.e if successfully finds a matching pattern, eof, timeout or deflt */
+/* returns original status arg or EXP_TCLERROR */
+static int
+eval_cases(interp,eg,m,o,last_f,last_case,status,masters,mcount,suffix)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *eg;
+int m;
+struct eval_out *o; /* 'output' - i.e., final case of interest */
+/* next two args are for debugging, when they change, reprint buffer */
+struct exp_f **last_f;
+int *last_case;
+int status;
+int *masters;
+int mcount;
+char *suffix;
+{
+ int i;
+ int em; /* master of ecase */
+ struct ecase *e;
+
+ if (o->e || status == EXP_TCLERROR || eg->ecd.count == 0) return(status);
+
+ if (status == EXP_TIMEOUT) {
+ for (i=0;i<eg->ecd.count;i++) {
+ e = eg->ecd.cases[i];
+ if (e->use == PAT_TIMEOUT || e->use == PAT_DEFAULT) {
+ o->e = e;
+ break;
+ }
+ }
+ return(status);
+ } else if (status == EXP_EOF) {
+ for (i=0;i<eg->ecd.count;i++) {
+ e = eg->ecd.cases[i];
+ if (e->use == PAT_EOF || e->use == PAT_DEFAULT) {
+ struct exp_fd_list *fdl;
+
+ for (fdl=e->i_list->fd_list; fdl ;fdl=fdl->next) {
+ em = fdl->fd;
+ if (em == EXP_SPAWN_ID_ANY || em == m) {
+ o->e = e;
+ return(status);
+ }
+ }
+ }
+ }
+ return(status);
+ }
+
+ /* the top loops are split from the bottom loop only because I can't */
+ /* split'em further. */
+
+ /* The bufferful condition does not prevent a pattern match from */
+ /* occurring and vice versa, so it is scanned with patterns */
+ for (i=0;i<eg->ecd.count;i++) {
+ struct exp_fd_list *fdl;
+ int j;
+
+ e = eg->ecd.cases[i];
+ if (e->use == PAT_TIMEOUT ||
+ e->use == PAT_DEFAULT ||
+ e->use == PAT_EOF) continue;
+
+ for (fdl = e->i_list->fd_list; fdl; fdl = fdl->next) {
+ em = fdl->fd;
+ /* if em == EXP_SPAWN_ID_ANY, then user is explicitly asking */
+ /* every case to be checked against every master */
+ if (em == EXP_SPAWN_ID_ANY) {
+ /* test against each spawn_id */
+ for (j=0;j<mcount;j++) {
+ status = eval_case_string(interp,e,masters[j],o,last_f,last_case,suffix);
+ if (status != EXP_NOMATCH) return(status);
+ }
+ } else {
+ /* reject things immediately from wrong spawn_id */
+ if (em != m) continue;
+
+ status = eval_case_string(interp,e,m,o,last_f,last_case,suffix);
+ if (status != EXP_NOMATCH) return(status);
+ }
+ }
+ }
+ return(EXP_NOMATCH);
+}
+
+static void
+ecases_remove_by_expi(interp,ecmd,exp_i)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *ecmd;
+struct exp_i *exp_i;
+{
+ int i;
+
+ /* delete every ecase dependent on it */
+ for (i=0;i<ecmd->ecd.count;) {
+ struct ecase *e = ecmd->ecd.cases[i];
+ if (e->i_list == exp_i) {
+ free_ecase(interp,e,0);
+
+ /* shift remaining elements down */
+ /* but only if there are any left */
+ if (i+1 != ecmd->ecd.count) {
+ memcpy(&ecmd->ecd.cases[i],
+ &ecmd->ecd.cases[i+1],
+ ((ecmd->ecd.count - i) - 1) *
+ sizeof(struct exp_cmd_descriptor *));
+ }
+ ecmd->ecd.count--;
+ if (0 == ecmd->ecd.count) {
+ ckfree((char *)ecmd->ecd.cases);
+ ecmd->ecd.cases = 0;
+ }
+ } else {
+ i++;
+ }
+ }
+}
+
+/* remove exp_i from list */
+static void
+exp_i_remove(interp,ei,exp_i)
+Tcl_Interp *interp;
+struct exp_i **ei; /* list to remove from */
+struct exp_i *exp_i; /* element to remove */
+{
+ /* since it's in middle of list, free exp_i by hand */
+ for (;*ei; ei = &(*ei)->next) {
+ if (*ei == exp_i) {
+ *ei = exp_i->next;
+ exp_i->next = 0;
+ exp_free_i(interp,exp_i,exp_indirect_update2);
+ break;
+ }
+ }
+}
+
+/* remove exp_i from list and remove any dependent ecases */
+static void
+exp_i_remove_with_ecases(interp,ecmd,exp_i)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *ecmd;
+struct exp_i *exp_i;
+{
+ ecases_remove_by_expi(interp,ecmd,exp_i);
+ exp_i_remove(interp,&ecmd->i_list,exp_i);
+}
+
+/* remove ecases tied to a single direct spawn id */
+static void
+ecmd_remove_fd(interp,ecmd,m,direct)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *ecmd;
+int m;
+int direct;
+{
+ struct exp_i *exp_i, *next;
+ struct exp_fd_list **fdl;
+
+ for (exp_i=ecmd->i_list;exp_i;exp_i=next) {
+ next = exp_i->next;
+
+ if (!(direct & exp_i->direct)) continue;
+
+ for (fdl = &exp_i->fd_list;*fdl;) {
+ if (m == ((*fdl)->fd)) {
+ struct exp_fd_list *tmp = *fdl;
+ *fdl = (*fdl)->next;
+ exp_free_fd_single(tmp);
+
+ /* if last bg ecase, disarm spawn id */
+ if ((ecmd->cmdtype == EXP_CMD_BG) && (m != EXP_SPAWN_ID_ANY)) {
+ exp_fs[m].bg_ecount--;
+ if (exp_fs[m].bg_ecount == 0) {
+ exp_disarm_background_filehandler(m);
+ exp_fs[m].bg_interp = 0;
+ }
+ }
+
+ continue;
+ }
+ fdl = &(*fdl)->next;
+ }
+
+ /* if left with no fds (and is direct), get rid of it */
+ /* and any dependent ecases */
+ if (exp_i->direct == EXP_DIRECT && !exp_i->fd_list) {
+ exp_i_remove_with_ecases(interp,ecmd,exp_i);
+ }
+ }
+}
+
+/* this is called from exp_close to clean up the fd */
+void
+exp_ecmd_remove_fd_direct_and_indirect(interp,m)
+Tcl_Interp *interp;
+int m;
+{
+ ecmd_remove_fd(interp,&exp_cmds[EXP_CMD_BEFORE],m,EXP_DIRECT|EXP_INDIRECT);
+ ecmd_remove_fd(interp,&exp_cmds[EXP_CMD_AFTER],m,EXP_DIRECT|EXP_INDIRECT);
+ ecmd_remove_fd(interp,&exp_cmds[EXP_CMD_BG],m,EXP_DIRECT|EXP_INDIRECT);
+
+ /* force it - explanation in exp_tk.c where this func is defined */
+ exp_disarm_background_filehandler_force(m);
+}
+
+/* arm a list of background fd's */
+static void
+fd_list_arm(interp,fdl)
+Tcl_Interp *interp;
+struct exp_fd_list *fdl;
+{
+ /* for each spawn id in list, arm if necessary */
+ for (;fdl;fdl=fdl->next) {
+ int m = fdl->fd;
+ if (m == EXP_SPAWN_ID_ANY) continue;
+
+ if (exp_fs[m].bg_ecount == 0) {
+ exp_arm_background_filehandler(m);
+ exp_fs[m].bg_interp = interp;
+ }
+ exp_fs[m].bg_ecount++;
+ }
+}
+
+/* return TRUE if this ecase is used by this fd */
+static int
+exp_i_uses_fd(exp_i,fd)
+struct exp_i *exp_i;
+int fd;
+{
+ struct exp_fd_list *fdp;
+
+ for (fdp = exp_i->fd_list;fdp;fdp=fdp->next) {
+ if (fdp->fd == fd) return 1;
+ }
+ return 0;
+}
+
+static void
+ecase_append(interp,ec)
+Tcl_Interp *interp;
+struct ecase *ec;
+{
+ if (!ec->transfer) Tcl_AppendElement(interp,"-notransfer");
+ if (ec->indices) Tcl_AppendElement(interp,"-indices");
+/* if (ec->iwrite) Tcl_AppendElement(interp,"-iwrite");*/
+ if (!ec->Case) Tcl_AppendElement(interp,"-nocase");
+
+ if (ec->re) Tcl_AppendElement(interp,"-re");
+ else if (ec->use == PAT_GLOB) Tcl_AppendElement(interp,"-gl");
+ else if (ec->use == PAT_EXACT) Tcl_AppendElement(interp,"-ex");
+ Tcl_AppendElement(interp,ec->pat);
+ Tcl_AppendElement(interp,ec->body?ec->body:"");
+}
+
+/* append all ecases that match this exp_i */
+static void
+ecase_by_exp_i_append(interp,ecmd,exp_i)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *ecmd;
+struct exp_i *exp_i;
+{
+ int i;
+ for (i=0;i<ecmd->ecd.count;i++) {
+ if (ecmd->ecd.cases[i]->i_list == exp_i) {
+ ecase_append(interp,ecmd->ecd.cases[i]);
+ }
+ }
+}
+
+static void
+exp_i_append(interp,exp_i)
+Tcl_Interp *interp;
+struct exp_i *exp_i;
+{
+ Tcl_AppendElement(interp,"-i");
+ if (exp_i->direct == EXP_INDIRECT) {
+ Tcl_AppendElement(interp,exp_i->variable);
+ } else {
+ struct exp_fd_list *fdp;
+
+ /* if more than one element, add braces */
+ if (exp_i->fd_list->next)
+ Tcl_AppendResult(interp," {",(char *)0);
+
+ for (fdp = exp_i->fd_list;fdp;fdp=fdp->next) {
+ char buf[10]; /* big enough for a small int */
+ sprintf(buf,"%d",fdp->fd);
+ Tcl_AppendElement(interp,buf);
+ }
+
+ if (exp_i->fd_list->next)
+ Tcl_AppendResult(interp,"} ",(char *)0);
+ }
+}
+
+#if 0
+/* delete ecases based on named -i descriptors */
+int
+expect_delete(interp,ecmd,argc,argv)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *ecmd;
+int argc;
+char **argv;
+{
+ while (*argv) {
+ if (streq(argv[0],"-i") && argv[1]) {
+ iflag = argv[1];
+ argc-=2; argv+=2;
+ } else if (streq(argv[0],"-all")) {
+ all = TRUE;
+ argc--; argv++;
+ } else if (streq(argv[0],"-noindirect")) {
+ direct &= ~EXP_INDIRECT;
+ argc--; argv++;
+ } else {
+ exp_error(interp,"usage: -delete [-all | -i spawn_id]\n");
+ return TCL_ERROR;
+ }
+ }
+
+ if (all) {
+ /* same logic as at end of regular expect cmd */
+ free_ecases(interp,ecmd,0);
+ exp_free_i(interp,ecmd->i_list,exp_indirect_update2);
+ return TCL_OK;
+ }
+
+ if (!iflag) {
+ if (0 == exp_update_master(interp,&m,0,0)) {
+ return TCL_ERROR;
+ }
+ } else if (Tcl_GetInt(interp,iflag,&m) != TCL_OK) {
+ /* handle as in indirect */
+
+ struct exp_i **old_i;
+
+ for (old_i=&ecmd->i_list;*old_i;) {
+ struct exp_i *tmp;
+
+ if ((*old_i)->direct == EXP_DIRECT) continue;
+ if (!streq((*old_i)->variable,iflag)) continue;
+
+ ecases_remove_by_expi(interp,ecmd,*old_i);
+
+ /* unlink from middle of list */
+ tmp = *old_i;
+ *old_i = tmp->next;
+ tmp->next = 0;
+ exp_free_i(interp,tmp_i,exp_indirect_update2);
+ } else {
+ old_i = &(*old_i)->next;
+ }
+ return TCL_OK;
+ }
+
+ /* delete ecases of this direct_fd */
+ /* unfinish after this ... */
+ for (exp_i=ecmd->i_list;exp_i;exp_i=exp_i->next) {
+ if (!(direct & exp_i->direct)) continue;
+ if (!exp_i_uses_fd(exp_i,m)) continue;
+
+ /* delete each ecase that uses this exp_i */
+
+
+ ecase_by_exp_i_append(interp,ecmd,exp_i);
+ }
+
+ return TCL_OK;
+}
+#endif
+
+/* return current setting of the permanent expect_before/after/bg */
+int
+expect_info(interp,ecmd,argc,argv)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *ecmd;
+int argc;
+char **argv;
+{
+ struct exp_i *exp_i;
+ int i;
+ int direct = EXP_DIRECT|EXP_INDIRECT;
+ char *iflag = 0;
+ int all = FALSE; /* report on all fds */
+ int m;
+
+ while (*argv) {
+ if (streq(argv[0],"-i") && argv[1]) {
+ iflag = argv[1];
+ argc-=2; argv+=2;
+ } else if (streq(argv[0],"-all")) {
+ all = TRUE;
+ argc--; argv++;
+ } else if (streq(argv[0],"-noindirect")) {
+ direct &= ~EXP_INDIRECT;
+ argc--; argv++;
+ } else {
+ exp_error(interp,"usage: -info [-all | -i spawn_id]\n");
+ return TCL_ERROR;
+ }
+ }
+
+ if (all) {
+ /* avoid printing out -i when redundant */
+ struct exp_i *previous = 0;
+
+ for (i=0;i<ecmd->ecd.count;i++) {
+ if (previous != ecmd->ecd.cases[i]->i_list) {
+ exp_i_append(interp,ecmd->ecd.cases[i]->i_list);
+ previous = ecmd->ecd.cases[i]->i_list;
+ }
+ ecase_append(interp,ecmd->ecd.cases[i]);
+ }
+ return TCL_OK;
+ }
+
+ if (!iflag) {
+ if (0 == exp_update_master(interp,&m,0,0)) {
+ return TCL_ERROR;
+ }
+ } else if (Tcl_GetInt(interp,iflag,&m) != TCL_OK) {
+ /* handle as in indirect */
+ Tcl_ResetResult(interp);
+ for (i=0;i<ecmd->ecd.count;i++) {
+ if (ecmd->ecd.cases[i]->i_list->direct == EXP_INDIRECT &&
+ streq(ecmd->ecd.cases[i]->i_list->variable,iflag)) {
+ ecase_append(interp,ecmd->ecd.cases[i]);
+ }
+ }
+ return TCL_OK;
+ }
+
+ /* print ecases of this direct_fd */
+ for (exp_i=ecmd->i_list;exp_i;exp_i=exp_i->next) {
+ if (!(direct & exp_i->direct)) continue;
+ if (!exp_i_uses_fd(exp_i,m)) continue;
+ ecase_by_exp_i_append(interp,ecmd,exp_i);
+ }
+
+ return TCL_OK;
+}
+
+/* Exp_ExpectGlobalCmd is invoked to process expect_before/after */
+/*ARGSUSED*/
+int
+Exp_ExpectGlobalCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int result = TCL_OK;
+ struct exp_i *exp_i, **eip;
+ struct exp_fd_list *fdl; /* temp for interating over fd_list */
+ struct exp_cmd_descriptor eg;
+ int count;
+
+ struct exp_cmd_descriptor *ecmd = (struct exp_cmd_descriptor *) clientData;
+
+ if ((argc == 2) && exp_one_arg_braced(argv[1])) {
+ return(exp_eval_with_one_arg(clientData,interp,argv));
+ } else if ((argc == 3) && streq(argv[1],"-brace")) {
+ char *new_argv[2];
+ new_argv[0] = argv[0];
+ new_argv[1] = argv[2];
+ return(exp_eval_with_one_arg(clientData,interp,new_argv));
+ }
+
+ if (argc > 1 && (argv[1][0] == '-')) {
+ if (exp_flageq("info",&argv[1][1],4)) {
+ return(expect_info(interp,ecmd,argc-2,argv+2));
+ }
+ }
+
+ exp_cmd_init(&eg,ecmd->cmdtype,EXP_PERMANENT);
+
+ if (TCL_ERROR == parse_expect_args(interp,&eg,EXP_SPAWN_ID_BAD,
+ argc,argv)) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * visit each NEW direct exp_i looking for spawn ids.
+ * When found, remove them from any OLD exp_i's.
+ */
+
+ /* visit each exp_i */
+ for (exp_i=eg.i_list;exp_i;exp_i=exp_i->next) {
+ if (exp_i->direct == EXP_INDIRECT) continue;
+
+ /* for each spawn id, remove it from ecases */
+ for (fdl=exp_i->fd_list;fdl;fdl=fdl->next) {
+ int m = fdl->fd;
+
+ /* validate all input descriptors */
+ if (m != EXP_SPAWN_ID_ANY) {
+ if (!exp_fd2f(interp,m,1,1,"expect")) {
+ result = TCL_ERROR;
+ goto cleanup;
+ }
+ }
+
+ /* remove spawn id from exp_i */
+ ecmd_remove_fd(interp,ecmd,m,EXP_DIRECT);
+ }
+ }
+
+ /*
+ * For each indirect variable, release its old ecases and
+ * clean up the matching spawn ids.
+ * Same logic as in "expect_X delete" command.
+ */
+
+ for (exp_i=eg.i_list;exp_i;exp_i=exp_i->next) {
+ struct exp_i **old_i;
+
+ if (exp_i->direct == EXP_DIRECT) continue;
+
+ for (old_i = &ecmd->i_list;*old_i;) {
+ struct exp_i *tmp;
+
+ if (((*old_i)->direct == EXP_DIRECT) ||
+ (!streq((*old_i)->variable,exp_i->variable))) {
+ old_i = &(*old_i)->next;
+ continue;
+ }
+
+ ecases_remove_by_expi(interp,ecmd,*old_i);
+
+ /* unlink from middle of list */
+ tmp = *old_i;
+ *old_i = tmp->next;
+ tmp->next = 0;
+ exp_free_i(interp,tmp,exp_indirect_update2);
+ }
+
+ /* if new one has ecases, update it */
+ if (exp_i->ecount) {
+ char *msg = exp_indirect_update1(interp,ecmd,exp_i);
+ if (msg) {
+ /* unusual way of handling error return */
+ /* because of Tcl's variable tracing */
+ strcpy(interp->result,msg);
+ result = TCL_ERROR;
+ goto indirect_update_abort;
+ }
+ }
+ }
+ /* empty i_lists have to be removed from global eg.i_list */
+ /* before returning, even if during error */
+ indirect_update_abort:
+
+ /*
+ * New exp_i's that have 0 ecases indicate fd/vars to be deleted.
+ * Now that the deletions have been done, discard the new exp_i's.
+ */
+
+ for (exp_i=eg.i_list;exp_i;) {
+ struct exp_i *next = exp_i->next;
+
+ if (exp_i->ecount == 0) {
+ exp_i_remove(interp,&eg.i_list,exp_i);
+ }
+ exp_i = next;
+ }
+ if (result == TCL_ERROR) goto cleanup;
+
+ /*
+ * arm all new bg direct fds
+ */
+
+ if (ecmd->cmdtype == EXP_CMD_BG) {
+ for (exp_i=eg.i_list;exp_i;exp_i=exp_i->next) {
+ if (exp_i->direct == EXP_DIRECT) {
+ fd_list_arm(interp,exp_i->fd_list);
+ }
+ }
+ }
+
+ /*
+ * now that old ecases are gone, add new ecases and exp_i's (both
+ * direct and indirect).
+ */
+
+ /* append ecases */
+
+ count = ecmd->ecd.count + eg.ecd.count;
+ if (eg.ecd.count) {
+ int start_index; /* where to add new ecases in old list */
+
+ if (ecmd->ecd.count) {
+ /* append to end */
+ ecmd->ecd.cases = (struct ecase **)ckrealloc((char *)ecmd->ecd.cases, count * sizeof(struct ecase *));
+ start_index = ecmd->ecd.count;
+ } else {
+ /* append to beginning */
+ ecmd->ecd.cases = (struct ecase **)ckalloc(eg.ecd.count * sizeof(struct ecase *));
+ start_index = 0;
+ }
+ memcpy(&ecmd->ecd.cases[start_index],eg.ecd.cases,
+ eg.ecd.count*sizeof(struct ecase *));
+ ecmd->ecd.count = count;
+ }
+
+ /* append exp_i's */
+ for (eip = &ecmd->i_list;*eip;eip = &(*eip)->next) {
+ /* empty loop to get to end of list */
+ }
+ /* *exp_i now points to end of list */
+
+ *eip = eg.i_list; /* connect new list to end of current list */
+
+ cleanup:
+ if (result == TCL_ERROR) {
+ /* in event of error, free any unreferenced ecases */
+ /* but first, split up i_list so that exp_i's aren't */
+ /* freed twice */
+
+ for (exp_i=eg.i_list;exp_i;) {
+ struct exp_i *next = exp_i->next;
+ exp_i->next = 0;
+ exp_i = next;
+ }
+ free_ecases(interp,&eg,1);
+ } else {
+ if (eg.ecd.cases) ckfree((char *)eg.ecd.cases);
+ }
+
+ if (ecmd->cmdtype == EXP_CMD_BG) {
+ exp_background_filehandlers_run_all();
+ }
+
+ return(result);
+}
+
+/* adjusts file according to user's size request */
+void
+exp_adjust(f)
+struct exp_f *f;
+{
+ int new_msize;
+
+ /* get the latest buffer size. Double the user input for */
+ /* two reasons. 1) Need twice the space in case the match */
+ /* straddles two bufferfuls, 2) easier to hack the division */
+ /* by two when shifting the buffers later on. The extra */
+ /* byte in the malloc's is just space for a null we can slam on the */
+ /* end. It makes the logic easier later. The -1 here is so that */
+ /* requests actually come out to even/word boundaries (if user */
+ /* gives "reasonable" requests) */
+ new_msize = f->umsize*2 - 1;
+ if (new_msize != f->msize) {
+ if (!f->buffer) {
+ /* allocate buffer space for 1st time */
+ f->buffer = ckalloc((unsigned)new_msize+1);
+ f->lower = ckalloc((unsigned)new_msize+1);
+ f->size = 0;
+ } else {
+ /* buffer already exists - resize */
+
+ /* if truncated, forget about some data */
+ if (f->size > new_msize) {
+ /* copy end of buffer down */
+ memmove(f->buffer,f->buffer+(f->size - new_msize),new_msize);
+ memmove(f->lower, f->lower +(f->size - new_msize),new_msize);
+ f->size = new_msize;
+
+ f->key = expect_key++;
+ }
+
+ f->buffer = ckrealloc(f->buffer,new_msize+1);
+ f->lower = ckrealloc(f->lower,new_msize+1);
+ }
+ f->msize = new_msize;
+ f->buffer[f->size] = '\0';
+ f->lower[f->size] = '\0';
+ }
+}
+
+
+/*
+
+ expect_read() does the logical equivalent of a read() for the
+expect command. This includes figuring out which descriptor should
+be read from.
+
+The result of the read() is left in a spawn_id's buffer rather than
+explicitly passing it back. Note that if someone else has modified a
+buffer either before or while this expect is running (i.e., if we or
+some event has called Tcl_Eval which did another expect/interact),
+expect_read will also call this a successful read (for the purposes if
+needing to pattern match against it).
+
+*/
+/* if it returns a negative number, it corresponds to a EXP_XXX result */
+/* if it returns a non-negative number, it means there is data */
+/* (0 means nothing new was actually read, but it should be looked at again) */
+int
+expect_read(interp,masters,masters_max,m,timeout,key)
+Tcl_Interp *interp;
+int *masters; /* If 0, then m is already known and set. */
+int masters_max; /* If *masters is not-zero, then masters_max */
+ /* is the number of masters. */
+ /* If *masters is zero, then masters_max */
+ /* is used as the mask (ready vs except). */
+ /* Crude but simplifies the interface. */
+int *m; /* Out variable to leave new master. */
+int timeout;
+int key;
+{
+ struct exp_f *f;
+ int cc;
+ int write_count;
+ int tcl_set_flags; /* if we have to discard chars, this tells */
+ /* whether to show user locally or globally */
+
+ if (masters == 0) {
+ /* we already know the master, just find out what happened */
+ cc = exp_get_next_event_info(interp,*m,masters_max);
+ tcl_set_flags = TCL_GLOBAL_ONLY;
+ } else {
+ cc = exp_get_next_event(interp,masters,masters_max,m,timeout,key);
+ tcl_set_flags = 0;
+ }
+
+ if (cc == EXP_DATA_NEW) {
+ /* try to read it */
+
+ cc = exp_i_read(interp,*m,timeout,tcl_set_flags);
+
+ /* the meaning of 0 from i_read means eof. Muck with it a */
+ /* little, so that from now on it means "no new data arrived */
+ /* but it should be looked at again anyway". */
+ if (cc == 0) {
+ cc = EXP_EOF;
+ } else if (cc > 0) {
+ f = exp_fs + *m;
+ f->buffer[f->size += cc] = '\0';
+
+ /* strip parity if requested */
+ if (f->parity == 0) {
+ /* do it from end backwards */
+ char *p = f->buffer + f->size - 1;
+ int count = cc;
+ while (count--) {
+ *p-- &= 0x7f;
+ }
+ }
+ } /* else {
+ assert(cc < 0) in which case some sort of error was
+ encountered such as an interrupt with that forced an
+ error return
+ } */
+ } else if (cc == EXP_DATA_OLD) {
+ f = exp_fs + *m;
+ cc = 0;
+ } else if (cc == EXP_RECONFIGURE) {
+ return EXP_RECONFIGURE;
+ }
+
+ if (cc == EXP_ABEOF) { /* abnormal EOF */
+ /* On many systems, ptys produce EIO upon EOF - sigh */
+ if (i_read_errno == EIO) {
+ /* Sun, Cray, BSD, and others */
+ cc = EXP_EOF;
+ } else if (i_read_errno == EINVAL) {
+ /* Solaris 2.4 occasionally returns this */
+ cc = EXP_EOF;
+ } else {
+ if (i_read_errno == EBADF) {
+ exp_error(interp,"bad spawn_id (process died earlier?)");
+ } else {
+ exp_error(interp,"i_read(spawn_id=%d): %s",*m,
+ Tcl_PosixError(interp));
+ exp_close(interp,*m);
+ }
+ return(EXP_TCLERROR);
+ /* was goto error; */
+ }
+ }
+
+ /* EOF, TIMEOUT, and ERROR return here */
+ /* In such cases, there is no need to update screen since, if there */
+ /* was prior data read, it would have been sent to the screen when */
+ /* it was read. */
+ if (cc < 0) return (cc);
+
+ /* update display */
+
+ if (f->size) write_count = f->size - f->printed;
+ else write_count = 0;
+
+ if (write_count) {
+ if (logfile_all || (loguser && logfile)) {
+ fwrite(f->buffer + f->printed,1,write_count,logfile);
+ }
+ /* don't write to user if they're seeing it already, */
+ /* that is, typing it! */
+ if (loguser && !exp_is_stdinfd(*m) && !exp_is_devttyfd(*m))
+ fwrite(f->buffer + f->printed,
+ 1,write_count,stdout);
+ if (debugfile) fwrite(f->buffer + f->printed,
+ 1,write_count,debugfile);
+
+ /* remove nulls from input, since there is no way */
+ /* for Tcl to deal with such strings. Doing it here */
+ /* lets them be sent to the screen, just in case */
+ /* they are involved in formatting operations */
+ if (f->rm_nulls) {
+ f->size -= rm_nulls(f->buffer + f->printed,write_count);
+ }
+ f->buffer[f->size] = '\0';
+
+ /* copy to lowercase buffer */
+ exp_lowmemcpy(f->lower+f->printed,
+ f->buffer+f->printed,
+ 1 + f->size - f->printed);
+
+ f->printed = f->size; /* count'm even if not logging */
+ }
+ return(cc);
+}
+
+/* when buffer fills, copy second half over first and */
+/* continue, so we can do matches over multiple buffers */
+void
+exp_buffer_shuffle(interp,f,save_flags,array_name,caller_name)
+Tcl_Interp *interp;
+struct exp_f *f;
+int save_flags;
+char *array_name;
+char *caller_name;
+{
+ char spawn_id[10]; /* enough for a %d */
+ char match_char; /* place to hold char temporarily */
+ /* uprooted by a NULL */
+
+ int first_half = f->size/2;
+ int second_half = f->size - first_half;
+
+ /*
+ * allow user to see data we are discarding
+ */
+
+ sprintf(spawn_id,"%d",f-exp_fs);
+ debuglog("%s: set %s(spawn_id) \"%s\"\r\n",
+ caller_name,array_name,dprintify(spawn_id));
+ Tcl_SetVar2(interp,array_name,"spawn_id",spawn_id,save_flags);
+
+ /* temporarily null-terminate buffer in middle */
+ match_char = f->buffer[first_half];
+ f->buffer[first_half] = 0;
+
+ debuglog("%s: set %s(buffer) \"%s\"\r\n",
+ caller_name,array_name,dprintify(f->buffer));
+ Tcl_SetVar2(interp,array_name,"buffer",f->buffer,save_flags);
+
+ /* remove middle-null-terminator */
+ f->buffer[first_half] = match_char;
+
+ memcpy(f->buffer,f->buffer+first_half,second_half);
+ memcpy(f->lower, f->lower +first_half,second_half);
+ f->size = second_half;
+ f->printed -= first_half;
+ if (f->printed < 0) f->printed = 0;
+}
+
+/* map EXP_ style return value to TCL_ style return value */
+/* not defined to work on TCL_OK */
+int
+exp_tcl2_returnvalue(x)
+int x;
+{
+ switch (x) {
+ case TCL_ERROR: return EXP_TCLERROR;
+ case TCL_RETURN: return EXP_TCLRET;
+ case TCL_BREAK: return EXP_TCLBRK;
+ case TCL_CONTINUE: return EXP_TCLCNT;
+ case EXP_CONTINUE: return EXP_TCLCNTEXP;
+ case EXP_CONTINUE_TIMER: return EXP_TCLCNTTIMER;
+ case EXP_TCL_RETURN: return EXP_TCLRETTCL;
+ }
+}
+
+/* map from EXP_ style return value to TCL_ style return values */
+int
+exp_2tcl_returnvalue(x)
+int x;
+{
+ switch (x) {
+ case EXP_TCLERROR: return TCL_ERROR;
+ case EXP_TCLRET: return TCL_RETURN;
+ case EXP_TCLBRK: return TCL_BREAK;
+ case EXP_TCLCNT: return TCL_CONTINUE;
+ case EXP_TCLCNTEXP: return EXP_CONTINUE;
+ case EXP_TCLCNTTIMER: return EXP_CONTINUE_TIMER;
+ case EXP_TCLRETTCL: return EXP_TCL_RETURN;
+ }
+}
+
+/* returns # of chars read or (non-positive) error of form EXP_XXX */
+/* returns 0 for end of file */
+/* If timeout is non-zero, set an alarm before doing the read, else assume */
+/* the read will complete immediately. */
+/*ARGSUSED*/
+static int
+exp_i_read(interp,m,timeout,save_flags)
+Tcl_Interp *interp;
+int m;
+int timeout;
+int save_flags;
+{
+ struct exp_f *f;
+ int cc = EXP_TIMEOUT;
+
+ f = exp_fs + m;
+ if (f->size == f->msize)
+ exp_buffer_shuffle(interp,f,save_flags,EXPECT_OUT,"expect");
+
+#ifdef SIMPLE_EVENT
+ restart:
+
+ alarm_fired = FALSE;
+
+ if (timeout > -1) {
+ signal(SIGALRM,sigalarm_handler);
+ alarm((timeout > 0)?timeout:1);
+ }
+#endif
+
+ cc = read(m,f->buffer+f->size, f->msize-f->size);
+ i_read_errno = errno;
+
+#ifdef SIMPLE_EVENT
+ alarm(0);
+
+ if (cc == -1) {
+ /* check if alarm went off */
+ if (i_read_errno == EINTR) {
+ if (alarm_fired) {
+ return EXP_TIMEOUT;
+ } else {
+ if (Tcl_AsyncReady()) {
+ int rc = Tcl_AsyncInvoke(interp,TCL_OK);
+ if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc));
+ }
+ if (!f->valid) {
+ exp_error(interp,"spawn_id %d no longer valid",f-exp_fs);
+ return EXP_TCLERROR;
+ }
+ goto restart;
+ }
+ }
+ }
+#endif
+ return(cc);
+}
+
+/* variables predefined by expect are retrieved using this routine
+which looks in the global space if they are not in the local space.
+This allows the user to localize them if desired, and also to
+avoid having to put "global" in procedure definitions.
+*/
+char *
+exp_get_var(interp,var)
+Tcl_Interp *interp;
+char *var;
+{
+ char *val;
+
+ if (NULL != (val = Tcl_GetVar(interp,var,0 /* local */)))
+ return(val);
+ return(Tcl_GetVar(interp,var,TCL_GLOBAL_ONLY));
+}
+
+static int
+get_timeout(interp)
+Tcl_Interp *interp;
+{
+ static int timeout = INIT_EXPECT_TIMEOUT;
+ char *t;
+
+ if (NULL != (t = exp_get_var(interp,EXPECT_TIMEOUT))) {
+ timeout = atoi(t);
+ }
+ return(timeout);
+}
+
+/* make a copy of a linked list (1st arg) and attach to end of another (2nd
+arg) */
+static int
+update_expect_fds(i_list,fd_union)
+struct exp_i *i_list;
+struct exp_fd_list **fd_union;
+{
+ struct exp_i *p;
+
+ /* for each i_list in an expect statement ... */
+ for (p=i_list;p;p=p->next) {
+ struct exp_fd_list *fdl;
+
+ /* for each fd in the i_list */
+ for (fdl=p->fd_list;fdl;fdl=fdl->next) {
+ struct exp_fd_list *tmpfdl;
+ struct exp_fd_list *u;
+
+ if (fdl->fd == EXP_SPAWN_ID_ANY) continue;
+
+ /* check this one against all so far */
+ for (u = *fd_union;u;u=u->next) {
+ if (fdl->fd == u->fd) goto found;
+ }
+ /* if not found, link in as head of list */
+ tmpfdl = exp_new_fd(fdl->fd);
+ tmpfdl->next = *fd_union;
+ *fd_union = tmpfdl;
+ found:;
+ }
+ }
+ return TCL_OK;
+}
+
+char *
+exp_cmdtype_printable(cmdtype)
+int cmdtype;
+{
+ switch (cmdtype) {
+ case EXP_CMD_FG: return("expect");
+ case EXP_CMD_BG: return("expect_background");
+ case EXP_CMD_BEFORE: return("expect_before");
+ case EXP_CMD_AFTER: return("expect_after");
+ }
+#ifdef LINT
+ return("unknown expect command");
+#endif
+}
+
+/* exp_indirect_update2 is called back via Tcl's trace handler whenever */
+/* an indirect spawn id list is changed */
+/*ARGSUSED*/
+static char *
+exp_indirect_update2(clientData, interp, name1, name2, flags)
+ClientData clientData;
+Tcl_Interp *interp; /* Interpreter containing variable. */
+char *name1; /* Name of variable. */
+char *name2; /* Second part of variable name. */
+int flags; /* Information about what happened. */
+{
+ char *msg;
+
+ struct exp_i *exp_i = (struct exp_i *)clientData;
+ exp_configure_count++;
+ msg = exp_indirect_update1(interp,&exp_cmds[exp_i->cmdtype],exp_i);
+
+ exp_background_filehandlers_run_all();
+
+ return msg;
+}
+
+static char *
+exp_indirect_update1(interp,ecmd,exp_i)
+Tcl_Interp *interp;
+struct exp_cmd_descriptor *ecmd;
+struct exp_i *exp_i;
+{
+ struct exp_fd_list *fdl; /* temp for interating over fd_list */
+
+ /*
+ * disarm any fd's that lose all their ecases
+ */
+
+ if (ecmd->cmdtype == EXP_CMD_BG) {
+ /* clean up each spawn id used by this exp_i */
+ for (fdl=exp_i->fd_list;fdl;fdl=fdl->next) {
+ int m = fdl->fd;
+
+ if (m == EXP_SPAWN_ID_ANY) continue;
+
+ /* silently skip closed or preposterous fds */
+ /* since we're just disabling them anyway */
+ /* preposterous fds will have been reported */
+ /* by code in next section already */
+ if (!exp_fd2f(interp,fdl->fd,1,0,"")) continue;
+
+ exp_fs[m].bg_ecount--;
+ if (exp_fs[m].bg_ecount == 0) {
+ exp_disarm_background_filehandler(m);
+ exp_fs[m].bg_interp = 0;
+ }
+ }
+ }
+
+ /*
+ * reread indirect variable
+ */
+
+ exp_i_update(interp,exp_i);
+
+ /*
+ * check validity of all fd's in variable
+ */
+
+ for (fdl=exp_i->fd_list;fdl;fdl=fdl->next) {
+ /* validate all input descriptors */
+ if (fdl->fd == EXP_SPAWN_ID_ANY) continue;
+
+ if (!exp_fd2f(interp,fdl->fd,1,1,
+ exp_cmdtype_printable(ecmd->cmdtype))) {
+ static char msg[200];
+ sprintf(msg,"%s from indirect variable (%s)",
+ interp->result,exp_i->variable);
+ return msg;
+ }
+ }
+
+ /* for each spawn id in list, arm if necessary */
+ if (ecmd->cmdtype == EXP_CMD_BG) {
+ fd_list_arm(interp,exp_i->fd_list);
+ }
+
+ return (char *)0;
+}
+
+void
+exp_background_filehandlers_run_all()
+{
+ int m;
+ struct exp_f *f;
+
+ /* kick off any that already have input waiting */
+ for (m=0;m<=exp_fd_max;m++) {
+ f = exp_fs + m;
+ if (!f->valid) continue;
+
+ /* is bg_interp the best way to check if armed? */
+ if (f->bg_interp && (f->size > 0)) {
+ exp_background_filehandler((ClientData)f->fd_ptr,0/*ignored*/);
+ }
+ }
+}
+
+/* this function is called from the background when input arrives */
+/*ARGSUSED*/
+void
+exp_background_filehandler(clientData,mask)
+ClientData clientData;
+int mask;
+{
+ int m;
+
+ Tcl_Interp *interp;
+ int cc; /* number of chars returned in a single read */
+ /* or negative EXP_whatever */
+ struct exp_f *f; /* file associated with master */
+
+ int i; /* trusty temporary */
+
+ struct eval_out eo; /* final case of interest */
+ struct exp_f *last_f; /* for differentiating when multiple f's */
+ /* to print out better debugging messages */
+ int last_case; /* as above but for case */
+
+ /* restore our environment */
+ m = *(int *)clientData;
+ f = exp_fs + m;
+ interp = f->bg_interp;
+
+ /* temporarily prevent this handler from being invoked again */
+ exp_block_background_filehandler(m);
+
+ /* if mask == 0, then we've been called because the patterns changed */
+ /* not because the waiting data has changed, so don't actually do */
+ /* any I/O */
+
+ if (mask == 0) {
+ cc = 0;
+ } else {
+ cc = expect_read(interp,(int *)0,mask,&m,EXP_TIME_INFINITY,0);
+ }
+
+do_more_data:
+ eo.e = 0; /* no final case yet */
+ eo.f = 0; /* no final file selected yet */
+ eo.match = 0; /* nothing matched yet */
+
+ /* force redisplay of buffer when debugging */
+ last_f = 0;
+
+ if (cc == EXP_EOF) {
+ /* do nothing */
+ } else if (cc < 0) { /* EXP_TCLERROR or any other weird value*/
+ goto finish;
+ /* if we were going to do this right, we should */
+ /* differentiate between things like HP ioctl-open-traps */
+ /* that fall out here and should rightfully be ignored */
+ /* and real errors that should be reported. Come to */
+ /* think of it, the only errors will come from HP */
+ /* ioctl handshake botches anyway. */
+ } else {
+ /* normal case, got data */
+ /* new data if cc > 0, same old data if cc == 0 */
+
+ /* below here, cc as general status */
+ cc = EXP_NOMATCH;
+ }
+
+ cc = eval_cases(interp,&exp_cmds[EXP_CMD_BEFORE],
+ m,&eo,&last_f,&last_case,cc,&m,1,"_background");
+ cc = eval_cases(interp,&exp_cmds[EXP_CMD_BG],
+ m,&eo,&last_f,&last_case,cc,&m,1,"_background");
+ cc = eval_cases(interp,&exp_cmds[EXP_CMD_AFTER],
+ m,&eo,&last_f,&last_case,cc,&m,1,"_background");
+ if (cc == EXP_TCLERROR) {
+ /* only likely problem here is some internal regexp botch */
+ Tcl_BackgroundError(interp);
+ goto finish;
+ }
+ /* special eof code that cannot be done in eval_cases */
+ /* or above, because it would then be executed several times */
+ if (cc == EXP_EOF) {
+ eo.f = exp_fs + m;
+ eo.match = eo.f->size;
+ eo.buffer = eo.f->buffer;
+ debuglog("expect_background: read eof\r\n");
+ goto matched;
+ }
+ if (!eo.e) {
+ /* if we get here, there must not have been a match */
+ goto finish;
+ }
+
+ matched:
+#define out(i,val) debuglog("expect_background: set %s(%s) \"%s\"\r\n",EXPECT_OUT,i, \
+ dprintify(val)); \
+ Tcl_SetVar2(interp,EXPECT_OUT,i,val,TCL_GLOBAL_ONLY);
+ {
+/* int iwrite = FALSE;*/ /* write spawn_id? */
+ char *body = 0;
+ char *buffer; /* pointer to normal or lowercased data */
+ struct ecase *e = 0; /* points to current ecase */
+ int match = -1; /* characters matched */
+ char match_char; /* place to hold char temporarily */
+ /* uprooted by a NULL */
+ char *eof_body = 0;
+
+ if (eo.e) {
+ e = eo.e;
+ body = e->body;
+/* iwrite = e->iwrite;*/
+ if (cc != EXP_TIMEOUT) {
+ f = eo.f;
+ match = eo.match;
+ buffer = eo.buffer;
+ }
+#if 0
+ if (e->timestamp) {
+ char value[20];
+
+ time(&current_time);
+ elapsed_time = current_time - start_time;
+ elapsed_time_total = current_time - start_time_total;
+ sprintf(value,"%d",elapsed_time);
+ out("seconds",value);
+ sprintf(value,"%d",elapsed_time_total);
+ out("seconds_total",value);
+ /* deprecated */
+ exp_timestamp(interp,&current_time,EXPECT_OUT);
+ }
+#endif
+ } else if (cc == EXP_EOF) {
+ /* read an eof but no user-supplied case */
+ f = eo.f;
+ match = eo.match;
+ buffer = eo.buffer;
+ }
+
+ if (match >= 0) {
+ char name[20], value[20];
+
+ if (e && e->use == PAT_RE) {
+ regexp *re = e->re;
+
+ for (i=0;i<NSUBEXP;i++) {
+ int offset;
+
+ if (re->startp[i] == 0) continue;
+
+ if (e->indices) {
+ /* start index */
+ sprintf(name,"%d,start",i);
+ offset = re->startp[i]-buffer;
+ sprintf(value,"%d",offset);
+ out(name,value);
+
+ /* end index */
+ sprintf(name,"%d,end",i);
+ sprintf(value,"%d",
+ re->endp[i]-buffer-1);
+ out(name,value);
+ }
+
+ /* string itself */
+ sprintf(name,"%d,string",i);
+
+ /* temporarily null-terminate in */
+ /* middle */
+ match_char = *re->endp[i];
+ *re->endp[i] = 0;
+ out(name,re->startp[i]);
+ *re->endp[i] = match_char;
+ }
+ /* redefine length of string that */
+ /* matched for later extraction */
+ match = re->endp[0]-buffer;
+ } else if (e && (e->use == PAT_GLOB || e->use == PAT_EXACT)) {
+ char *str;
+
+ if (e->indices) {
+ /* start index */
+ sprintf(value,"%d",e->simple_start);
+ out("0,start",value);
+
+ /* end index */
+ sprintf(value,"%d",e->simple_start + match - 1);
+ out("0,end",value);
+ }
+
+ /* string itself */
+ str = f->buffer + e->simple_start;
+ /* temporarily null-terminate in middle */
+ match_char = str[match];
+ str[match] = 0;
+ out("0,string",str);
+ str[match] = match_char;
+
+ /* redefine length of string that */
+ /* matched for later extraction */
+ match += e->simple_start;
+ } else if (e && e->use == PAT_NULL && e->indices) {
+ /* start index */
+ sprintf(value,"%d",match-1);
+ out("0,start",value);
+ /* end index */
+ sprintf(value,"%d",match-1);
+ out("0,end",value);
+ } else if (e && e->use == PAT_FULLBUFFER) {
+ debuglog("expect_background: full buffer\r\n");
+ }
+ }
+
+ /* this is broken out of (match > 0) (above) since it can */
+ /* that an EOF occurred with match == 0 */
+ if (eo.f) {
+ char spawn_id[10]; /* enough for a %d */
+
+/* if (iwrite) {*/
+ sprintf(spawn_id,"%d",f-exp_fs);
+ out("spawn_id",spawn_id);
+/* }*/
+
+ /* save buf[0..match] */
+ /* temporarily null-terminate string in middle */
+ match_char = f->buffer[match];
+ f->buffer[match] = 0;
+ out("buffer",f->buffer);
+ /* remove middle-null-terminator */
+ f->buffer[match] = match_char;
+
+ /* "!e" means no case matched - transfer by default */
+ if (!e || e->transfer) {
+ /* delete matched chars from input buffer */
+ f->size -= match;
+ f->printed -= match;
+ if (f->size != 0) {
+ memmove(f->buffer,f->buffer+match,f->size);
+ memmove(f->lower,f->lower+match,f->size);
+ }
+ f->buffer[f->size] = '\0';
+ f->lower[f->size] = '\0';
+ }
+
+ if (cc == EXP_EOF) {
+ /* exp_close() deletes all background bodies */
+ /* so save eof body temporarily */
+ if (body) {
+ eof_body = ckalloc(strlen(body)+1);
+ strcpy(eof_body,body);
+ body = eof_body;
+ }
+
+ exp_close(interp,f - exp_fs);
+ }
+
+ }
+
+ if (body) {
+ int result = Tcl_GlobalEval(interp,body);
+ if (result != TCL_OK) Tcl_BackgroundError(interp);
+
+ if (eof_body) ckfree(eof_body);
+ }
+
+
+ /*
+ * Event handler will not call us back if there is more input
+ * pending but it has already arrived. bg_status will be
+ * "blocked" only if armed.
+ */
+ if (exp_fs[m].valid && (exp_fs[m].bg_status == blocked)
+ && (f->size > 0)) {
+ cc = f->size;
+ goto do_more_data;
+ }
+ }
+ finish:
+ /* fd could have gone away, so check before using */
+ if (exp_fs[m].valid)
+ exp_unblock_background_filehandler(m);
+}
+#undef out
+
+/*ARGSUSED*/
+int
+Exp_ExpectCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int cc; /* number of chars returned in a single read */
+ /* or negative EXP_whatever */
+ int m; /* before doing an actual read, attempt */
+ /* to match upon any spawn_id */
+ struct exp_f *f; /* file associated with master */
+
+ int i; /* trusty temporary */
+ struct exp_cmd_descriptor eg;
+ struct exp_fd_list *fd_list; /* list of masters to watch */
+ struct exp_fd_list *fdl; /* temp for interating over fd_list */
+ int *masters; /* array of masters to watch */
+ int mcount; /* number of masters to watch */
+
+ struct eval_out eo; /* final case of interest */
+
+ int result; /* Tcl result */
+
+ time_t start_time_total;/* time at beginning of this procedure */
+ time_t start_time = 0; /* time when restart label hit */
+ time_t current_time = 0;/* current time (when we last looked)*/
+ time_t end_time; /* future time at which to give up */
+ time_t elapsed_time_total;/* time from now to match/fail/timeout */
+ time_t elapsed_time; /* time from restart to (ditto) */
+
+ struct exp_f *last_f; /* for differentiating when multiple f's */
+ /* to print out better debugging messages */
+ int last_case; /* as above but for case */
+ int first_time = 1; /* if not "restarted" */
+
+ int key; /* identify this expect command instance */
+ int configure_count; /* monitor exp_configure_count */
+
+ int timeout; /* seconds */
+ int remtime; /* remaining time in timeout */
+ int reset_timer; /* should timer be reset after continue? */
+
+ if ((argc == 2) && exp_one_arg_braced(argv[1])) {
+ return(exp_eval_with_one_arg(clientData,interp,argv));
+ } else if ((argc == 3) && streq(argv[1],"-brace")) {
+ char *new_argv[2];
+ new_argv[0] = argv[0];
+ new_argv[1] = argv[2];
+ return(exp_eval_with_one_arg(clientData,interp,new_argv));
+ }
+
+ time(&start_time_total);
+ start_time = start_time_total;
+ reset_timer = TRUE;
+
+ /* make arg list for processing cases */
+ /* do it dynamically, since expect can be called recursively */
+
+ exp_cmd_init(&eg,EXP_CMD_FG,EXP_TEMPORARY);
+ fd_list = 0;
+ masters = 0;
+ if (TCL_ERROR == parse_expect_args(interp,&eg,
+ *(int *)clientData,argc,argv))
+ return TCL_ERROR;
+
+ restart_with_update:
+ /* validate all descriptors */
+ /* and flatten fds into array */
+
+ if ((TCL_ERROR == update_expect_fds(exp_cmds[EXP_CMD_BEFORE].i_list,&fd_list))
+ || (TCL_ERROR == update_expect_fds(exp_cmds[EXP_CMD_AFTER].i_list, &fd_list))
+ || (TCL_ERROR == update_expect_fds(eg.i_list,&fd_list))) {
+ result = TCL_ERROR;
+ goto cleanup;
+ }
+
+ /* declare ourselves "in sync" with external view of close/indirect */
+ configure_count = exp_configure_count;
+
+ /* count and validate fd_list */
+ mcount = 0;
+ for (fdl=fd_list;fdl;fdl=fdl->next) {
+ mcount++;
+ /* validate all input descriptors */
+ if (!exp_fd2f(interp,fdl->fd,1,1,"expect")) {
+ result = TCL_ERROR;
+ goto cleanup;
+ }
+ }
+
+ /* make into an array */
+ masters = (int *)ckalloc(mcount * sizeof(int));
+ for (fdl=fd_list,i=0;fdl;fdl=fdl->next,i++) {
+ masters[i] = fdl->fd;
+ }
+
+ restart:
+ if (first_time) first_time = 0;
+ else time(&start_time);
+
+ if (eg.timeout_specified_by_flag) {
+ timeout = eg.timeout;
+ } else {
+ /* get the latest timeout */
+ timeout = get_timeout(interp);
+ }
+
+ key = expect_key++;
+
+ result = TCL_OK;
+ last_f = 0;
+
+ /* end of restart code */
+
+ eo.e = 0; /* no final case yet */
+ eo.f = 0; /* no final file selected yet */
+ eo.match = 0; /* nothing matched yet */
+
+ /* timeout code is a little tricky, be very careful changing it */
+ if (timeout != EXP_TIME_INFINITY) {
+ /* if exp_continue -continue_timer, do not update end_time */
+ if (reset_timer) {
+ time(&current_time);
+ end_time = current_time + timeout;
+ } else {
+ reset_timer = TRUE;
+ }
+ }
+
+ /* remtime and current_time updated at bottom of loop */
+ remtime = timeout;
+
+ for (;;) {
+ if ((timeout != EXP_TIME_INFINITY) && (remtime < 0)) {
+ cc = EXP_TIMEOUT;
+ } else {
+ cc = expect_read(interp,masters,mcount,&m,remtime,key);
+ }
+
+ /*SUPPRESS 530*/
+ if (cc == EXP_EOF) {
+ /* do nothing */
+ } else if (cc == EXP_TIMEOUT) {
+ debuglog("expect: timed out\r\n");
+ } else if (cc == EXP_RECONFIGURE) {
+ reset_timer = FALSE;
+ goto restart_with_update;
+ } else if (cc < 0) { /* EXP_TCLERROR or any other weird value*/
+ goto error;
+ } else {
+ /* new data if cc > 0, same old data if cc == 0 */
+
+ f = exp_fs + m;
+
+ /* below here, cc as general status */
+ cc = EXP_NOMATCH;
+
+ /* force redisplay of buffer when debugging */
+ last_f = 0;
+ }
+
+ cc = eval_cases(interp,&exp_cmds[EXP_CMD_BEFORE],
+ m,&eo,&last_f,&last_case,cc,masters,mcount,"");
+ cc = eval_cases(interp,&eg,
+ m,&eo,&last_f,&last_case,cc,masters,mcount,"");
+ cc = eval_cases(interp,&exp_cmds[EXP_CMD_AFTER],
+ m,&eo,&last_f,&last_case,cc,masters,mcount,"");
+ if (cc == EXP_TCLERROR) goto error;
+ /* special eof code that cannot be done in eval_cases */
+ /* or above, because it would then be executed several times */
+ if (cc == EXP_EOF) {
+ eo.f = exp_fs + m;
+ eo.match = eo.f->size;
+ eo.buffer = eo.f->buffer;
+ debuglog("expect: read eof\r\n");
+ break;
+ } else if (cc == EXP_TIMEOUT) break;
+ /* break if timeout or eof and failed to find a case for it */
+
+ if (eo.e) break;
+
+ /* no match was made with current data, force a read */
+ f->force_read = TRUE;
+
+ if (timeout != EXP_TIME_INFINITY) {
+ time(&current_time);
+ remtime = end_time - current_time;
+ }
+ }
+
+ goto done;
+
+error:
+ result = exp_2tcl_returnvalue(cc);
+ done:
+#define out(i,val) debuglog("expect: set %s(%s) \"%s\"\r\n",EXPECT_OUT,i, \
+ dprintify(val)); \
+ Tcl_SetVar2(interp,EXPECT_OUT,i,val,0);
+
+ if (result != TCL_ERROR) {
+/* int iwrite = FALSE;*/ /* write spawn_id? */
+ char *body = 0;
+ char *buffer; /* pointer to normal or lowercased data */
+ struct ecase *e = 0; /* points to current ecase */
+ int match = -1; /* characters matched */
+ char match_char; /* place to hold char temporarily */
+ /* uprooted by a NULL */
+ char *eof_body = 0;
+
+ if (eo.e) {
+ e = eo.e;
+ body = e->body;
+/* iwrite = e->iwrite;*/
+ if (cc != EXP_TIMEOUT) {
+ f = eo.f;
+ match = eo.match;
+ buffer = eo.buffer;
+ }
+ if (e->timestamp) {
+ char value[20];
+
+ time(&current_time);
+ elapsed_time = current_time - start_time;
+ elapsed_time_total = current_time - start_time_total;
+ sprintf(value,"%d",elapsed_time);
+ out("seconds",value);
+ sprintf(value,"%d",elapsed_time_total);
+ out("seconds_total",value);
+
+ /* deprecated */
+ exp_timestamp(interp,&current_time,EXPECT_OUT);
+ }
+ } else if (cc == EXP_EOF) {
+ /* read an eof but no user-supplied case */
+ f = eo.f;
+ match = eo.match;
+ buffer = eo.buffer;
+ }
+
+ if (match >= 0) {
+ char name[20], value[20];
+
+ if (e && e->use == PAT_RE) {
+ regexp *re = e->re;
+
+ for (i=0;i<NSUBEXP;i++) {
+ int offset;
+
+ if (re->startp[i] == 0) continue;
+
+ if (e->indices) {
+ /* start index */
+ sprintf(name,"%d,start",i);
+ offset = re->startp[i]-buffer;
+ sprintf(value,"%d",offset);
+ out(name,value);
+
+ /* end index */
+ sprintf(name,"%d,end",i);
+ sprintf(value,"%d",
+ re->endp[i]-buffer-1);
+ out(name,value);
+ }
+
+ /* string itself */
+ sprintf(name,"%d,string",i);
+
+ /* temporarily null-terminate in */
+ /* middle */
+ match_char = *re->endp[i];
+ *re->endp[i] = 0;
+ out(name,re->startp[i]);
+ *re->endp[i] = match_char;
+ }
+ /* redefine length of string that */
+ /* matched for later extraction */
+ match = re->endp[0]-buffer;
+ } else if (e && (e->use == PAT_GLOB || e->use == PAT_EXACT)) {
+ char *str;
+
+ if (e->indices) {
+ /* start index */
+ sprintf(value,"%d",e->simple_start);
+ out("0,start",value);
+
+ /* end index */
+ sprintf(value,"%d",e->simple_start + match - 1);
+ out("0,end",value);
+ }
+
+ /* string itself */
+ str = f->buffer + e->simple_start;
+ /* temporarily null-terminate in middle */
+ match_char = str[match];
+ str[match] = 0;
+ out("0,string",str);
+ str[match] = match_char;
+
+ /* redefine length of string that */
+ /* matched for later extraction */
+ match += e->simple_start;
+ } else if (e && e->use == PAT_NULL && e->indices) {
+ /* start index */
+ sprintf(value,"%d",match-1);
+ out("0,start",value);
+ /* end index */
+ sprintf(value,"%d",match-1);
+ out("0,end",value);
+ } else if (e && e->use == PAT_FULLBUFFER) {
+ debuglog("expect: full buffer\r\n");
+ }
+ }
+
+ /* this is broken out of (match > 0) (above) since it can */
+ /* that an EOF occurred with match == 0 */
+ if (eo.f) {
+ char spawn_id[10]; /* enough for a %d */
+
+/* if (iwrite) {*/
+ sprintf(spawn_id,"%d",f-exp_fs);
+ out("spawn_id",spawn_id);
+/* }*/
+
+ /* save buf[0..match] */
+ /* temporarily null-terminate string in middle */
+ match_char = f->buffer[match];
+ f->buffer[match] = 0;
+ out("buffer",f->buffer);
+ /* remove middle-null-terminator */
+ f->buffer[match] = match_char;
+
+ /* "!e" means no case matched - transfer by default */
+ if (!e || e->transfer) {
+ /* delete matched chars from input buffer */
+ f->size -= match;
+ f->printed -= match;
+ if (f->size != 0) {
+ memmove(f->buffer,f->buffer+match,f->size);
+ memmove(f->lower,f->lower+match,f->size);
+ }
+ f->buffer[f->size] = '\0';
+ f->lower[f->size] = '\0';
+ }
+
+ if (cc == EXP_EOF) {
+ /* exp_close() deletes all background bodies */
+ /* so save eof body temporarily */
+ if (body) {
+ eof_body = ckalloc(strlen(body)+1);
+ strcpy(eof_body,body);
+ body = eof_body;
+ }
+
+ exp_close(interp,f - exp_fs);
+ }
+
+ }
+
+ if (body) {
+ result = Tcl_Eval(interp,body);
+
+ if (eof_body) ckfree(eof_body);
+ }
+ }
+
+ cleanup:
+ if (result == EXP_CONTINUE_TIMER) {
+ reset_timer = FALSE;
+ result = EXP_CONTINUE;
+ }
+
+ if ((result == EXP_CONTINUE)
+ && (configure_count == exp_configure_count)) {
+ debuglog("expect: continuing expect\r\n");
+ goto restart;
+ }
+
+ if (fd_list) {
+ exp_free_fd(fd_list);
+ fd_list = 0;
+ }
+ if (masters) {
+ ckfree((char *)masters);
+ masters = 0;
+ }
+
+ if (result == EXP_CONTINUE) {
+ debuglog("expect: continuing expect after update\r\n");
+ goto restart_with_update;
+ }
+
+ free_ecases(interp,&eg,0); /* requires i_lists to be avail */
+ exp_free_i(interp,eg.i_list,exp_indirect_update2);
+
+ return(result);
+}
+#undef out
+
+/* beginning of deprecated code */
+
+#define out(elt) Tcl_SetVar2(interp,array,elt,ascii,0);
+void
+exp_timestamp(interp,timeval,array)
+Tcl_Interp *interp;
+time_t *timeval;
+char *array;
+{
+ struct tm *tm;
+ char *ascii;
+
+ tm = localtime(timeval); /* split */
+ ascii = asctime(tm); /* print */
+ ascii[24] = '\0'; /* zap trailing \n */
+
+ out("timestamp");
+
+ sprintf(ascii,"%ld",*timeval);
+ out("epoch");
+
+ sprintf(ascii,"%d",tm->tm_sec);
+ out("sec");
+ sprintf(ascii,"%d",tm->tm_min);
+ out("min");
+ sprintf(ascii,"%d",tm->tm_hour);
+ out("hour");
+ sprintf(ascii,"%d",tm->tm_mday);
+ out("mday");
+ sprintf(ascii,"%d",tm->tm_mon);
+ out("mon");
+ sprintf(ascii,"%d",tm->tm_year);
+ out("year");
+ sprintf(ascii,"%d",tm->tm_wday);
+ out("wday");
+ sprintf(ascii,"%d",tm->tm_yday);
+ out("yday");
+ sprintf(ascii,"%d",tm->tm_isdst);
+ out("isdst");
+}
+/* end of deprecated code */
+
+/*ARGSUSED*/
+static int
+Exp_TimestampCmd(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ char *format = 0;
+ time_t seconds = -1;
+ int gmt = FALSE; /* local time by default */
+ struct tm *tm;
+ Tcl_DString dstring;
+
+ argc--; argv++;
+
+ while (*argv) {
+ if (streq(*argv,"-format")) {
+ argc--; argv++;
+ if (!*argv) goto usage_error;
+ format = *argv;
+ argc--; argv++;
+ } else if (streq(*argv,"-seconds")) {
+ argc--; argv++;
+ if (!*argv) goto usage_error;
+ seconds = atoi(*argv);
+ argc--; argv++;
+ } else if (streq(*argv,"-gmt")) {
+ gmt = TRUE;
+ argc--; argv++;
+ } else break;
+ }
+
+ if (argc) goto usage_error;
+
+ if (seconds == -1) {
+ time(&seconds);
+ }
+
+ Tcl_DStringInit(&dstring);
+
+ if (format) {
+ if (gmt) {
+ tm = gmtime(&seconds);
+ } else {
+ tm = localtime(&seconds);
+ }
+/* exp_strftime(interp->result,TCL_RESULT_SIZE,format,tm);*/
+ exp_strftime(format,tm,&dstring);
+ Tcl_DStringResult(interp,&dstring);
+ } else {
+ sprintf(interp->result,"%ld",seconds);
+ }
+
+ return TCL_OK;
+ usage_error:
+ exp_error(interp,"args: [-seconds #] [-format format]");
+ return TCL_ERROR;
+
+}
+
+/* lowmemcpy - like memcpy but it lowercases result */
+void
+exp_lowmemcpy(dest,src,n)
+char *dest;
+char *src;
+int n;
+{
+ for (;n>0;n--) {
+ *dest = ((isascii(*src) && isupper(*src))?tolower(*src):*src);
+ src++; dest++;
+ }
+}
+
+/*ARGSUSED*/
+int
+Exp_MatchMaxCmd(clientData,interp,argc,argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int size = -1;
+ int m = -1;
+ struct exp_f *f;
+ int Default = FALSE;
+
+ argc--; argv++;
+
+ for (;argc>0;argc--,argv++) {
+ if (streq(*argv,"-d")) {
+ Default = TRUE;
+ } else if (streq(*argv,"-i")) {
+ argc--;argv++;
+ if (argc < 1) {
+ exp_error(interp,"-i needs argument");
+ return(TCL_ERROR);
+ }
+ m = atoi(*argv);
+ } else break;
+ }
+
+ if (!Default) {
+ if (m == -1) {
+ if (!(f = exp_update_master(interp,&m,0,0)))
+ return(TCL_ERROR);
+ } else {
+ if (!(f = exp_fd2f(interp,m,0,0,"match_max")))
+ return(TCL_ERROR);
+ }
+ } else if (m != -1) {
+ exp_error(interp,"cannot do -d and -i at the same time");
+ return(TCL_ERROR);
+ }
+
+ if (argc == 0) {
+ if (Default) {
+ size = exp_default_match_max;
+ } else {
+ size = f->umsize;
+ }
+ sprintf(interp->result,"%d",size);
+ return(TCL_OK);
+ }
+
+ if (argc > 1) {
+ exp_error(interp,"too many arguments");
+ return(TCL_OK);
+ }
+
+ /* all that's left is to set the size */
+ size = atoi(argv[0]);
+ if (size <= 0) {
+ exp_error(interp,"must be positive");
+ return(TCL_ERROR);
+ }
+
+ if (Default) exp_default_match_max = size;
+ else f->umsize = size;
+
+ return(TCL_OK);
+}
+
+/*ARGSUSED*/
+int
+Exp_RemoveNullsCmd(clientData,interp,argc,argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int value = -1;
+ int m = -1;
+ struct exp_f *f;
+ int Default = FALSE;
+
+ argc--; argv++;
+
+ for (;argc>0;argc--,argv++) {
+ if (streq(*argv,"-d")) {
+ Default = TRUE;
+ } else if (streq(*argv,"-i")) {
+ argc--;argv++;
+ if (argc < 1) {
+ exp_error(interp,"-i needs argument");
+ return(TCL_ERROR);
+ }
+ m = atoi(*argv);
+ } else break;
+ }
+
+ if (!Default) {
+ if (m == -1) {
+ if (!(f = exp_update_master(interp,&m,0,0)))
+ return(TCL_ERROR);
+ } else {
+ if (!(f = exp_fd2f(interp,m,0,0,"remove_nulls")))
+ return(TCL_ERROR);
+ }
+ } else if (m != -1) {
+ exp_error(interp,"cannot do -d and -i at the same time");
+ return(TCL_ERROR);
+ }
+
+ if (argc == 0) {
+ if (Default) {
+ value = exp_default_match_max;
+ } else {
+ value = f->rm_nulls;
+ }
+ sprintf(interp->result,"%d",value);
+ return(TCL_OK);
+ }
+
+ if (argc > 1) {
+ exp_error(interp,"too many arguments");
+ return(TCL_OK);
+ }
+
+ /* all that's left is to set the value */
+ value = atoi(argv[0]);
+ if (value != 0 && value != 1) {
+ exp_error(interp,"must be 0 or 1");
+ return(TCL_ERROR);
+ }
+
+ if (Default) exp_default_rm_nulls = value;
+ else f->rm_nulls = value;
+
+ return(TCL_OK);
+}
+
+/*ARGSUSED*/
+int
+Exp_ParityCmd(clientData,interp,argc,argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ int parity;
+ int m = -1;
+ struct exp_f *f;
+ int Default = FALSE;
+
+ argc--; argv++;
+
+ for (;argc>0;argc--,argv++) {
+ if (streq(*argv,"-d")) {
+ Default = TRUE;
+ } else if (streq(*argv,"-i")) {
+ argc--;argv++;
+ if (argc < 1) {
+ exp_error(interp,"-i needs argument");
+ return(TCL_ERROR);
+ }
+ m = atoi(*argv);
+ } else break;
+ }
+
+ if (!Default) {
+ if (m == -1) {
+ if (!(f = exp_update_master(interp,&m,0,0)))
+ return(TCL_ERROR);
+ } else {
+ if (!(f = exp_fd2f(interp,m,0,0,"parity")))
+ return(TCL_ERROR);
+ }
+ } else if (m != -1) {
+ exp_error(interp,"cannot do -d and -i at the same time");
+ return(TCL_ERROR);
+ }
+
+ if (argc == 0) {
+ if (Default) {
+ parity = exp_default_parity;
+ } else {
+ parity = f->parity;
+ }
+ sprintf(interp->result,"%d",parity);
+ return(TCL_OK);
+ }
+
+ if (argc > 1) {
+ exp_error(interp,"too many arguments");
+ return(TCL_OK);
+ }
+
+ /* all that's left is to set the parity */
+ parity = atoi(argv[0]);
+
+ if (Default) exp_default_parity = parity;
+ else f->parity = parity;
+
+ return(TCL_OK);
+}
+
+#if DEBUG_PERM_ECASES
+/* This big chunk of code is just for debugging the permanent */
+/* expect cases */
+void
+exp_fd_print(fdl)
+struct exp_fd_list *fdl;
+{
+ if (!fdl) return;
+ printf("%d ",fdl->fd);
+ exp_fd_print(fdl->next);
+}
+
+void
+exp_i_print(exp_i)
+struct exp_i *exp_i;
+{
+ if (!exp_i) return;
+ printf("exp_i %x",exp_i);
+ printf((exp_i->direct == EXP_DIRECT)?" direct":" indirect");
+ printf((exp_i->duration == EXP_PERMANENT)?" perm":" tmp");
+ printf(" ecount = %d\n",exp_i->ecount);
+ printf("variable %s, value %s\n",
+ ((exp_i->variable)?exp_i->variable:"--"),
+ ((exp_i->value)?exp_i->value:"--"));
+ printf("fds: ");
+ exp_fd_print(exp_i->fd_list); printf("\n");
+ exp_i_print(exp_i->next);
+}
+
+void
+exp_ecase_print(ecase)
+struct ecase *ecase;
+{
+ printf("pat <%s>\n",ecase->pat);
+ printf("exp_i = %x\n",ecase->i_list);
+}
+
+void
+exp_ecases_print(ecd)
+struct exp_cases_descriptor *ecd;
+{
+ int i;
+
+ printf("%d cases\n",ecd->count);
+ for (i=0;i<ecd->count;i++) exp_ecase_print(ecd->cases[i]);
+}
+
+void
+exp_cmd_print(ecmd)
+struct exp_cmd_descriptor *ecmd;
+{
+ printf("expect cmd type: %17s",exp_cmdtype_printable(ecmd->cmdtype));
+ printf((ecmd->duration==EXP_PERMANENT)?" perm ": "tmp ");
+ /* printdict */
+ exp_ecases_print(&ecmd->ecd);
+ exp_i_print(ecmd->i_list);
+}
+
+void
+exp_cmds_print()
+{
+ exp_cmd_print(&exp_cmds[EXP_CMD_BEFORE]);
+ exp_cmd_print(&exp_cmds[EXP_CMD_AFTER]);
+ exp_cmd_print(&exp_cmds[EXP_CMD_BG]);
+}
+
+/*ARGSUSED*/
+int
+cmdX(clientData, interp, argc, argv)
+ClientData clientData;
+Tcl_Interp *interp;
+int argc;
+char **argv;
+{
+ exp_cmds_print();
+ return TCL_OK;
+}
+#endif /*DEBUG_PERM_ECASES*/
+
+/* need address for passing into cmdExpect */
+static int spawn_id_bad = EXP_SPAWN_ID_BAD;
+static int spawn_id_user = EXP_SPAWN_ID_USER;
+
+static struct exp_cmd_data
+cmd_data[] = {
+{"expect", exp_proc(Exp_ExpectCmd), (ClientData)&spawn_id_bad, 0},
+{"expect_after",exp_proc(Exp_ExpectGlobalCmd),(ClientData)&exp_cmds[EXP_CMD_AFTER],0},
+{"expect_before",exp_proc(Exp_ExpectGlobalCmd),(ClientData)&exp_cmds[EXP_CMD_BEFORE],0},
+{"expect_user", exp_proc(Exp_ExpectCmd), (ClientData)&spawn_id_user, 0},
+{"expect_tty", exp_proc(Exp_ExpectCmd), (ClientData)&exp_dev_tty, 0},
+{"expect_background",exp_proc(Exp_ExpectGlobalCmd),(ClientData)&exp_cmds[EXP_CMD_BG],0},
+{"match_max", exp_proc(Exp_MatchMaxCmd), 0, 0},
+{"remove_nulls",exp_proc(Exp_RemoveNullsCmd), 0, 0},
+{"parity", exp_proc(Exp_ParityCmd), 0, 0},
+{"timestamp", exp_proc(Exp_TimestampCmd), 0, 0},
+{0}};
+
+void
+exp_init_expect_cmds(interp)
+Tcl_Interp *interp;
+{
+ exp_create_commands(interp,cmd_data);
+
+ Tcl_SetVar(interp,EXPECT_TIMEOUT,INIT_EXPECT_TIMEOUT_LIT,0);
+ Tcl_SetVar(interp,EXP_SPAWN_ID_ANY_VARNAME,EXP_SPAWN_ID_ANY_LIT,0);
+
+ exp_cmd_init(&exp_cmds[EXP_CMD_BEFORE],EXP_CMD_BEFORE,EXP_PERMANENT);
+ exp_cmd_init(&exp_cmds[EXP_CMD_AFTER ],EXP_CMD_AFTER, EXP_PERMANENT);
+ exp_cmd_init(&exp_cmds[EXP_CMD_BG ],EXP_CMD_BG, EXP_PERMANENT);
+ exp_cmd_init(&exp_cmds[EXP_CMD_FG ],EXP_CMD_FG, EXP_TEMPORARY);
+
+ /* preallocate to one element, so future realloc's work */
+ exp_cmds[EXP_CMD_BEFORE].ecd.cases = 0;
+ exp_cmds[EXP_CMD_AFTER ].ecd.cases = 0;
+ exp_cmds[EXP_CMD_BG ].ecd.cases = 0;
+
+ pattern_style[PAT_EOF] = "eof";
+ pattern_style[PAT_TIMEOUT] = "timeout";
+ pattern_style[PAT_DEFAULT] = "default";
+ pattern_style[PAT_FULLBUFFER] = "full buffer";
+ pattern_style[PAT_GLOB] = "glob pattern";
+ pattern_style[PAT_RE] = "regular expression";
+ pattern_style[PAT_EXACT] = "exact string";
+ pattern_style[PAT_NULL] = "null";
+
+#if 0
+ Tcl_CreateCommand(interp,"x",
+ cmdX,(ClientData)0,exp_deleteProc);
+#endif
+}
+
+void
+exp_init_sig() {
+#if 0
+ signal(SIGALRM,sigalarm_handler);
+ signal(SIGINT,sigint_handler);
+#endif
+}
diff --git a/expect/expect.h b/expect/expect.h
new file mode 100644
index 00000000000..c1053a18b10
--- /dev/null
+++ b/expect/expect.h
@@ -0,0 +1,78 @@
+/* expect.h - include file for using the expect library, libexpect.a
+from C or C++ (i.e., without Tcl)
+
+Written by: Don Libes, libes@cme.nist.gov, NIST, 12/3/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+#ifndef _EXPECT_H
+#define _EXPECT_H
+
+#include "expect_comm.h"
+
+enum exp_type {
+ exp_end = 0, /* placeholder - no more cases */
+ exp_glob, /* glob-style */
+ exp_exact, /* exact string */
+ exp_regexp, /* regexp-style, uncompiled */
+ exp_compiled, /* regexp-style, compiled */
+ exp_null, /* matches binary 0 */
+ exp_bogus /* aid in reporting compatibility problems */
+};
+
+struct exp_case { /* case for expect command */
+ char *pattern;
+ regexp *re;
+ enum exp_type type;
+ int value; /* value to be returned upon match */
+};
+
+EXTERN char *exp_buffer; /* buffer of matchable chars */
+EXTERN char *exp_buffer_end; /* one beyond end of matchable chars */
+EXTERN char *exp_match; /* start of matched string */
+EXTERN char *exp_match_end; /* one beyond end of matched string */
+EXTERN int exp_match_max; /* bytes */
+EXTERN int exp_timeout; /* seconds */
+EXTERN int exp_full_buffer; /* if true, return on full buffer */
+EXTERN int exp_remove_nulls; /* if true, remove nulls */
+
+EXTERN int exp_pty_timeout; /* see Cray hooks in source */
+EXTERN int exp_pid; /* process-id of spawned process */
+EXTERN int exp_autoallocpty; /* if TRUE, we do allocation */
+EXTERN int exp_pty[2]; /* master is [0], slave is [1] */
+EXTERN char *exp_pty_slave_name; /* name of pty slave device if we */
+ /* do allocation */
+EXTERN char *exp_stty_init; /* initial stty args */
+EXTERN int exp_ttycopy; /* copy tty parms from /dev/tty */
+EXTERN int exp_ttyinit; /* set tty parms to sane state */
+EXTERN int exp_console; /* redirect console */
+
+EXTERN jmp_buf exp_readenv; /* for interruptable read() */
+EXTERN int exp_reading; /* whether we can longjmp or not */
+#define EXP_ABORT 1 /* abort read */
+#define EXP_RESTART 2 /* restart read */
+
+EXTERN int exp_logfile_all;
+EXTERN FILE *exp_debugfile;
+EXTERN FILE *exp_logfile;
+
+EXTERN int exp_disconnect _ANSI_ARGS_((void));
+EXTERN FILE *exp_popen _ANSI_ARGS_((char *command));
+EXTERN void (*exp_child_exec_prelude) _ANSI_ARGS_((void));
+
+#ifndef EXP_DEFINE_FNS
+EXTERN int exp_spawnl _ANSI_ARGS_(TCL_VARARGS(char *,file));
+EXTERN int exp_expectl _ANSI_ARGS_(TCL_VARARGS(int,fd));
+EXTERN int exp_fexpectl _ANSI_ARGS_(TCL_VARARGS(FILE *,fp));
+#endif
+
+EXTERN int exp_spawnv _ANSI_ARGS_((char *file, char *argv[]));
+EXTERN int exp_expectv _ANSI_ARGS_((int fd, struct exp_case *cases));
+EXTERN int exp_fexpectv _ANSI_ARGS_((FILE *fp, struct exp_case *cases));
+
+EXTERN int exp_spawnfd _ANSI_ARGS_((int fd));
+
+#endif /* _EXPECT_H */
diff --git a/expect/expect.man b/expect/expect.man
new file mode 100644
index 00000000000..a57b17564f1
--- /dev/null
+++ b/expect/expect.man
@@ -0,0 +1,2591 @@
+.TH EXPECT 1 "29 December 1994"
+.SH NAME
+expect \- programmed dialogue with interactive programs, Version 5
+.SH SYNOPSIS
+.B expect
+[
+.B \-dDinN
+]
+[
+.B \-c
+.I cmds
+]
+[
+.BR \- [ f | b ]
+]
+.I cmdfile
+]
+[
+.I args
+]
+.SH INTRODUCTION
+.B Expect
+is a program that "talks" to other interactive programs according to a
+script. Following the script,
+.B Expect
+knows what can be expected from
+a program and what the correct response should be. An interpreted
+language provides branching and high-level control structures to
+direct the dialogue. In addition, the user can take control
+and interact directly when desired, afterward returning control to the
+script.
+.PP
+.B Expectk
+is a mixture of
+.B Expect
+and
+.BR Tk .
+It behaves just like
+.B Expect
+and
+.BR Tk 's
+.BR wish .
+.B Expect
+can also be used directly in C or C++ (that is, without Tcl).
+See libexpect(3).
+.PP
+The name "Expect" comes from the idea of
+.I send/expect
+sequences popularized
+by uucp, kermit and other modem control programs.
+However unlike uucp,
+.B Expect
+is generalized so that it can be run as a user-level command
+with any program and task in mind.
+.B Expect
+can actually talk to several programs at the same time.
+.PP
+For example, here are some things
+.B Expect
+can do:
+.RS
+.TP 4
+\(bu
+Cause your computer to dial you back,
+so that you can login without paying for the call.
+.TP
+\(bu
+Start a game (e.g., rogue) and if the optimal configuration doesn't appear,
+restart it (again and again) until it does,
+then hand over control to you.
+.TP
+\(bu
+Run fsck, and in response to its questions, answer "yes", "no" or give control back to you,
+based on predetermined criteria.
+.TP
+\(bu
+Connect to another network or BBS (e.g., MCI Mail, CompuServe) and
+automatically retrieve your mail so that it appears as if
+it was originally sent to your local system.
+.TP
+\(bu
+Carry environment variables, current directory,
+or any kind of information across rlogin, telnet, tip, su, chgrp, etc.
+.RE
+.PP
+There are a variety of reasons why the shell cannot perform these tasks.
+(Try, you'll see.)
+All are possible with
+.BR Expect .
+.PP
+In general,
+.B Expect
+is useful for running any program which requires
+interaction between the program and the user.
+All that is necessary is that the interaction can be characterized
+programmatically.
+.B Expect
+can also give the user back control
+(without halting the program being controlled) if desired.
+Similarly, the user can return control to the script at any time.
+.SH USAGE
+.B Expect
+reads
+.I cmdfile
+for a list of commands to execute.
+.B Expect
+may also be invoked implicitly on systems which support the #! notation
+by marking the script executable, and making the first line in your script:
+
+ #!/usr/local/bin/expect \-f
+
+Of course, the path must accurately describe where
+.B Expect
+lives. /usr/local/bin is just an example.
+
+The
+.B \-c
+flag prefaces a command to be executed before any in the script.
+The command should be quoted to prevent being broken up by the shell.
+This option may be used multiple times.
+Multiple commands may be
+executed with a single
+.B \-c
+by separating them with semicolons.
+Commands are executed in the order they appear.
+(When using Expectk, this option is specified as
+.BR \-command .)
+.PP
+The
+.B \-d
+flag enables some diagnostic output, which
+primarily reports internal activity of commands such as
+.B expect
+and
+.BR interact .
+This flag has the same effect as "exp_internal 1" at the beginning of an Expect
+script, plus the version of
+.B Expect
+is printed.
+(The
+.B strace
+command is useful for tracing statements, and the
+.B trace
+command is useful for tracing variable assignments.)
+(When using Expectk, this option is specified as
+.BR \-diag .)
+.PP
+The
+.B \-D
+flag enables an interactive debugger. An integer value should follow.
+The debugger will take control before the next Tcl procedure
+if the value is non-zero
+or if a ^C is pressed (or a breakpoint is hit, or other appropriate debugger
+command appears in the script). See the README file or SEE ALSO (below)
+for more information on the debugger.
+(When using Expectk, this option is specified as
+.BR \-Debug .)
+.PP
+The
+.B \-f
+flag prefaces a file from which to read commands from.
+The flag itself is optional as it is only useful when using
+the #! notation (see above),
+so that other arguments may be supplied on the command line.
+(When using Expectk, this option is specified as
+.BR \-file .)
+.PP
+By default, the command file is read into memory and executed in its entirety.
+It is occasionally desirable to read files one line at a time. For example,
+stdin is read this way. In order to force arbitrary files to be handled this
+way, use the
+.B \-b
+flag.
+(When using Expectk, this option is specified as
+.BR \-buffer .)
+.PP
+If the string "\-" is supplied as a filename, standard input is read instead.
+(Use "./\-" to read from a file actually named "\-".)
+.PP
+The
+.B \-i
+flag causes
+.B Expect
+to interactively prompt for commands instead of reading
+them from a file.
+Prompting is terminated via the
+.B exit
+command or upon EOF.
+See
+.B interpreter
+(below) for more information.
+.B \-i
+is assumed if neither a command file nor
+.B \-c
+is used.
+(When using Expectk, this option is specified as
+.BR \-interactive .)
+.PP
+.B \-\-
+may be used to delimit the end of the options. This is useful if
+you want to pass an option-like argument to your script without it being
+interpreted by
+.BR Expect .
+This can usefully be placed in the #! line to prevent any flag-like
+interpretation by Expect. For example, the following will leave the
+original arguments (including the script name) in the variable
+.IR argv .
+
+ #!/usr/local/bin/expect \-\-
+
+Note that the usual getopt(3) and execve(2) conventions must be observed
+when adding arguments to the #! line.
+.PP
+The file $exp_library/expect.rc is sourced automatically if present, unless
+the
+.B \-N
+flag is used.
+(When using Expectk, this option is specified as
+.BR \-NORC .)
+Immediately after this,
+the file ~/.expect.rc is sourced automatically, unless the
+.B \-n
+flag is used. If the environment variable DOTDIR is defined,
+it is treated as a directory and .expect.rc is read from there.
+(When using Expectk, this option is specified as
+.BR \-norc .)
+This sourcing occurs only after executing any
+.B \-c
+flags.
+.PP
+.B \-v
+causes Expect to print its version number and exit. (The corresponding flag
+in Expectk, which uses long flag names, is \-version.)
+.PP
+Optional
+.I args
+are constructed into a list and stored in the variable named
+.IR argv .
+.I argc
+is initialized to the length of argv.
+.PP
+.I argv0
+is defined to be the name of the script (or binary if no script is used).
+For example,
+the following prints out the name of the script and the first three arguments:
+.nf
+
+ send_user "$argv0 [lrange $argv 0 2]\\n"
+
+.fi
+.SH COMMANDS
+.B Expect
+uses
+.I Tcl
+(Tool Command Language).
+Tcl provides control flow (e.g., if, for, break),
+expression evaluation and several other features such as recursion,
+procedure definition, etc.
+Commands used here but not defined (e.g.,
+.BR set ,
+.BR if ,
+.BR exec )
+are Tcl commands (see tcl(3)).
+.B Expect
+supports additional commands, described below.
+Unless otherwise specified, commands return the empty string.
+.PP
+Commands are listed alphabetically so that they can be quickly located.
+However, new users may find it easier to start by reading the descriptions
+of
+.BR spawn ,
+.BR send ,
+.BR expect ,
+and
+.BR interact ,
+in that order.
+
+Note that the best introduction to the language (both Expect and Tcl)
+is provided in the book "Exploring Expect" (see SEE ALSO below).
+Examples are included in this man page but they are very limited since
+this man page is meant primarily as reference material.
+
+Note that in the text of this man page, "Expect" with an uppercase "E"
+refers to the
+.B Expect
+program while "expect" with a lower-case "e" refers to the
+.B expect
+command within the
+.B Expect
+program.)
+.I
+.TP 6
+.BI close " [-slave] [\-onexec 0|1] [\-i spawn_id]"
+closes the connection to the current process.
+Most interactive programs will detect EOF on their stdin and exit;
+thus
+.B close
+usually suffices to kill the process as well.
+The
+.B \-i
+flag declares the process to close corresponding to the named spawn_id.
+
+Both
+.B expect
+and
+.B interact
+will detect when the current process exits and implicitly do a
+.BR close .
+But if you kill the process by, say, "exec kill $pid",
+you will need to explicitly call
+.BR close .
+
+The
+.BR \-onexec
+flag determines whether the spawn id will be closed in any new spawned
+processes or if the process is overlayed. To leave a spawn id open,
+use the value 0. A non-zero integer value will force the spawn closed
+(the default) in any new processes.
+
+The
+.B \-slave
+flag closes the slave associated with the spawn id. (See "spawn -pty".)
+When the connection is closed, the slave is automatically closed as
+well if still open.
+
+No matter whether the connection is closed implicitly or explicitly,
+you should call
+.B wait
+to clear up the corresponding kernel process slot.
+.B close
+does not call
+.B wait
+since there is no guarantee that closing a process connection will cause
+it to exit.
+See
+.B wait
+below for more info.
+.TP
+.BI debug " [[-now] 0|1]"
+controls a Tcl debugger allowing you to step through statements, set
+breakpoints, etc.
+
+With no arguments, a 1 is returned if the debugger is not running, otherwise
+a 0 is returned.
+
+With a 1 argument, the debugger is started. With a 0 argument, the
+debugger is stopped. If a 1 argument is preceded by the
+.B \-now
+flag, the debugger is started immediately (i.e., in the middle of the
+.B debug
+command itself). Otherwise, the debugger is started with the next
+Tcl statement.
+
+The
+.B debug
+command does not change any traps. Compare this to starting Expect with the
+.B -D
+flag (see above).
+
+See the README file or SEE ALSO (below)
+for more information on the debugger.
+.TP
+.B disconnect
+disconnects a forked process from the terminal. It continues running in the
+background. The process is given its own process group (if possible).
+Standard I/O is redirected to /dev/null.
+.IP
+The following fragment uses
+.B disconnect
+to continue running the script in the background.
+.nf
+
+ if [fork]!=0 exit
+ disconnect
+ . . .
+
+.fi
+The following script reads a password, and then runs a program
+every hour that demands a password each time it is run. The script supplies
+the password so that you only have to type it once.
+(See the
+.B stty
+command which demonstrates how to turn off password echoing.)
+.nf
+
+ send_user "password?\\ "
+ expect_user -re "(.*)\\n"
+ for {} 1 {} {
+ if [fork]!=0 {sleep 3600;continue}
+ disconnect
+ spawn priv_prog
+ expect Password:
+ send "$expect_out(1,string)\\r"
+ . . .
+ exit
+ }
+
+.fi
+An advantage to using
+.B disconnect
+over the shell asynchronous process feature (&) is that
+.B Expect
+can
+save the terminal parameters prior to disconnection, and then later
+apply them to new ptys. With &,
+.B Expect
+does not have a chance
+to read the terminal's parameters since the terminal is already
+disconnected by the time
+.B Expect
+receives control.
+.TP
+.BI exit " [\-opts] [status]"
+causes
+.B Expect
+to exit or otherwise prepare to do so.
+
+The
+.B \-onexit
+flag causes the next argument to be used as an exit handler.
+Without an argument, the current exit handler is returned.
+
+The
+.B \-noexit
+flag causes
+.B Expect
+to prepare to exit but stop short of actually returning control to the
+operating system. The user-defined exit handler is run as well as Expect's
+own internal handlers.
+No further Expect commands should be executed.
+This is useful if you are running Expect with other Tcl extensions.
+The current interpreter (and main window if in the Tk environment) remain
+so that other Tcl extensions can clean up. If Expect's
+.B exit
+is called again (however this might occur), the handlers are not rerun.
+
+Upon exiting,
+all connections to spawned processes are closed. Closure will be detected
+as an EOF by spawned processes.
+.B exit
+takes no other actions beyond what the normal _exit(2) procedure does.
+Thus, spawned processes that do not check for EOF may continue to run.
+(A variety of conditions are important to determining, for example, what
+signals a spawned process will be sent, but these are system-dependent,
+typically documented under exit(3).)
+Spawned processes that continue to run will be inherited by init.
+
+.I status
+(or 0 if not specified) is returned as the exit status of
+.BR Expect .
+.B exit
+is implicitly executed if the end of the script is reached.
+.TP
+.B exp_continue
+The command
+.B exp_continue
+allows
+.B expect
+itself to continue
+executing rather than returning as it normally would.
+(See
+.B expect
+for more information.)
+.TP
+.BI exp_internal " [\-f file] value"
+causes further commands to send diagnostic information internal to
+.B Expect
+to stderr if
+.I value
+is non-zero. This output is disabled if
+.I value
+is 0. The diagnostic information includes every character received,
+and every attempt made to match the current output against the patterns.
+.IP
+If the optional
+.I file
+is supplied, all normal and debugging output is written to that file
+(regardless of the value of
+.IR value ).
+Any previous diagnostic output file is closed.
+
+The
+.B \-info
+flag causes exp_internal to return a description of the
+most recent non-info arguments given.
+.TP
+.BI exp_open " [args] [\-i spawn_id]"
+returns a Tcl file identifier that corresponds to the original spawn id.
+The file identifier can then be used as if it were opened by Tcl's
+.B open
+command. (The spawn id should no longer be used. A
+.B wait
+should not be executed.
+
+The
+.B \-leaveopen
+flag leaves the spawn id open for access through
+Expect commands. A
+.B wait
+must be executed on the spawn id.
+.TP
+.BI exp_pid " [\-i spawn_id]"
+returns the process id corresponding to the currently spawned process.
+If the
+.B \-i
+flag is used, the pid returned corresponds to that of the given spawn id.
+.TP
+.B exp_send
+is an alias for
+.BR send .
+.TP
+.B exp_send_error
+is an alias for
+.BR send_error .
+.TP
+.B exp_send_log
+is an alias for
+.BR send_log .
+.TP
+.B exp_send_tty
+is an alias for
+.BR send_tty .
+.TP
+.B exp_send_user
+is an alias for
+.BR send_user .
+.TP
+.BI exp_version " [[\-exit] version]"
+is useful for assuring that the script is compatible with the current
+version of Expect.
+.IP
+With no arguments, the current version of
+.B Expect
+is returned. This version
+may then be encoded in your script. If you actually know that you are not
+using features of recent versions, you can specify an earlier version.
+.IP
+Versions consist of three numbers separated by dots. First
+is the major number. Scripts written for versions of
+.B Expect
+with a
+different major number will almost certainly not work.
+.B exp_version
+returns an error if the major numbers do not match.
+.IP
+Second is the minor number. Scripts written for a version with a
+greater minor number than the current version
+may depend upon some new feature and might not run.
+.B exp_version
+returns an error if the major numbers match, but the script minor number
+is greater than that of the running
+.BR Expect .
+.IP
+Third is a number that plays no part in the version comparison.
+However, it is incremented when the
+.B Expect
+software
+distribution is changed in any way, such as by additional documentation
+or optimization. It is reset to 0 upon each new minor version.
+.IP
+With the
+.B \-exit
+flag,
+.B Expect
+prints an error and exits if the version is out of date.
+.TP
+.BI expect " [[\-opts] pat1 body1] ... [\-opts] patn [bodyn]"
+waits until one of the patterns matches the output of a spawned process,
+a specified time period has passed, or an end-of-file is seen.
+If the final body is empty, it may be omitted.
+.IP
+Patterns from the most recent
+.B expect_before
+command are implicitly used before any other patterns.
+Patterns from the most recent
+.B expect_after
+command are implicitly used after any other patterns.
+.IP
+If the arguments to the entire
+.B expect
+statement require more than one line,
+all the arguments may be "braced" into one so as to avoid terminating each
+line with a backslash. In this one case, the usual Tcl substitutions will
+occur despite the braces.
+.IP
+If a pattern is the keyword
+.BR eof ,
+the corresponding body is executed upon end-of-file.
+If a pattern is the keyword
+.BR timeout ,
+the corresponding body is executed upon timeout. If no timeout keyword
+is used, an implicit null action is executed upon timeout.
+The default timeout period is 10 seconds but may be set, for example to 30,
+by the command "set timeout 30". An infinite timeout may be designated
+by the value \-1.
+If a pattern is the keyword
+.BR default ,
+the corresponding body is executed upon either timeout or end-of-file.
+.IP
+If a pattern matches, then the corresponding body is executed.
+.B expect
+returns the result of the body (or the empty string if no pattern matched).
+In the event that multiple patterns match, the one appearing first is
+used to select a body.
+.IP
+Each time new output arrives, it is compared to each pattern in the order
+they are listed. Thus, you may test for absence of a match by making
+the last pattern something guaranteed to appear, such as a prompt.
+In situations where there is no prompt, you must use
+.B timeout
+(just like you would if you were interacting manually).
+.IP
+Patterns are specified in three ways. By default,
+patterns are specified as with Tcl's
+.B string match
+command. (Such patterns are also similar to C-shell regular expressions
+usually referred to as "glob" patterns). The
+.B \-gl
+flag may may
+be used to protect patterns that might otherwise match
+.B expect
+flags from doing so.
+Any pattern beginning with a "-" should be protected this way. (All strings
+starting with "-" are reserved for future options.)
+
+.IP
+For example, the following fragment looks for a successful login.
+(Note that
+.B abort
+is presumed to be a procedure defined elsewhere in the script.)
+.nf
+
+.ta \w' expect 'u +\w'invalid password 'u
+ expect {
+ busy {puts busy\\n ; exp_continue}
+ failed abort
+ "invalid password" abort
+ timeout abort
+ connected
+ }
+
+.fi
+Quotes are necessary on the fourth pattern since it contains a space, which
+would otherwise separate the pattern from the action.
+Patterns with the same action (such as the 3rd and 4th) require listing the
+actions again. This can be avoid by using regexp-style patterns (see below).
+More information on forming glob-style patterns can be found in the Tcl manual.
+.IP
+Regexp-style patterns follow the syntax defined by Tcl's
+.B regexp
+(short for "regular expression") command.
+regexp patterns are introduced with the flag
+.BR \-re .
+The previous example can be rewritten using a regexp as:
+.nf
+
+.ta \w' expect 'u +\w'connected 'u
+ expect {
+ busy {puts busy\\n ; exp_continue}
+ \-re "failed|invalid password" abort
+ timeout abort
+ connected
+ }
+
+.fi
+Both types of patterns are "unanchored". This means that patterns
+do not have to match the entire string, but can begin and end the
+match anywhere in the string (as long as everything else matches).
+Use ^ to match the beginning of a string, and $ to match the end.
+Note that if you do not wait for the end of a string, your responses
+can easily end up in the middle of the string as they are echoed from
+the spawned process. While still producing correct results, the output
+can look unnatural. Thus, use of $ is encouraged if you can exactly
+describe the characters at the end of a string.
+
+Note that in many editors, the ^ and $ match the beginning and end of
+lines respectively. However, because expect is not line oriented,
+these characters match the beginning and end of the data (as opposed
+to lines) currently in the expect matching buffer. (Also, see the
+note below on "system indigestion.")
+
+The
+.B \-ex
+flag causes the pattern to be matched as an "exact" string. No
+interpretation of *, ^, etc is made (although the usual Tcl
+conventions must still be observed).
+Exact patterns are always unanchored.
+
+.IP
+The
+.B \-nocase
+flag causes uppercase characters of the output to compare as if they were
+lowercase characters. The pattern is not affected.
+.IP
+While reading output,
+more than 2000 bytes can force earlier bytes to be "forgotten".
+This may be changed with the function
+.BR match_max .
+(Note that excessively large values can slow down the pattern matcher.)
+If
+.I patlist
+is
+.BR full_buffer ,
+the corresponding body is executed if
+.I match_max
+bytes have been received and no other patterns have matched.
+Whether or not the
+.B full_buffer
+keyword is used, the forgotten characters are written to
+expect_out(buffer).
+
+If
+.I patlist
+is the keyword
+.BR null ,
+and nulls are allowed (via the
+.B remove_nulls
+command), the corresponding body is executed if a single ASCII
+0 is matched.
+It is not possible to
+match 0 bytes via glob or regexp patterns.
+
+Upon matching a pattern (or eof or full_buffer),
+any matching and previously unmatched output is saved in the variable
+.IR expect_out(buffer) .
+Up to 9 regexp substring matches are saved in the variables
+.I expect_out(1,string)
+through
+.IR expect_out(9,string) .
+If the
+.B -indices
+flag is used before a pattern,
+the starting and ending indices (in a form suitable for
+.BR lrange )
+of the
+10 strings are stored in the variables
+.I expect_out(X,start)
+and
+.I expect_out(X,end)
+where X is a digit, corresponds to the substring position in the buffer.
+0 refers to strings which matched the entire pattern
+and is generated for glob patterns as well as regexp patterns.
+For example, if a process has produced output of "abcdefgh\\n", the result of:
+.nf
+
+ expect "cd"
+
+.fi
+is as if the following statements had executed:
+.nf
+
+ set expect_out(0,string) cd
+ set expect_out(buffer) abcd
+
+.fi
+and "efgh\\n" is left in the output buffer.
+If a process produced the output "abbbcabkkkka\\n", the result of:
+.nf
+
+ expect \-indices \-re "b(b*).*(k+)"
+
+.fi
+is as if the following statements had executed:
+.nf
+
+ set expect_out(0,start) 1
+ set expect_out(0,end) 10
+ set expect_out(0,string) bbbcabkkkk
+ set expect_out(1,start) 2
+ set expect_out(1,end) 3
+ set expect_out(1,string) bb
+ set expect_out(2,start) 10
+ set expect_out(2,end) 10
+ set expect_out(2,string) k
+ set expect_out(buffer) abbbcabkkkk
+
+.fi
+and "a\\n" is left in the output buffer. The pattern "*" (and -re ".*") will
+flush the output buffer without reading any more output from the
+process.
+.IP
+Normally, the matched output is discarded from Expect's internal buffers.
+This may be prevented by prefixing a pattern with the
+.B \-notransfer
+flag. This flag is especially useful in experimenting (and can be
+abbreviated to "-n" for convenience while experimenting).
+
+The spawn id associated with the matching output (or eof or
+full_buffer) is stored in
+.IR expect_out(spawn_id) .
+
+The
+.B \-timeout
+flag causes the current expect command to use the following value
+as a timeout instead of using the value of the timeout variable.
+
+By default,
+patterns are matched against output from the current process, however the
+.B \-i
+flag declares the output from the named spawn_id list be matched against
+any following patterns (up to the next
+.BR \-i ).
+The spawn_id list should either be a whitespace separated list of spawn_ids
+or a variable referring to such a list of spawn_ids.
+
+For example, the following example waits for
+"connected" from the current process, or "busy", "failed" or "invalid
+password" from the spawn_id named by $proc2.
+.nf
+
+ expect {
+ \-i $proc2 busy {puts busy\\n ; exp_continue}
+ \-re "failed|invalid password" abort
+ timeout abort
+ connected
+ }
+
+.fi
+The value of the global variable
+.I any_spawn_id
+may be used to match patterns to any spawn_ids that are named
+with all other
+.B \-i
+flags in the current
+.B expect
+command.
+The spawn_id from a
+.B \-i
+flag with no associated pattern (i.e., followed immediately
+by another
+.BR \-i )
+is made available to any other patterns
+in the same
+.B expect
+command associated with
+.I any_spawn_id.
+
+The
+.B \-i
+flag may also name a global variable in which case the variable is read
+for a list of spawn ids. The variable is reread whenever it changes.
+This provides a way of changing the I/O source while the command is in
+execution. Spawn ids provided this way are called "indirect" spawn ids.
+
+Actions such as
+.B break
+and
+.B continue
+cause control structures (i.e.,
+.BR for ,
+.BR proc )
+to behave in the usual way.
+The command
+.B exp_continue
+allows
+.B expect
+itself to continue
+executing rather than returning as it normally would.
+.IP
+This is useful for avoiding explicit loops or repeated expect statements.
+The following example is part of a fragment to automate rlogin. The
+.B exp_continue
+avoids having to write a second
+.B expect
+statement (to look for the prompt again) if the rlogin prompts for a password.
+.nf
+
+ expect {
+ Password: {
+ stty -echo
+ send_user "password (for $user) on $host: "
+ expect_user -re "(.*)\\n"
+ send_user "\\n"
+ send "$expect_out(1,string)\\r"
+ stty echo
+ exp_continue
+ } incorrect {
+ send_user "invalid password or account\\n"
+ exit
+ } timeout {
+ send_user "connection to $host timed out\\n"
+ exit
+ } eof {
+ send_user \\
+ "connection to host failed: $expect_out(buffer)"
+ exit
+ } -re $prompt
+ }
+
+.fi
+For example, the following fragment might help a user guide
+an interaction that is already totally automated. In this case, the terminal
+is put into raw mode. If the user presses "+", a variable is incremented.
+If "p" is pressed, several returns are sent to the process,
+perhaps to poke it in some way, and "i" lets the user interact with the
+process, effectively stealing away control from the script.
+In each case, the
+.B exp_continue
+allows the current
+.B expect
+to continue pattern matching after executing the
+current action.
+.nf
+
+ stty raw \-echo
+ expect_after {
+ \-i $user_spawn_id
+ "p" {send "\\r\\r\\r"; exp_continue}
+ "+" {incr foo; exp_continue}
+ "i" {interact; exp_continue}
+ "quit" exit
+ }
+
+.fi
+.IP
+By default,
+.B exp_continue
+resets the timeout timer. The timer is not restarted, if
+.B exp_continue
+is called with the
+.B \-continue_timer
+flag.
+.TP
+.BI expect_after " [expect_args]"
+works identically to the
+.B expect_before
+except that if patterns from both
+.B expect
+and
+.B expect_after
+can match, the
+.B expect
+pattern is used. See the
+.B expect_before
+command for more information.
+.TP
+.BI expect_background " [expect_args]"
+takes the same arguments as
+.BR expect ,
+however it returns immediately.
+Patterns are tested whenever new input arrives.
+The pattern
+.B timeout
+and
+.B default
+are meaningless to
+.BR expect_background
+and are silently discarded.
+Otherwise, the
+.B expect_background
+command uses
+.B expect_before
+and
+.B expect_after
+patterns just like
+.B expect
+does.
+
+When
+.B expect_background
+actions are being evaluated, background processing for the same
+spawn id is blocked. Background processing is unblocked when
+the action completes. While background processing is blocked,
+it is possible to do a (foreground)
+.B expect
+on the same spawn id.
+
+It is not possible to execute an
+.B expect
+while an
+.B expect_background
+is unblocked.
+.B expect_background
+for a particular spawn id is deleted by
+declaring a new expect_background with the same spawn id. Declaring
+.B expect_background
+with no pattern removes the given spawn id
+from the ability to match patterns in the background.
+.TP
+.BI expect_before " [expect_args]"
+takes the same arguments as
+.BR expect ,
+however it returns immediately.
+Pattern-action pairs from the most recent
+.B expect_before
+with the same spawn id are implicitly added to any following
+.B expect
+commands. If a pattern matches, it is treated as if it had been
+specified in the
+.B expect
+command itself, and the associated body is executed in the context
+of the
+.B expect
+command.
+If patterns from both
+.B expect_before
+and
+.B expect
+can match, the
+.B expect_before
+pattern is used.
+
+If no pattern is specified, the spawn id is not checked for any patterns.
+
+Unless overridden by a
+.B \-i
+flag,
+.B expect_before
+patterns match against the spawn id defined at the time that the
+.B expect_before
+command was executed (not when its pattern is matched).
+
+The \-info flag causes
+.B expect_before
+to return the current specifications of what patterns it will match.
+By default, it reports on the current spawn id. An optional spawn id specification may be given for information on that spawn id. For example
+.nf
+
+ expect_before -info -i $proc
+
+.fi
+At most one spawn id specification may be given. The flag \-indirect
+suppresses direct spawn ids that come only from indirect specifications.
+
+Instead of a spawn id specification, the flag "-all" will cause
+"-info" to report on all spawn ids.
+
+The output of the \-info flag can be reused as the argument to expect_before.
+.TP
+.BI expect_tty " [expect_args]"
+is like
+.B expect
+but it reads characters from /dev/tty (i.e. keystrokes from the user).
+By default, reading is performed in cooked mode.
+Thus, lines must end with a return in order for
+.B expect
+to see them.
+This may be changed via
+.B stty
+(see the
+.B stty
+command below).
+.TP
+.BI expect_user " [expect_args]"
+is like
+.B expect
+but it reads characters from stdin (i.e. keystrokes from the user).
+By default, reading is performed in cooked mode.
+Thus, lines must end with a return in order for
+.B expect
+to see them.
+This may be changed via
+.B stty
+(see the
+.B stty
+command below).
+.TP
+.B fork
+creates a new process. The new process is an exact copy of the current
+.B Expect
+process. On success,
+.B fork
+returns 0 to the new (child) process and returns the process ID of the child
+process to the parent process.
+On failure (invariably due to lack of resources, e.g., swap space, memory),
+.B fork
+returns \-1 to the parent process, and no child process is created.
+.IP
+Forked processes exit via the
+.B exit
+command, just like the original process.
+Forked processes are allowed to write to the log files. If you do not
+disable debugging or logging in most of the processes, the result can be
+confusing.
+.IP
+Some pty implementations may be confused by multiple readers and writers,
+even momentarily. Thus, it is safest to
+.B fork
+before spawning processes.
+.TP
+.BI interact " [string1 body1] ... [stringn [bodyn]]"
+gives control of the current process to the user, so that
+keystrokes are sent to the current process,
+and the stdout and stderr of the current process are returned.
+.IP
+String-body pairs may be specified as arguments, in which case the
+body is executed when the corresponding string is entered. (By default, the
+string is not sent to the current process.) The
+.B interpreter
+command is assumed, if the final body is missing.
+.IP
+If the arguments to the entire
+.B interact
+statement require more than one line,
+all the arguments may be "braced" into one so as to avoid terminating each
+line with a backslash. In this one case, the usual Tcl substitutions will
+occur despite the braces.
+.IP
+For example, the following command runs interact with the following
+string-body pairs defined: When ^Z is pressed,
+.B Expect
+is suspended.
+(The
+.B \-reset
+flag restores the terminal modes.)
+When ^A is pressed, the user sees "you typed a control-A" and the
+process is sent a ^A. When $ is pressed, the user sees the date.
+When ^C is pressed,
+.B Expect
+exits. If "foo" is entered, the user sees "bar".
+When ~~ is pressed, the
+.B Expect
+interpreter runs interactively.
+.nf
+
+.ta \w' interact 'u +\w'$CTRLZ 'u +\w'{'u
+ set CTRLZ \\032
+ interact {
+ -reset $CTRLZ {exec kill \-STOP [pid]}
+ \\001 {send_user "you typed a control\-A\\n";
+ send "\\001"
+ }
+ $ {send_user "The date is [exec date]."}
+ \\003 exit
+ foo {send_user "bar"}
+ ~~
+ }
+
+.fi
+.IP
+In string-body pairs, strings are matched in the order they are listed
+as arguments. Strings that partially match are not sent to the
+current process in anticipation of the remainder coming. If
+characters are then entered such that there can no longer possibly be
+a match, only the part of the string will be sent to the process that cannot
+possibly begin another match. Thus, strings that are substrings of
+partial matches can match later, if the original strings that was attempting
+to be match ultimately fails.
+.IP
+By default, string matching is exact with no wild cards. (In contrast,
+the
+.B expect
+command uses glob-style patterns by default.) The
+.B \-ex
+flag may be used to protect patterns that might otherwise match
+.B interact
+flags from doing so.
+Any pattern beginning with a "-" should be protected this way. (All strings
+starting with "-" are reserved for future options.)
+
+The
+.B \-re
+flag forces the string to be interpreted as a regexp-style pattern. In this
+case, matching substrings are stored in the variable
+.I interact_out
+similarly to the way
+.B expect
+stores its output in the variable
+.BR expect_out .
+The
+.B \-indices
+flag is similarly supported.
+
+The pattern
+.B eof
+introduces an action that is
+executed upon end-of-file. A separate
+.B eof
+pattern may also follow the
+.B \-output
+flag in which case it is matched if an eof is detected while writing output.
+The default
+.B eof
+action is "return", so that
+.B interact
+simply returns upon any EOF.
+
+The pattern
+.B timeout
+introduces a timeout (in seconds) and action that is executed
+after no characters have been read for a given time.
+The
+.B timeout
+pattern applies to the most recently specified process.
+There is no default timeout.
+The special variable "timeout" (used by the
+.B expect
+command) has no affect on this timeout.
+
+For example, the following statement could be used to autologout users who have
+not typed anything for an hour but who still get frequent system
+messages:
+.nf
+
+ interact -input $user_spawn_id timeout 3600 return -output \\
+ $spawn_id
+
+.fi
+
+If the pattern is the keyword
+.BR null ,
+and nulls are allowed (via the
+.B remove_nulls
+command), the corresponding body is executed if a single ASCII
+0 is matched.
+It is not possible to
+match 0 bytes via glob or regexp patterns.
+
+Prefacing a pattern with the flag
+.B \-iwrite
+causes the variable
+.I interact_out(spawn_id)
+to be set to the spawn_id which matched the pattern
+(or eof).
+
+Actions such as
+.B break
+and
+.B continue
+cause control structures (i.e.,
+.BR for ,
+.BR proc )
+to behave in the usual way.
+However
+.B return
+causes interact to return to its caller, while
+.B inter_return
+causes
+.B interact
+to cause a return in its caller. For example, if "proc foo" called
+.B interact
+which then executed the action
+.BR inter_return ,
+.B proc foo
+would return. (This means that if
+.B interact
+calls
+.B interpreter
+interactively typing
+.B return
+will cause the interact to continue, while
+.B inter_return
+will cause the interact to return to its caller.)
+.IP
+During
+.BR interact ,
+raw mode is used so that all characters may be passed to the current process.
+If the current process does not catch job control signals,
+it will stop if sent a stop signal (by default ^Z).
+To restart it, send a continue signal (such as by "kill \-CONT <pid>").
+If you really want to send a SIGSTOP to such a process (by ^Z),
+consider spawning csh first and then running your program.
+On the other hand, if you want to send a SIGSTOP to
+.B Expect
+itself, first press the escape character, and then press ^Z.
+.IP
+String-body pairs can be used as a shorthand for avoiding having
+to enter the interpreter and execute commands interactively. The previous
+terminal mode is used while the body of a string-body pair is being executed.
+.IP
+For speed, actions execute in raw mode by default. The
+.B \-reset
+flag resets the terminal to the mode it had before
+.B interact
+was executed (invariably, cooked mode).
+Note that characters entered when the mode is being switched may be lost
+(an unfortunate feature of the terminal driver on some systems).
+The only reason to use
+.B \-reset
+is if your action
+depends on running in cooked mode.
+.IP
+The
+.B \-echo
+flag sends characters that match the following pattern back to the process
+that generated them as each character is read. This may be useful
+when the user needs to see feedback from partially typed patterns.
+.IP
+If a pattern is being echoed but eventually fails to match,
+the characters are sent to the spawned process. If the spawned
+process then echoes them, the user will see the characters twice.
+.B \-echo
+is probably only appropriate in situations where the user is
+unlikely to not complete the pattern. For example, the following
+excerpt is from rftp, the recursive-ftp script, where the user is
+prompted to enter ~g, ~p, or ~l, to get, put, or list the current
+directory recursively. These are so far away from the normal ftp
+commands, that the user is unlikely to type ~ followed by anything
+else, except mistakenly, in which case, they'll probably just ignore
+the result anyway.
+.nf
+
+ interact {
+ -echo ~g {getcurdirectory 1}
+ -echo ~l {getcurdirectory 0}
+ -echo ~p {putcurdirectory}
+ }
+
+.fi
+The
+.B \-nobuffer
+flag sends characters that match the following pattern on to
+the output process as characters are read.
+
+This is useful when you wish to let a program echo back the pattern.
+For example, the following might be used to monitor where a person is
+dialing (a Hayes-style modem). Each time "atd" is seen the script
+logs the rest of the line.
+.nf
+
+ proc lognumber {} {
+ interact -nobuffer -re "(.*)\\r" return
+ puts $log "[exec date]: dialed $interact_out(1,string)"
+ }
+
+ interact -nobuffer "atd" lognumber
+
+.fi
+.IP
+During
+.BR interact ,
+previous use of
+.B log_user
+is ignored. In particular,
+.B interact
+will force its output to be logged (sent to the standard output)
+since it is presumed the user doesn't wish to interact blindly.
+.IP
+The
+.B \-o
+flag causes any following key-body pairs to be applied to the output of
+the current process.
+This can be useful, for example, when dealing with hosts that
+send unwanted characters during a telnet session.
+.IP
+By default,
+.B interact
+expects the user to be writing stdin and reading stdout of the
+.B Expect
+process
+itself.
+The
+.B \-u
+flag (for "user") makes
+.B interact
+look for the user as the process named by its argument
+(which must be a spawned id).
+.IP
+This allows two unrelated processes to be joined
+together without using an explicit loop. To aid in debugging, Expect
+diagnostics always go to stderr (or stdout for certain logging and
+debugging information). For the same reason, the
+.B interpreter
+command will read interactively from stdin.
+.IP
+For example, the following fragment creates a login process.
+Then it dials the user (not shown), and finally connects the two together.
+Of course, any process may be substituted for login.
+A shell, for example, would allow the user to work without supplying an
+account and password.
+.nf
+
+ spawn login
+ set login $spawn_id
+ spawn tip modem
+ # dial back out to user
+ # connect user to login
+ interact \-u $login
+
+.fi
+To send output to multiple processes, list each spawn id list prefaced by a
+.B \-output
+flag. Input for a group of output spawn ids may be determined
+by a spawn id list prefaced by a
+.B \-input
+flag. (Both
+.B \-input
+and
+.B \-output
+may take lists in the same form as the
+.B \-i
+flag in the
+.B expect
+command, except that any_spawn_id is not meaningful in
+.BR interact .)
+All following flags and
+strings (or patterns) apply to this input until another -input flag appears.
+If no
+.B \-input
+appears,
+.B \-output
+implies "\-input $user_spawn_id \-output".
+(Similarly, with patterns that do not have
+.BR \-input .)
+If one
+.B \-input
+is specified, it overrides $user_spawn_id. If a second
+.B \-input
+is specified,
+it overrides $spawn_id. Additional
+.B \-input
+flags may be specified.
+
+The two implied input processes default to having their outputs specified as
+$spawn_id and $user_spawn_id (in reverse).
+If a
+.B \-input
+flag appears
+with no
+.B \-output
+flag, characters from that process are discarded.
+
+The
+.B \-i
+flag introduces a replacement for the current spawn_id when no
+other
+.B \-input
+or
+.B \-output
+flags are used. A \-i flag implies a \-o flag.
+
+It is possible to change the processes that are being interacted with
+by using indirect spawn ids. (Indirect spawn ids are described in the
+section on the expect command.) Indirect spawn ids may be specified
+with the -i, -u, -input, or -output flags.
+.TP
+.B interpreter
+causes the user to be interactively prompted for
+.B Expect
+and Tcl commands.
+The result of each command is printed.
+.IP
+Actions such as
+.B break
+and
+.B continue
+cause control structures (i.e.,
+.BR for ,
+.BR proc )
+to behave in the usual way.
+However
+.B return
+causes interpreter to return to its caller, while
+.B inter_return
+causes
+.B interpreter
+to cause a return in its caller. For example, if "proc foo" called
+.B interpreter
+which then executed the action
+.BR inter_return ,
+.B proc foo
+would return.
+Any other command causes
+.B interpreter
+to continue prompting for new commands.
+.IP
+By default, the prompt contains two integers.
+The first integer describes the depth of
+the evaluation stack (i.e., how many times Tcl_Eval has been called). The
+second integer is the Tcl history identifier. The prompt can be set by
+defining a procedure called "prompt1" whose return value becomes the next
+prompt. If a statement has open quotes, parens, braces, or brackets, a
+secondary prompt (by default "+> ") is issued upon newline. The secondary
+prompt may be set by defining a procedure called "prompt2".
+.IP
+During
+.BR interpreter ,
+cooked mode is used, even if the its caller was using raw mode.
+.TP
+.BI log_file " [args] [[\-a] file]"
+If a filename is provided,
+.B log_file
+will record a transcript of the session (beginning at that point) in the file.
+.B log_file
+will stop recording if no argument is given. Any previous log file is closed.
+
+Instead of a filename, a Tcl file identifier may be provided by using the
+.B \-open
+or
+.B \-leaveopen
+flags. This is similar to the
+.B spawn
+command. (See
+.B spawn
+for more info.)
+
+The
+.B \-a
+flag forces output to be logged that was suppressed by the
+.B log_user
+command.
+
+By default, the
+.B log_file
+command
+.I appends
+to old files rather than truncating them,
+for the convenience of being able to turn logging off and on multiple
+times in one session.
+To truncate files, use the
+.B \-noappend
+flag.
+
+The
+.B -info
+flag causes log_file to return a description of the
+most recent non-info arguments given.
+.TP
+.BI log_user " -info|0|1"
+By default, the send/expect dialogue is logged to stdout
+(and a logfile if open).
+The logging to stdout is disabled by the command "log_user 0"
+and reenabled by "log_user 1". Logging to the logfile is unchanged.
+
+The
+.B -info
+flag causes log_user to return a description of the
+most recent non-info arguments given.
+.TP
+.BI match_max " [\-d] [\-i spawn_id] [size]"
+defines the size of the buffer (in bytes) used internally by
+.BR expect .
+With no
+.I size
+argument, the current size is returned.
+.IP
+With the
+.B \-d
+flag, the default size is set. (The initial default is 2000.)
+With the
+.B \-i
+flag, the size is set for the named spawn id, otherwise it is set for
+the current process.
+.TP
+.BI overlay " [\-# spawn_id] [\-# spawn_id] [...] program [args]"
+executes
+.IR "program args"
+in place of the current
+.B Expect
+program, which terminates.
+A bare hyphen argument forces a hyphen in front of the command name as if
+it was a login shell.
+All spawn_ids are closed except for those named as arguments. These
+are mapped onto the named file identifiers.
+.IP
+Spawn_ids are mapped to file identifiers for the new program to inherit.
+For example, the following line runs chess and allows it to be
+controlled by the current process \- say, a chess master.
+.nf
+
+ overlay \-0 $spawn_id \-1 $spawn_id \-2 $spawn_id chess
+
+.fi
+This is more efficient than
+"interact \-u", however, it sacrifices the ability to do programmed
+interaction since the
+.B Expect
+process is no longer in control.
+.IP
+Note that no controlling terminal is provided. Thus, if you
+disconnect or remap standard input, programs that do
+job control (shells, login, etc) will not function properly.
+.TP
+.BI parity " [\-d] [\-i spawn_id] [value]"
+defines whether parity should be retained or stripped from the output of
+spawned processes. If
+.I value
+is zero, parity is stripped, otherwise it is not stripped.
+With no
+.I value
+argument, the current value is returned.
+.IP
+With the
+.B \-d
+flag, the default parity value is set. (The initial default is 1, i.e.,
+parity is not stripped.)
+With the
+.B \-i
+flag, the parity value is set for the named spawn id, otherwise it is set for
+the current process.
+.TP
+.BI remove_nulls " [\-d] [\-i spawn_id] [value]"
+defines whether nulls are retained or removed from the output of
+spawned processes before pattern matching
+or storing in the variable
+.I expect_out
+or
+.IR interact_out .
+If
+.I value
+is 1, nulls are removed. If
+.I value
+is 0, nulls are not removed.
+With no
+.I value
+argument, the current value is returned.
+.IP
+With the
+.B \-d
+flag, the default value is set. (The initial default is 1, i.e.,
+nulls are removed.)
+With the
+.B \-i
+flag, the value is set for the named spawn id, otherwise it is set for
+the current process.
+
+Whether or not nulls are removed,
+.B Expect
+will record null bytes to the log and stdout.
+.TP
+.BI send " [\-flags] string"
+Sends
+.IR string
+to the current process.
+For example, the command
+.nf
+
+ send "hello world\\r"
+
+.fi
+sends the characters, h e l l o <blank> w o r l d <return> to the
+current process.
+(Tcl includes a printf-like command (called
+.BR format )
+which can build arbitrarily complex strings.)
+.IP
+Characters are sent immediately although programs with line-buffered input
+will not read the characters until a return character is sent. A return
+character is denoted "\\r".
+
+The
+.B \-\-
+flag forces the next argument to be interpreted as a string rather than a flag.
+Any string can be preceded by "\-\-" whether or not it actually looks
+like a flag. This provides a reliable mechanism to specify variable strings
+without being tripped up by those that accidentally look like flags.
+(All strings starting with "-" are reserved for future options.)
+
+The
+.B \-i
+flag declares that the string be sent to the named spawn_id.
+If the spawn_id is
+.IR user_spawn_id ,
+and the terminal is in raw mode, newlines in the string are translated
+to return-newline
+sequences so that they appear as it the terminal was in cooked mode.
+The
+.B \-raw
+flag disables this translation.
+
+The
+.BR \-null
+flag sends null characters (0 bytes). By default, one null is sent.
+An integer may follow the
+.BR \-null
+to indicate how many nulls to send.
+
+The
+.B \-break
+flag generates a break condition. This only makes sense if the spawn
+id refers to a tty device opened via "spawn -open". If you have
+spawned a process such as tip, you should use tip's convention for
+generating a break.
+
+The
+.B \-s
+flag forces output to be sent "slowly", thus avoid the common situation
+where a computer outtypes an input buffer that was designed for a
+human who would never outtype the same buffer. This output is
+controlled by the value of the variable "send_slow" which takes a two
+element list. The first element is an integer that describes the
+number of bytes to send atomically. The second element is a real
+number that describes the number of seconds by which the atomic sends
+must be separated. For example, "set send_slow {10 .001}" would force
+"send \-s" to send strings with 1 millisecond in between each 10
+characters sent.
+
+The
+.B \-h
+flag forces output to be sent (somewhat) like a human actually typing.
+Human-like delays appear between the characters. (The algorithm is
+based upon a Weibull distribution, with modifications to suit this
+particular application.) This output is controlled by the value of
+the variable "send_human" which takes a five element list. The first
+two elements are average interarrival time of characters in seconds.
+The first is used by default. The second is used at word endings, to
+simulate the subtle pauses that occasionally occur at such
+transitions. The third parameter is a measure of variability where .1
+is quite variable, 1 is reasonably variable, and 10 is quite
+invariable. The extremes are 0 to infinity. The last two parameters
+are, respectively, a minimum and maximum interarrival time.
+The minimum and maximum are used last and "clip" the final time.
+The ultimate average can be quite different from the given average
+if the minimum and maximum clip enough values.
+
+As an
+example, the following command emulates a fast and
+consistent typist:
+.nf
+
+ set send_human {.1 .3 1 .05 2}
+ send \-h "I'm hungry. Let's do lunch."
+
+.fi
+while the following might be more suitable after a hangover:
+.nf
+
+ set send_human {.4 .4 .2 .5 100}
+ send \-h "Goodd party lash night!"
+
+.fi
+Note that errors are not simulated, although you can set up error
+correction situations yourself by embedding mistakes and corrections
+in a send argument.
+
+The flags for sending null characters, for sending breaks, for forcing slow
+output and for human-style output are mutually exclusive. Only the one
+specified last will be used. Furthermore, no
+.I string
+argument can be specified with the flags for sending null characters or breaks.
+
+It is a good idea to precede the first
+.B send
+to a process by an
+.BR expect .
+.B expect
+will wait for the process to start, while
+.B send
+cannot.
+In particular, if the first
+.B send
+completes before the process starts running,
+you run the risk of having your data ignored.
+In situations where interactive programs offer no initial prompt,
+you can precede
+.B send
+by a delay as in:
+.nf
+
+ # To avoid giving hackers hints on how to break in,
+ # this system does not prompt for an external password.
+ # Wait for 5 seconds for exec to complete
+ spawn telnet very.secure.gov
+ sleep 5
+ send password\\r
+
+.fi
+.B exp_send
+is an alias for
+.BI send .
+If you are using Expectk or some other variant of Expect in the Tk environment,
+.B send
+is defined by Tk for an entirely different purpose.
+.B exp_send
+is provided for compatibility between environments.
+Similar aliases are provided for other Expect's other send commands.
+.TP
+.BI send_error " [\-flags] string"
+is like
+.BR send ,
+except that the output is sent to stderr rather than the current
+process.
+.TP
+.BI send_log " [\--] string"
+is like
+.BR send ,
+except that the string is only sent to the log file (see
+.BR log_file .)
+The arguments are ignored if no log file is open.
+.TP
+.BI send_tty " [\-flags] string"
+is like
+.BR send ,
+except that the output is sent to /dev/tty rather than the current
+process.
+.TP
+.BI send_user " [\-flags] string"
+is like
+.BR send ,
+except that the output is sent to stdout rather than the current
+process.
+.TP
+.BI sleep " seconds"
+causes the script to sleep for the given number of seconds.
+Seconds may be a decimal number. Interrupts (and Tk events if you
+are using Expectk) are processed while Expect sleeps.
+.TP
+.BI spawn " [args] program [args]"
+creates a new process running
+.IR "program args" .
+Its stdin, stdout and stderr are connected to Expect,
+so that they may be read and written by other
+.B Expect
+commands.
+The connection is broken by
+.B close
+or if the process itself closes any of the file identifiers.
+.IP
+When a process is started by
+.BR spawn ,
+the variable
+.I spawn_id
+is set to a descriptor referring to that process.
+The process described by
+.I spawn_id
+is considered the
+.IR "current process" .
+.I spawn_id
+may be read or written, in effect providing job control.
+.IP
+.I user_spawn_id
+is a global variable containing a descriptor which refers to the user.
+For example, when
+.I spawn_id
+is set to this value,
+.B expect
+behaves like
+.BR expect_user .
+
+.I
+.I error_spawn_id
+is a global variable containing a descriptor which refers to the standard
+error.
+For example, when
+.I spawn_id
+is set to this value,
+.B send
+behaves like
+.BR send_error .
+.IP
+.I tty_spawn_id
+is a global variable containing a descriptor which refers to /dev/tty.
+If /dev/tty does not exist (such as in a cron, at, or batch script), then
+.I tty_spawn_id
+is not defined. This may be tested as:
+.nf
+
+ if [info vars tty_spawn_id] {
+ # /dev/tty exists
+ } else {
+ # /dev/tty doesn't exist
+ # probably in cron, batch, or at script
+ }
+
+.fi
+.IP
+.B spawn
+returns the UNIX process id. If no process is spawned, 0 is returned.
+The variable
+.I spawn_out(slave,name)
+is set to the name of the pty slave device.
+.IP
+By default,
+.B spawn
+echoes the command name and arguments. The
+.B \-noecho
+flag stops
+.B spawn
+from doing this.
+.IP
+The
+.B \-console
+flag causes console output to be redirected to the spawned process.
+This is not supported on all systems.
+
+Internally,
+.B spawn
+uses a pty, initialized the same way as the user's tty. This is further
+initialized so that all settings are "sane" (according to stty(1)).
+If the variable
+.I stty_init
+is defined, it is interpreted in the style of stty arguments
+as further configuration.
+For example, "set stty_init raw" will cause further spawned processes's
+terminals to start in raw mode.
+.B \-nottycopy
+skips the initialization based on the user's tty.
+.B \-nottyinit
+skips the "sane" initialization.
+.IP
+Normally,
+.B spawn
+takes little time to execute. If you notice spawn taking a
+significant amount of time, it is probably encountering ptys that are
+wedged. A number of tests are run on ptys to avoid entanglements with
+errant processes. (These take 10 seconds per wedged pty.) Running
+Expect with the
+.B \-d
+option will show if
+.B Expect
+is encountering many ptys in odd states. If you cannot kill
+the processes to which these ptys are attached, your only recourse may
+be to reboot.
+
+If
+.I program
+cannot be spawned successfully because exec(2) fails (e.g. when
+.I program
+doesn't exist), an error message will be returned by the next
+.B interact
+or
+.B expect
+command as if
+.I program
+had run and produced the error message as output.
+This behavior is a natural consequence of the implementation of
+.BR spawn .
+Internally, spawn forks, after which the spawned process has no
+way to communicate with the original
+.B Expect
+process except by communication
+via the spawn_id.
+
+The
+.B \-open
+flag causes the next argument to be interpreted as a Tcl file identifier
+(i.e., returned by
+.BR open .)
+The spawn id can then be used as if it were a spawned process. (The file
+identifier should no longer be used.)
+This lets you treat raw devices, files, and
+pipelines as spawned processes without using a pty. 0 is returned to
+indicate there is no associated process. When the connection to
+the spawned process is closed, so is the Tcl file identifier.
+The
+.B \-leaveopen
+flag is similar to
+.B \-open
+except that
+.B \-leaveopen
+causes the file identifier to be left open even after the spawn id is closed.
+
+The
+.B \-pty
+flag causes a pty to be opened but no process spawned. 0 is returned
+to indicate there is no associated process. Spawn_id is set as usual.
+
+The variable
+.I spawn_out(slave,fd)
+is set to a file identifier corresponding to the pty slave.
+It can be closed using "close -slave".
+
+The
+.B \-ignore
+flag names a signal to be ignored in the spawned process.
+Otherwise, signals get the default behavior.
+Signals are named as in the
+.B trap
+command, except that each signal requires a separate flag.
+.TP
+.BI strace " level"
+causes following statements to be printed before being executed.
+(Tcl's trace command traces variables.)
+.I level
+indicates how far down in the call stack to trace.
+For example,
+the following command runs
+.B Expect
+while tracing the first 4 levels of calls,
+but none below that.
+.nf
+
+ expect \-c "strace 4" script.exp
+
+.fi
+
+The
+.B -info
+flag causes strace to return a description of the
+most recent non-info arguments given.
+.TP
+.BI stty " args"
+changes terminal modes similarly to the external stty command.
+
+By default, the controlling terminal is accessed. Other terminals can
+be accessed by appending "< /dev/tty..." to the command. (Note that
+the arguments should not be grouped into a single argument.)
+
+Requests for status return it as the result of the command. If no status
+is requested and the controlling terminal is accessed, the previous
+status of the raw and echo attributes are returned in a form which can
+later be used by the command.
+
+For example, the arguments
+.B raw
+or
+.B \-cooked
+put the terminal into raw mode.
+The arguments
+.B \-raw
+or
+.B cooked
+put the terminal into cooked mode.
+The arguments
+.B echo
+and
+.B \-echo
+put the terminal into echo and noecho mode respectively.
+.IP
+The following example illustrates how to temporarily disable echoing.
+This could be used in otherwise-automatic
+scripts to avoid embedding passwords in them.
+(See more discussion on this under EXPECT HINTS below.)
+.nf
+
+ stty \-echo
+ send_user "Password: "
+ expect_user -re "(.*)\\n"
+ set password $expect_out(1,string)
+ stty echo
+
+.fi
+.TP
+.BI system " args"
+gives
+.I args
+to sh(1) as input,
+just as if it had been typed as a command from a terminal.
+.B Expect
+waits until the shell terminates.
+The return status from sh is handled the same way that
+.B exec
+handles its return status.
+.IP
+In contrast to
+.B exec
+which redirects stdin and stdout to the script,
+.B system
+performs no redirection
+(other than that indicated by the string itself).
+Thus, it is possible to use programs which must talk directly to /dev/tty.
+For the same reason, the results of
+.B system
+are not recorded in the log.
+.TP
+.BI timestamp " [args]"
+returns a timestamp.
+With no arguments, the number of
+seconds since the epoch is returned.
+
+The
+.B \-format
+flag introduces a string which is returned but with
+substitutions made according to the
+POSIX rules for strftime. For example %a is replaced by an abbreviated
+weekday name (i.e., Sat). Others are:
+.nf
+ %a abbreviated weekday name
+ %A full weekday name
+ %b abbreviated month name
+ %B full month name
+ %c date-time as in: Wed Oct 6 11:45:56 1993
+ %d day of the month (01-31)
+ %H hour (00-23)
+ %I hour (01-12)
+ %j day (001-366)
+ %m month (01-12)
+ %M minute (00-59)
+ %p am or pm
+ %S second (00-61)
+ %u day (1-7, Monday is first day of week)
+ %U week (00-53, first Sunday is first day of week one)
+ %V week (01-53, ISO 8601 style)
+ %w day (0-6)
+ %W week (00-53, first Monday is first day of week one)
+ %x date-time as in: Wed Oct 6 1993
+ %X time as in: 23:59:59
+ %y year (00-99)
+ %Y year as in: 1993
+ %Z timezone (or nothing if not determinable)
+ %% a bare percent sign
+
+.fi
+Other % specifications are undefined. Other characters will be passed
+through untouched. Only the C locale is supported.
+
+The
+.B \-seconds
+flag introduces a number of seconds since the epoch to be used as a source
+from which to format. Otherwise, the current time is used.
+
+The
+.B \-gmt
+flag forces timestamp output to use the GMT timezone. With no flag,
+the local timezone is used.
+.TP
+.BI trap " [[command] signals]"
+causes the given
+.I command
+to be executed upon future receipt of any of the given signals.
+The command is executed in the global scope.
+If
+.I command
+is absent, the signal action is returned.
+If
+.I command
+is the string SIG_IGN, the signals are ignored.
+If
+.I command
+is the string SIG_DFL, the signals are result to the system default.
+.I signals
+is either a single signal or a list of signals. Signals may be specified
+numerically or symbolically as per signal(3). The "SIG" prefix may be omitted.
+
+With no arguments (or the argument \-number),
+.B trap
+returns the signal number of the trap command currently being executed.
+
+The
+.B \-code
+flag uses the return code of the command in place of whatever code Tcl
+was about to return when the command originally started running.
+
+The
+.B \-interp
+flag causes the command to be evaluated using the interpreter
+active at the time the command started running
+rather than when the trap was declared.
+
+The
+.B \-name
+flag causes the
+.B trap
+command to return the signal name of the trap command currently being executed.
+
+The
+.B \-max
+flag causes the
+.B trap
+command to return the largest signal number that can be set.
+
+For example, the command "trap {send_user "Ouch!"} SIGINT" will print "Ouch!"
+each time the user presses ^C.
+
+By default, SIGINT (which can usually be generated by pressing ^C) and
+SIGTERM cause Expect to exit. This is due to the following trap, created
+by default when Expect starts.
+.nf
+
+ trap exit {SIGINT SIGTERM}
+
+.fi
+If you use the -D flag to start the debugger, SIGINT is redefined
+to start the interactive debugger. This is due to the following trap:
+.nf
+
+ trap {exp_debug 1} SIGINT
+
+.fi
+The debugger trap can be changed by setting the environment variable
+EXPECT_DEBUG_INIT to a new trap command.
+
+You can, of course, override both of these just by adding trap
+commands to your script. In particular, if you have your own "trap
+exit SIGINT", this will override the debugger trap. This is useful
+if you want to prevent users from getting to the debugger at all.
+
+If you want to define your own trap on SIGINT but still trap to the
+debugger when it is running, use:
+.nf
+
+ if ![exp_debug] {trap mystuff SIGINT}
+
+.fi
+Alternatively, you can trap to the debugger using some other signal.
+
+.B trap
+will not let you override the action for SIGALRM as this is used internally
+to
+.BR Expect .
+The disconnect command sets SIGALRM to SIG_IGN (ignore). You can reenable
+this as long as you disable it during subsequent spawn commands.
+
+See signal(3) for more info.
+.TP
+.BI wait " [args]"
+delays until a spawned process (or
+the current process if none is named) terminates.
+.IP
+.B wait
+normally returns a list of four integers.
+The first integer is the pid of the process that was waited upon.
+The second integer is the corresponding spawn id.
+The third integer is -1 if an operating system error occurred, or 0 otherwise.
+If the third integer was 0, the fourth integer is the status returned by
+the spawned process. If the third integer was -1, the fourth integer is
+the value of errno set by the operating system. The global variable
+errorCode is also set.
+
+Additional elements may appear at the end of the return value from
+.BR wait .
+An optional fifth element identifies a class of information.
+Currently, the only possible value for this element is CHILDKILLED in
+which case the next two values are the C-style signal name and a short
+textual description.
+.IP
+The
+.B \-i
+flag declares the process to wait corresponding to the named spawn_id
+(NOT the process id).
+Inside a SIGCHLD handler,
+it is possible to wait for any spawned process by using the spawn id -1.
+
+The
+.B \-nowait
+flag causes the wait to return immediately with the indication of a
+successful wait. When the process exits (later), it will automatically
+disappear without the need for an explicit wait.
+
+The
+.B wait
+command may also be used wait for a forked process using the arguments
+"-i -1". Unlike its use with spawned processes, this command can be
+executed at any time. There is no control over which process is
+reaped. However, the return value can be checked for the process id.
+
+.SH LIBRARIES
+Expect automatically knows about two built-in libraries for Expect scripts.
+These are defined by the directories named in the variables
+exp_library and exp_exec_library. Both are meant to contain utility
+files that can be used by other scripts.
+
+exp_library contains architecture-independent files. exp_exec_library
+contains architecture-dependent files. Depending on your system, both
+directories may be totally empty. The existence of the file
+$exp_exec_library/cat-buffers describes whether your /bin/cat buffers
+by default.
+.SH PRETTY-PRINTING
+A vgrind definition is available for pretty-printing
+.B Expect
+scripts.
+Assuming the vgrind definition supplied with the
+.B Expect
+distribution is
+correctly installed, you can use it as:
+.nf
+
+ vgrind \-lexpect file
+
+.fi
+.SH EXAMPLES
+It many not be apparent how to put everything together that the man page
+describes. I encourage you to read and try out the examples in
+the example directory of the
+.B Expect
+distribution.
+Some of them are real programs. Others are simply illustrative
+of certain techniques, and of course, a couple are just quick hacks.
+The INSTALL file has a quick overview of these programs.
+.PP
+The
+.B Expect
+papers (see SEE ALSO) are also useful. While some papers
+use syntax corresponding to earlier versions of Expect, the accompanying
+rationales are still valid and go into a lot more detail than this
+man page.
+.SH CAVEATS
+Extensions may collide with Expect's command names. For example,
+.B send
+is defined by Tk for an entirely different purpose.
+For this reason, most of the
+.B Expect
+commands are also available as "exp_XXXX".
+Commands and variables beginning with "exp", "inter", "spawn",
+and "timeout" do not have aliases.
+Use the extended command names if you need this compatibility between environments.
+
+.B Expect
+takes a rather liberal view of scoping.
+In particular, variables read by commands specific to the
+.B Expect
+program will be sought first from the local scope, and if not found, in the
+global scope. For example, this
+obviates the need to place "global timeout" in every
+procedure you write that uses
+.BR expect .
+On the other hand, variables written are always in the local scope (unless
+a "global" command has been issued). The most common problem this causes
+is when spawn is executed in a procedure. Outside the procedure,
+.I spawn_id
+no longer exists, so the spawned process is no longer accessible
+simply because of scoping. Add a "global spawn_id" to such a procedure.
+
+If you cannot enable the multispawning capability
+(i.e., your system supports neither select (BSD *.*), poll (SVR>2),
+nor something equivalent),
+.B Expect
+will only be able to control a single process at a time.
+In this case, do not attempt to set
+.IR spawn_id ,
+nor should you execute processes via exec while a spawned process
+is running. Furthermore, you will not be able to
+.B expect
+from multiple processes (including the user as one) at the same time.
+
+Terminal parameters can have a big effect on scripts. For example, if
+a script is written to look for echoing, it will misbehave if echoing
+is turned off. For this reason, Expect forces sane terminal
+parameters by default. Unfortunately, this can make things unpleasant
+for other programs. As an example, the emacs shell wants to change
+the "usual" mappings: newlines get mapped to newlines instead of
+carriage-return newlines, and echoing is disabled. This allows one to
+use emacs to edit the input line. Unfortunately, Expect cannot
+possibly guess this.
+
+You can request that Expect not override its default setting of
+terminal parameters, but you must then be very careful when writing
+scripts for such environments. In the case of emacs, avoid depending
+upon things like echoing and end-of-line mappings.
+
+The commands that accepted arguments braced into a single list (the
+.B expect
+variants and
+.BR interact )
+use a heuristic to decide if the list is actually one argument or many.
+The heuristic can fail only in the case when the list actually does
+represent a single argument which has multiple embedded \\n's with
+non-whitespace characters between them. This seems sufficiently improbable,
+however the argument "-brace" can be used to force a single argument
+to be handled as a single argument. This could conceivably be used
+with machine-generated Expect code.
+.SH BUGS
+It was really tempting to name the program "sex" (for either "Smart EXec"
+or "Send-EXpect"), but good sense (or perhaps just Puritanism) prevailed.
+
+On some systems, when a shell is spawned, it complains about not being
+able to access the tty but runs anyway. This means your system has a
+mechanism for gaining the controlling tty that
+.B Expect
+doesn't know about. Please find out what it is, and send this information
+back to me.
+
+Ultrix 4.1 (at least the latest versions around here) considers
+timeouts of above 1000000 to be equivalent to 0.
+
+Digital UNIX 4.0A (and probably other versions) refuses to allocate
+ptys if you define a SIGCHLD handler. See grantpt page for more info.
+
+IRIX 6.0 does not handle pty permissions correctly so that if Expect
+attempts to allocate a pty previously used by someone else, it fails.
+Upgrade to IRIX 6.1.
+
+Telnet (verified only under SunOS 4.1.2) hangs if TERM is not set.
+This is a problem under cron, at and in cgi scripts, which do not
+define TERM. Thus, you must set it explicitly - to what type is
+usually irrelevant. It just has to be set to something! The
+following probably suffices for most cases.
+.nf
+
+ set env(TERM) vt100
+
+.fi
+
+Tip (verified only under BSDI BSD/OS 3.1 i386) hangs if SHELL and HOME
+are not set. This is a problem under cron, at and in cgi scripts,
+which do not define these environment variables. Thus, you must set
+them explicitly - to what type is usually irrelevant. It just has to
+be set to something! The following probably suffices for most cases.
+.nf
+
+ set env(SHELL) /bin/sh
+ set env(HOME) /usr/local/bin
+
+.fi
+
+
+Some implementations of ptys are designed so that the kernel throws
+away any unread output after 10 to 15 seconds (actual number is
+implementation-dependent) after the process has closed the file
+descriptor. Thus
+.B Expect
+programs such as
+.nf
+
+ spawn date
+ sleep 20
+ expect
+
+.fi
+will fail. To avoid this, invoke non-interactive programs with
+.B exec
+rather than
+.BR spawn .
+While such situations are conceivable, in practice I have never
+encountered a situation in which the final output of a truly
+interactive program would be lost due to this behavior.
+
+On the other hand, Cray UNICOS ptys throw away any unread output
+immediately after the process has closed the file descriptor. I have
+reported this to Cray and they are working on a fix.
+
+Sometimes a delay is required between a prompt and a response, such as
+when a tty interface is changing UART settings or matching baud rates
+by looking for start/stop bits. Usually, all this is require is to
+sleep for a second or two. A more robust technique is to retry until
+the hardware is ready to receive input. The following example uses
+both strategies:
+.nf
+
+ send "speed 9600\\r";
+ sleep 1
+ expect {
+ timeout {send "\\r"; exp_continue}
+ $prompt
+ }
+
+.fi
+
+.SH EXPECT HINTS
+There are a couple of things about
+.B Expect
+that may be non-intuitive.
+This section attempts to address some of these things with a couple of
+suggestions.
+
+A common expect problem is how to recognize shell prompts. Since
+these are customized differently by differently people and different
+shells, portably automating rlogin can be difficult without knowing
+the prompt. A reasonable convention is to have users store a regular
+expression describing their prompt (in particular, the end of it) in
+the environment variable EXPECT_PROMPT. Code like the following
+can be used. If EXPECT_PROMPT doesn't exist, the code still has a good chance of functioning correctly.
+.nf
+
+ set prompt "(%|#|\\\\$) $" ;# default prompt
+ catch {set prompt $env(EXPECT_PROMPT)}
+
+ expect -re $prompt
+
+.fi
+I encourage you to write
+.B expect
+patterns that include the end of whatever
+you expect to see. This avoids the possibility of answering a question
+before seeing the entire thing. In addition, while you may well be
+able to answer questions before seeing them entirely, if you answer
+early, your answer may appear echoed back in the middle of the question.
+In other words, the resulting dialogue will be correct but look scrambled.
+
+Most prompts include a space character at the end.
+For example, the prompt from ftp is 'f', 't', 'p', '>' and <blank>.
+To match this prompt, you must account for each of these characters.
+It is a common mistake not to include the blank.
+Put the blank in explicitly.
+
+If you use a pattern of the form X*, the * will match all the output
+received from the end of X to the last thing received.
+This sounds intuitive but can be somewhat confusing because the phrase
+"last thing received" can vary depending upon the speed of the computer
+and the processing of I/O both by the kernel and the device driver.
+.PP
+In particular, humans tend to see program output arriving in huge chunks
+(atomically) when in reality most programs produce output one
+line at a time. Assuming this is the case, the * in the pattern of the
+previous paragraph may only match the end of the current line even though
+there seems to be more, because at the time of the match that was all
+the output that had been received.
+.PP
+.B expect
+has no way of knowing that further output is coming unless your
+pattern specifically accounts for it.
+.PP
+Even depending on line-oriented buffering is unwise. Not only do programs
+rarely make promises about the type of buffering they do, but system
+indigestion can break output lines up so that lines break at seemingly
+random places. Thus, if you can express the last few characters
+of a prompt when writing patterns, it is wise to do so.
+
+If you are waiting for a pattern in the last output of a program
+and the program emits something else instead, you will not be able to
+detect that with the
+.B timeout
+keyword. The reason is that
+.B expect
+will not timeout \- instead it will get an
+.B eof
+indication.
+Use that instead. Even better, use both. That way if that line
+is ever moved around, you won't have to edit the line itself.
+
+Newlines are usually converted to carriage return, linefeed sequences
+when output by the terminal driver. Thus, if you want a pattern that
+explicitly matches the two lines, from, say, printf("foo\\nbar"),
+you should use the pattern "foo\\r\\nbar".
+.PP
+A similar translation occurs when reading from the user, via
+.BR expect_user .
+In this case, when you press return, it will be
+translated to a newline. If
+.B Expect
+then passes that to a program
+which sets its terminal to raw mode (like telnet), there is going to
+be a problem, as the program expects a true return. (Some programs
+are actually forgiving in that they will automatically translate
+newlines to returns, but most don't.) Unfortunately, there is no way to find
+out that a program put its terminal into raw mode.
+.PP
+Rather than manually replacing newlines with returns, the solution is to
+use the command "stty raw", which will stop the translation.
+Note, however, that this means that you will no longer get the cooked
+line-editing features.
+.PP
+.B interact
+implicitly sets your terminal to raw mode so this problem will not arise then.
+
+It is often useful to store passwords (or other private information)
+in
+.B Expect
+scripts. This is not recommended since anything that is
+stored on a computer is susceptible to being accessed by anyone.
+Thus, interactively prompting for passwords from a script is a smarter
+idea than embedding them literally. Nonetheless, sometimes such embedding
+is the only possibility.
+.PP
+Unfortunately, the UNIX file system has no direct way of creating
+scripts which are executable but unreadable. Systems which support
+setgid shell scripts may indirectly simulate this as follows:
+.PP
+Create the
+.B Expect
+script (that contains the secret data) as usual.
+Make its permissions be 750 (\-rwxr\-x\-\-\-) and owned by a trusted group,
+i.e., a group which is allowed to read it. If necessary, create a new
+group for this purpose. Next, create a /bin/sh script with
+permissions 2751 (\-rwxr\-s\-\-x) owned by the same group as before.
+.PP
+The result is a script which may be executed (and read) by anyone.
+When invoked, it runs the
+.B Expect
+script.
+.SH SEE ALSO
+.BR Tcl (3),
+.BR libexpect (3)
+.br
+.I
+"Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs"
+\fRby Don Libes, pp. 602, ISBN 1-56592-090-2, O'Reilly and Associates, 1995.
+.br
+.I
+"expect: Curing Those Uncontrollable Fits of Interactivity" \fRby Don Libes,
+Proceedings of the Summer 1990 USENIX Conference,
+Anaheim, California, June 11-15, 1990.
+.br
+.I
+"Using
+.B expect
+to Automate System Administration Tasks" \fRby Don Libes,
+Proceedings of the 1990 USENIX Large Installation Systems Administration
+Conference, Colorado Springs, Colorado, October 17-19, 1990.
+.br
+.I
+"Tcl: An Embeddable Command Language" \fRby John Ousterhout,
+Proceedings of the Winter 1990 USENIX Conference,
+Washington, D.C., January 22-26, 1990.
+.br
+.I
+"expect: Scripts for Controlling Interactive Programs" \fRby Don Libes,
+Computing Systems, Vol. 4, No. 2, University of California Press Journals,
+November 1991.
+.br
+.I
+"Regression Testing and Conformance Testing Interactive Programs", \fRby Don
+Libes, Proceedings of the Summer 1992 USENIX Conference, pp. 135-144,
+San Antonio, TX, June 12-15, 1992.
+.br
+.I
+"Kibitz \- Connecting Multiple Interactive Programs Together", \fRby Don Libes,
+Software \- Practice & Experience, John Wiley & Sons, West Sussex, England,
+Vol. 23, No. 5, May, 1993.
+.br
+.I
+"A Debugger for Tcl Applications", \fRby Don Libes,
+Proceedings of the 1993 Tcl/Tk Workshop, Berkeley, CA, June 10-11, 1993.
+.SH AUTHOR
+Don Libes, National Institute of Standards and Technology
+.SH ACKNOWLEDGMENTS
+Thanks to John Ousterhout for Tcl, and Scott Paisley for inspiration.
+Thanks to Rob Savoye for Expect's autoconfiguration code.
+.PP
+The HISTORY file documents much of the evolution of
+.BR expect .
+It makes interesting reading and might give you further insight to this
+software. Thanks to the people mentioned in it who sent me bug fixes
+and gave other assistance.
+.PP
+Design and implementation of
+.B Expect
+was paid for in part by the U.S. government and is therefore in the public
+domain.
+However the author and NIST would like credit
+if this program and documentation or portions of them are used.
diff --git a/expect/expect_cf.h.in b/expect/expect_cf.h.in
new file mode 100644
index 00000000000..ebcfef38102
--- /dev/null
+++ b/expect/expect_cf.h.in
@@ -0,0 +1,114 @@
+/*
+ * Check for headers
+ */
+#ifndef __EXPECT_CF_H__
+#define __EXPECT_CF_H__
+
+#undef NO_STDLIB_H /* Tcl requires this name */
+#undef HAVE_STDARG_H
+#undef HAVE_VARARGS_H
+#undef HAVE_STROPTS_H
+#undef HAVE_SYSCONF_H
+#undef HAVE_SYS_FCNTL_H
+#undef HAVE_SYS_WAIT_H
+#undef HAVE_SYS_BSDTYPES_H /* nice ISC special */
+#undef HAVE_SYS_SELECT_H /* nice ISC special */
+#undef HAVE_SYS_TIME_H /* nice ISC special */
+#undef HAVE_SYS_PTEM_H /* SCO needs this for window size */
+#undef HAVE_STRREDIR_H /* Solaris needs this for console redir */
+#undef HAVE_STRPTY_H /* old-style Dynix ptys need this */
+#undef HAVE_UNISTD_H
+#undef HAVE_SYSMACROS_H
+#undef HAVE_INTTYPES_H
+#undef HAVE_TIOCGWINSZ_IN_TERMIOS_H
+#undef HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H
+
+#undef pid_t
+#undef RETSIGTYPE
+#undef TIME_WITH_SYS_TIME /* ok to include both time.h and sys/time.h */
+
+/*
+ * This section is for compile macros needed by
+ * everything else.
+ */
+
+/*
+ * Check for functions
+ */
+#undef HAVE_MEMCPY
+#undef HAVE_SYSCONF
+#undef SIMPLE_EVENT
+#undef HAVE_STRFTIME
+#undef HAVE_MEMMOVE
+#undef HAVE_TIMEZONE /* timezone() a la Pyramid */
+#undef HAVE_STRCHR
+
+#ifndef HAVE_STRCHR
+#define strchr(s,c) index(s,c)
+#endif /* HAVE_STRCHR */
+
+/*
+ * timezone
+ */
+#undef HAVE_SV_TIMEZONE
+
+/*
+ * wait status type
+ */
+#undef NO_UNION_WAIT
+
+#undef WNOHANG_REQUIRES_POSIX_SOURCE
+
+/*
+ * Signal stuff. Setup the return type
+ * and if signals need to be re-armed.
+ */
+/*#ifndef RETSIGTYPE*/
+/*#define RETSIGTYPE void*/
+/*#endif*/
+#undef REARM_SIG
+
+/*
+ * Generate correct type for select mask
+ */
+#ifndef SELECT_MASK_TYPE
+#define SELECT_MASK_TYPE fd_set
+#endif
+
+/*
+ * Check how stty works
+ */
+#undef STTY_READS_STDOUT
+
+/*
+ * Check for tty/pty functions and structures
+ */
+#undef POSIX
+#undef HAVE_TCSETATTR
+#undef HAVE_TERMIO
+#undef HAVE_TERMIOS
+#undef HAVE_SGTTYB
+#undef HAVE__GETPTY
+#undef HAVE_GETPTY
+#undef HAVE_OPENPTY
+#undef HAVE_PTC
+#undef HAVE_PTC_PTS
+#undef HAVE_PTYM
+#undef HAVE_PTYTRAP
+#undef HAVE_PTMX
+#undef HAVE_PTMX_BSD
+#undef HAVE_SCO_CLIST_PTYS
+
+/*
+ * Special hacks
+ */
+#undef CONVEX
+#undef SOLARIS
+
+#ifdef SOLARIS
+#define __EXTENSIONS__
+#endif /* SOLARIS */
+
+#undef WNOHANG_BACKUP_VALUE
+
+#endif /* __EXPECT_CF_H__ */
diff --git a/expect/expect_comm.h b/expect/expect_comm.h
new file mode 100644
index 00000000000..39fa67b3c72
--- /dev/null
+++ b/expect/expect_comm.h
@@ -0,0 +1,172 @@
+/* expectcomm.h - public symbols common to both expect.h and expect_tcl.h
+
+Written by: Don Libes, libes@cme.nist.gov, NIST, 12/3/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+*/
+
+#ifndef _EXPECT_COMM_H
+#define _EXPECT_COMM_H
+
+#if 0
+#include "expect_cf.h"
+#endif
+
+#include <stdio.h>
+#include <setjmp.h>
+
+/* since it's possible that the caller may include tcl.h before including
+ this file, we cannot include varargs/stdargs ourselves */
+
+/* Much of the following stdarg/prototype support is taken from tcl.h
+ * (7.5) with modifications. What's going on here is that don't want
+ * to simply include tcl.h everywhere, because one of the files is the
+ * Tcl-less Expect library.)
+ */
+
+
+/* Definitions that allow Tcl functions with variable numbers of
+ * arguments to be used with either varargs.h or stdarg.h.
+ * TCL_VARARGS is used in procedure prototypes. TCL_VARARGS_DEF is
+ * used to declare the arguments in a function definiton: it takes the
+ * type and name of the first argument and supplies the appropriate
+ * argument declaration string for use in the function definition.
+ * TCL_VARARGS_START initializes the va_list data structure and
+ * returns the first argument. */
+
+/* in Tcl 7.5, Tcl now supplies these definitions */
+#if !defined(TCL_VARARGS)
+# if defined(__STDC__) || defined(HAVE_STDARG_H)
+# include <stdarg.h>
+# define TCL_VARARGS(type, name) (type name, ...)
+# define TCL_VARARGS_DEF(type, name) (type name, ...)
+# define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
+# else
+# include <varargs.h>
+# ifdef __cplusplus
+# define TCL_VARARGS(type, name) (type name, ...)
+# define TCL_VARARGS_DEF(type, name) (type va_alist, ...)
+# else
+# define TCL_VARARGS(type, name) ()
+# define TCL_VARARGS_DEF(type, name) (va_alist)
+# endif
+# define TCL_VARARGS_START(type, name, list) \
+ (va_start(list), va_arg(list, type))
+# endif /* use stdarg.h */
+
+/*
+ * Definitions that allow this header file to be used either with or
+ * without ANSI C features like function prototypes.
+ */
+
+# undef _ANSI_ARGS_
+# undef CONST
+
+# if ((defined(__STDC__) || defined(SABER)) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) || defined(USE_PROTOTYPE)
+# define _USING_PROTOTYPES_ 1
+# define _ANSI_ARGS_(x) x
+# define CONST const
+# else
+# define _ANSI_ARGS_(x) ()
+# define CONST
+# endif
+
+# ifdef __cplusplus
+# define EXTERN extern "C"
+# else
+# define EXTERN extern
+# endif
+
+#endif /* defined(TCL_VARARGS) */
+
+/* Arghhh! Tcl pulls in all of tcl.h in order to get the regexp funcs */
+/* Tcl offers us a way to avoid this: temporarily define _TCL. Here goes: */
+
+#ifdef EXP_AVOID_INCLUDING_TCL_H
+# ifdef _TCL
+# define EXP__TCL_WAS_DEFINED
+# else
+# define _TCL
+# endif
+#endif
+
+#include "tclRegexp.h"
+
+/* clean up the mess */
+#ifdef EXP_AVOID_INCLUDING_TCL_H
+# ifdef EXP__TCL_WAS_DEFINED
+# undef EXP__TCL_WAS_DEFINED
+# else
+# undef _TCL
+# endif
+#endif
+
+#if 0
+/* moved to exp_int.h so expect_cf.h no longer needs to be installed */
+#ifdef NO_STDLIB_H
+# include "../compat/stdlib.h"
+#else
+# include <stdlib.h> /* for malloc */
+#endif /*NO_STDLIB_H*/
+#endif
+
+/* common return codes for Expect functions */
+/* The library actually only uses TIMEOUT and EOF */
+#define EXP_ABEOF -1 /* abnormal eof in Expect */
+ /* when in library, this define is not used. */
+ /* Instead "-1" is used literally in the */
+ /* usual sense to check errors in system */
+ /* calls */
+#define EXP_TIMEOUT -2
+#define EXP_TCLERROR -3
+#define EXP_FULLBUFFER -5
+#define EXP_MATCH -6
+#define EXP_NOMATCH -7
+#define EXP_CANTMATCH EXP_NOMATCH
+#define EXP_CANMATCH -8
+#define EXP_DATA_NEW -9 /* if select says there is new data */
+#define EXP_DATA_OLD -10 /* if we already read data in another cmd */
+#define EXP_EOF -11
+#define EXP_RECONFIGURE -12 /* changes to indirect spawn id lists */
+ /* require us to reconfigure things */
+
+/* in the unlikely event that a signal handler forces us to return this */
+/* through expect's read() routine, we temporarily convert it to this. */
+#define EXP_TCLRET -20
+#define EXP_TCLCNT -21
+#define EXP_TCLCNTTIMER -22
+#define EXP_TCLBRK -23
+#define EXP_TCLCNTEXP -24
+#define EXP_TCLRETTCL -25
+
+/* yet more TCL return codes */
+/* Tcl does not safely provide a way to define the values of these, so */
+/* use ridiculously numbers for safety */
+#define EXP_CONTINUE -101 /* continue expect command */
+ /* and restart timer */
+#define EXP_CONTINUE_TIMER -102 /* continue expect command */
+ /* and continue timer */
+#define EXP_TCL_RETURN -103 /* converted by interact */
+ /* and interpeter from */
+ /* inter_return into */
+ /* TCL_RETURN*/
+
+#define EXP_TIME_INFINITY -1
+#define EXP_SPAWN_ID_BAD -1
+
+EXTERN int exp_is_debugging;
+EXTERN int exp_loguser;
+EXTERN int exp_disconnected; /* proc. disc'd from controlling tty */
+
+EXTERN void (*exp_close_in_child)(); /* procedure to close files in child */
+EXTERN void exp_close_tcl_files(); /* deflt proc: close all Tcl's files */
+
+EXTERN void exp_slave_control _ANSI_ARGS_((int,int));
+
+EXTERN char *exp_pty_error; /* place to pass a string generated */
+ /* deep in the innards of the pty */
+ /* code but needed by anyone */
+
+#endif /* _EXPECT_COMM_H */
diff --git a/expect/expect_tcl.h b/expect/expect_tcl.h
new file mode 100644
index 00000000000..9be02b8d1e2
--- /dev/null
+++ b/expect/expect_tcl.h
@@ -0,0 +1,47 @@
+/* expect_tcl.h - include file for using the expect library, libexpect.a
+with Tcl (and optionally Tk)
+
+Written by: Don Libes, libes@cme.nist.gov, NIST, 12/3/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#ifndef _EXPECT_TCL_H
+#define _EXPECT_TCL_H
+
+#include "expect_comm.h"
+
+EXTERN int exp_cmdlinecmds;
+EXTERN int exp_interactive;
+EXTERN FILE *exp_cmdfile;
+EXTERN char *exp_cmdfilename;
+EXTERN int exp_getpid; /* pid of Expect itself */
+EXTERN int exp_buffer_command_input;
+
+EXTERN int exp_tcl_debugger_available;
+
+EXTERN Tcl_Interp *exp_interp;
+
+#define Exp_Init Expect_Init
+EXTERN int Expect_Init _ANSI_ARGS_((Tcl_Interp *)); /* for Tcl_AppInit apps */
+EXTERN void exp_parse_argv _ANSI_ARGS_((Tcl_Interp *,int argc,char **argv));
+EXTERN int exp_interpreter _ANSI_ARGS_((Tcl_Interp *));
+EXTERN int exp_interpret_cmdfile _ANSI_ARGS_((Tcl_Interp *,FILE *));
+EXTERN int exp_interpret_cmdfilename _ANSI_ARGS_((Tcl_Interp *,char *));
+EXTERN void exp_interpret_rcfiles _ANSI_ARGS_((Tcl_Interp *,int my_rc,int sys_rc));
+
+EXTERN char * exp_cook _ANSI_ARGS_((char *s,int *len));
+
+EXTERN void exp_close_on_exec _ANSI_ARGS_((int));
+
+ /* app-specific exit handler */
+EXTERN void (*exp_app_exit)_ANSI_ARGS_((Tcl_Interp *));
+EXTERN void exp_exit _ANSI_ARGS_((Tcl_Interp *,int status));
+EXTERN void exp_exit_handlers _ANSI_ARGS_((ClientData));
+
+EXTERN void exp_error _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp));
+
+#endif /* _EXPECT_TCL_H */
diff --git a/expect/expectk.man b/expect/expectk.man
new file mode 100644
index 00000000000..b8c71273abd
--- /dev/null
+++ b/expect/expectk.man
@@ -0,0 +1,42 @@
+.TH EXPECTK 1 "15 February 1993"
+.SH NAME
+expectk \- Expect with Tk support
+.SH SYNOPSIS
+.B expectk
+[
+.I args
+]
+.SH INTRODUCTION
+.B Expectk
+is a combination of Expect with Tk. (See their respective man pages for a more comprehensive explanation
+of either.)
+.B Expectk
+should run any
+.B wish
+or
+.B Expect
+script (with minor changes - see below).
+.PP
+The differences between the Expectk and Expect environment follows.
+.PP
+The
+.B send
+command is Tk's. Expect's
+.B send
+command can be invoked by the name
+.BR exp_send .
+(For compatibility, Expect allows either
+.B send
+or
+.B exp_send
+to be used.)
+.PP
+Scripts may be invoked implicitly on systems which support the #! notation
+by marking the script executable, and making the first line in your script:
+
+ #!/usr/local/bin/expectk \-f
+
+Of course, the path must accurately describe where
+.B Expectk
+lives. /usr/local/bin is just an example.
+
diff --git a/expect/fixcat b/expect/fixcat
new file mode 100755
index 00000000000..7a538cf7334
--- /dev/null
+++ b/expect/fixcat
@@ -0,0 +1,21 @@
+#!expect --
+# Synopsis: fixcat
+# Author: Don Libes
+
+# Description: test to see if /bin/cat is unbuffered (i.e., -u is needed)
+# Return 0 if buffered, 1 if unbuffered.
+#
+# If this file is sitting in an architecture-specific library directory,
+# then it serves as a marker that your /bin/cat buffers by default.
+
+# test for when catting to/from files
+log_user 0
+spawn -open [open "|cat" "r+"]
+send "\r"
+expect "\r" {exit 1}
+
+# test for when catting to real tty
+#log_user 0
+#spawn /bin/cat
+#send "\r"
+#expect "\r\n\r\n" {exit 1}
diff --git a/expect/fixline1 b/expect/fixline1
new file mode 100755
index 00000000000..7ea503fa96a
--- /dev/null
+++ b/expect/fixline1
@@ -0,0 +1,13 @@
+#!expect --
+# Synopsis: fixline1 newpath < input > output
+# Author: Don Libes
+
+# Description: change first line of script to reflect new binary
+# try to match any of the following first lines
+#!expect ...
+#!../expect ...
+#!expectk ...
+#!foo/bar/expectk ...
+#
+regsub "^#!(.*/)*(.*)" [gets stdin] "#!$argv/\\2" line1
+puts -nonewline "$line1\n[read stdin]"
diff --git a/expect/install-sh b/expect/install-sh
new file mode 100755
index 00000000000..9ab1d23932a
--- /dev/null
+++ b/expect/install-sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# 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.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/expect/libexpect.man b/expect/libexpect.man
new file mode 100644
index 00000000000..00626358558
--- /dev/null
+++ b/expect/libexpect.man
@@ -0,0 +1,690 @@
+.TH LIBEXPECT 3 "12 December 1991"
+.SH NAME
+libexpect \- programmed dialogue with interactive programs \- C functions
+.SH DESCRIPTION
+This library contains functions that allow Expect to be used as
+a Tcl extension or to be used directly from C or C++ (without Tcl).
+Adding Expect as a Tcl extension is very short and simple, so that will be
+covered first.
+.SH SYNOPSIS
+.nf
+
+.B #include "expect_tcl.h"
+.B Expect_Init(interp);
+
+.B cc files... \-lexpect5.20 \-ltcl7.5 \-lm
+
+.fi
+Note: library versions may differ in the actual release.
+
+The Expect_Init function adds expect commands to the named
+interpreter. It avoids overwriting commands that already exist,
+however aliases beginning with "exp_" are always created for expect
+commands. So for example, "send" can be used as "exp_send".
+
+Generally, you should only call Expect commands via Tcl_Eval.
+Certain auxiliary functions may be called directly. They are summarized
+below. They may be useful in constructing your own main. Look
+at the file exp_main_exp.c in the Expect distribution as
+a prototype main. Another prototype is tclAppInit.c in the
+Tcl source distribution. A prototype for working with Tk is in
+exp_main_tk.c in the Expect distribution.
+.nf
+
+int exp_cmdlinecmds;
+int exp_interactive;
+FILE *exp_cmdfile;
+char *exp_cmdfilename;
+int exp_tcl_debugger_available;
+
+void exp_parse_argv(Tcl_Interp *,int argc,char **argv);
+int exp_interpreter(Tcl_Interp *);
+void exp_interpret_cmdfile(Tcl_Interp *,FILE *);
+void exp_interpret_cmdfilename(Tcl_Interp *,char *);
+void exp_interpret_rcfiles(Tcl_Interp *,int my_rc,int sys_rc);
+char * exp_cook(char *s,int *len);
+void (*exp_app_exit)EXP_PROTO((Tcl_Interp *);
+void exp_exit(Tcl_Interp *,int status);
+void exp_exit_handlers(Tcl_Interp *);
+void exp_error(Tcl_Interp,char *,...);
+
+.fi
+.B exp_cmdlinecmds
+is 1 if Expect has been invoked with commands on the program command-line (using "-c" for example).
+.B exp_interactive
+is 1 if Expect has been invoked with the -i flag or if no commands or script is being invoked.
+.B exp_cmdfile
+is a stream from which Expect will read commands.
+.B exp_cmdfilename
+is the name of a file which Expect will open and read commands from.
+.B exp_tcl_debugger_available
+is 1 if the debugger has been armed.
+
+.B exp_parse_argv
+reads the representation of the command line.
+Based on what is found, any of the other variables listed here
+are initialized appropriately.
+.B exp_interpreter
+interactively prompts the user for commands and evaluates them.
+.B exp_interpret_cmdfile
+reads the given stream and evaluates any commands found.
+.B exp_interpret_cmdfilename
+opens the named file and evaluates any commands found.
+.B exp_interpret_rcfiles
+reads and evalutes the .rc files. If my_rc is zero,
+then ~/.expectrc is skipped. If sys_rc is zero, then the system-wide
+expectrc file is skipped.
+.B exp_cook
+returns a static buffer containing the argument reproduced with
+newlines replaced by carriage-return linefeed sequences.
+The primary purpose of this is to allow messages to be produced
+without worrying about whether the terminal is in raw mode or
+cooked mode.
+If length is zero, it is computed via strlen.
+.B exp_error is a printf-like function that writes the result
+to interp->result.
+.SH SYNOPSIS
+.nf
+.B #include <expect.h>
+
+.B int
+.B "exp_spawnl(file, arg0 [, arg1, ..., argn] (char *)0);"
+.B char *file;
+.B char *arg0, *arg1, ... *argn;
+
+.B int
+.B exp_spawnv(file,argv);
+.B char *file, *argv[ ];
+
+.B int
+.B exp_spawnfd(fd);
+.B int fd;
+
+.B FILE *
+.B exp_popen(command);
+.B char *command;
+
+.B extern int exp_pid;
+.B extern int exp_ttyinit;
+.B extern int exp_ttycopy;
+.B extern int exp_console;
+.B extern char *exp_stty_init;
+.B extern void (*exp_close_in_child)();
+.B extern void (*exp_child_exec_prelude)();
+.B extern void exp_close_tcl_files();
+
+.B cc files... \-lexpect \-ltcl \-lm
+.fi
+
+.SH DESCRIPTION
+.B exp_spawnl
+and
+.B exp_spawnv
+fork a new process so that its stdin,
+stdout, and stderr can be written and read by the current process.
+.I file
+is the name of a file to be executed. The
+.I arg
+pointers are
+null-terminated strings. Following the style of execve(),
+.I arg0
+(or
+.IR argv[0] )
+is customarily a duplicate of the name of the file.
+.PP
+Four interfaces are available,
+.B exp_spawnl
+is useful when the number of
+arguments is known at compile time.
+.B exp_spawnv
+is useful when the number of arguments is not known at compile time.
+.B exp_spawnfd
+is useful when an open file descriptor is already available as a source.
+.B exp_popen
+is explained later on.
+.PP
+If the process is successfully created, a file descriptor is returned
+which corresponds to the process's stdin, stdout and stderr.
+A stream may be associated with the file descriptor by using fdopen().
+(This should almost certainly be followed by setbuf() to unbuffer the I/O.)
+.PP
+Closing the file descriptor will typically be detected by the
+process as an EOF. Once such a process exits, it should be waited
+upon (via wait) in order to free up the kernel process slot. (Some systems
+allow you to avoid this if you ignore the SIGCHLD signal).
+.PP
+.B exp_popen
+is yet another interface, styled after popen(). It takes a Bourne
+shell command line, and returns a stream that corresponds to the process's
+stdin, stdout and stderr. The actual implementation of
+.B exp_popen
+below demonstrates
+.BR exp_spawnl .
+.nf
+
+FILE *
+exp_popen(program)
+char *program;
+{
+ FILE *fp;
+ int ec;
+
+ if (0 > (ec = exp_spawnl("sh","sh","-c",program,(char *)0)))
+ return(0);
+ if (NULL == (fp = fdopen(ec,"r+")) return(0);
+ setbuf(fp,(char *)0);
+ return(fp);
+}
+.fi
+
+After a process is started, the variable
+.B exp_pid
+is set to the process-id of the new process. The variable
+.B exp_pty_slave_name
+is set to the name of the slave side of the pty.
+
+The spawn functions uses a pty to communicate with the process. By
+default, the pty is initialized the same way as the user's tty (if
+possible, i.e., if the environment has a controlling terminal.) This
+initialization can be skipped by setting exp_ttycopy to 0.
+
+The pty is further initialized to some system wide defaults if
+exp_ttyinit is non-zero. The default is generally comparable to "stty sane".
+
+The tty setting can be further modified by setting the variable
+.BR exp_stty_init .
+This variable is interpreted in the style of stty arguments. For
+example, exp_stty_init = "sane"; repeats the default initialization.
+
+On some systems, it is possible to redirect console output to ptys.
+If this is supported, you can force the next spawn to obtain the
+console output by setting the variable
+.B exp_console
+to 1.
+
+Between the time a process is started and the new program is given
+control, the spawn functions can clean up the environment by closing
+file descriptors. By default, the only file descriptors closed are
+ones internal to Expect and any marked "close-on-exec".
+
+If needed, you can close additional file descriptors by creating
+an appropriate function and assigning it to exp_close_in_child.
+The function will be called after the fork and before the exec.
+(This also modifies the behavior of the spawn command in Expect.)
+
+If you are also using Tcl, it may be convenient to use the function
+exp_close_tcl_files which closes all files between the default
+standard file descriptors and the highest descriptor known to Tcl.
+(Expect does this.)
+
+The function exp_child_exec_prelude is the last function called prior
+to the actual exec in the child. You can redefine this for effects
+such as manipulating the uid or the signals.
+
+.SH "IF YOU WANT TO ALLOCATE YOUR OWN PTY"
+.nf
+
+.B extern int exp_autoallocpty;
+.B extern int exp_pty[2];
+.fi
+
+The spawn functions use a pty to communicate with the process. By
+default, a pty is automatically allocated each time a process is spawned.
+If you want to allocate ptys yourself, before calling one of the spawn
+functions, set
+.B exp_autoallocpty
+to 0,
+.B exp_pty[0]
+to the master pty file descriptor and
+.B exp_pty[1]
+to the slave pty file descriptor.
+The expect library will not do any pty initializations (e.g., exp_stty_init will not be used).
+The slave pty file descriptor will be
+automatically closed when the process is spawned. After the process is
+started, all further communication takes place with the master pty file
+descriptor.
+.PP
+.B exp_spawnl
+and
+.B exp_spawnv
+duplicate the shell's actions
+in searching for an executable file in a list of directories. The
+directory list is obtained from the environment.
+.SH EXPECT PROCESSING
+While it is possible to use read() to read information from a process
+spawned by
+.B exp_spawnl
+or
+.BR exp_spawnv ,
+more convenient functions are provided. They are as
+follows:
+.nf
+
+.B int
+.B exp_expectl(fd,type1,pattern1,[re1,],value1,type2,...,exp_end);
+.B int fd;
+.B enum exp_type type;
+.B char *pattern1, *pattern2, ...;
+.B regexp *re1, *re2, ...;
+.B int value1, value2, ...;
+.B
+
+.B int
+.B exp_fexpectl(fp,type1,pattern1,[re1,]value1,type2,...,exp_end);
+.B FILE *fp;
+.B enum exp_type type;
+.B char *pattern1, *pattern2, ...;
+.B regexp *re1, *re2, ...;
+.B int value1, value2, ...;
+
+.B enum exp_type {
+.B exp_end,
+.B exp_glob,
+.B exp_exact,
+.B exp_regexp,
+.B exp_compiled,
+.B exp_null,
+.B };
+
+.B struct exp_case {
+.B char *pattern;
+.B regexp *re;
+.B enum exp_type type;
+.B int value;
+.B };
+
+.B int
+.B exp_expectv(fd,cases);
+.B int fd;
+.B struct exp_case *cases;
+
+.B int
+.B exp_fexpectv(fp,cases);
+.B FILE *fp;
+.B struct exp_case *cases;
+
+.B extern int exp_timeout;
+.B extern char *exp_match;
+.B extern char *exp_match_end;
+.B extern char *exp_buffer;
+.B extern char *exp_buffer_end;
+.B extern int exp_match_max;
+.B extern int exp_full_buffer;
+.B extern int exp_remove_nulls;
+.fi
+
+The functions wait until the output from a process matches one of the
+patterns, a specified time period has passed, or an EOF is seen.
+.PP
+The first argument to each function is either a file descriptor or a stream.
+Successive sets of arguments describe patterns and associated integer values
+to return when the pattern matches.
+.PP
+The type argument is one of four values. exp_end indicates that no more
+patterns appear.
+exp_glob indicates that the pattern is a glob-style string pattern.
+exp_exact indicates that the pattern is an exact string.
+exp_regexp indicates that the pattern is a regexp-style string pattern.
+exp_compiled indicates that the pattern is a regexp-style string pattern,
+and that its compiled form is also provided.
+exp_null indicates that the pattern is a null (for debugging purposes,
+a string pattern must also follow).
+.PP
+If the compiled form is not provided with the functions
+.B exp_expectl
+and
+.BR exp_fexpectl ,
+any pattern compilation done internally is
+thrown away after the function returns. The functions
+.B exp_expectv
+and
+.B exp_fexpectv
+will automatically compile patterns and will not throw them away.
+Instead, they must be discarded by the user, by calling free on each
+pattern. It is only necessary to discard them, the last time the
+cases are used.
+.PP
+Regexp subpatterns matched are stored in the compiled regexp.
+Assuming "re" contains a compiled regexp, the matched string can be
+found in re->startp[0]. The match substrings (according to the parentheses)
+in the original pattern can be found in re->startp[1], re->startp[2], and
+so on, up to re->startp[9]. The corresponding strings ends are re->endp[x]
+where x is that same index as for the string start.
+
+The type exp_null matches if a null appears in the input. The
+variable exp_remove_nulls must be set to 0 to prevent nulls from
+being automatically stripped. By default, exp_remove_nulls is set
+to 1 and nulls are automatically stripped.
+
+.B exp_expectv
+and
+.B exp_fexpectv
+are useful when the number of patterns is
+not known in advance. In this case, the sets are provided in an array.
+The end of the array is denoted by a struct exp_case with type exp_end.
+For the rest
+of this discussion, these functions will be referred to generically as
+.IR expect.
+.PP
+If a pattern matches, then the corresponding integer value is returned.
+Values need not be unique, however they should be positive to avoid
+being mistaken for EXP_EOF, EXP_TIMEOUT, or EXP_FULLBUFFER.
+Upon EOF or timeout, the value
+.B EXP_EOF
+or
+.B EXP_TIMEOUT
+is returned. The
+default timeout period is 10 seconds but may be changed by setting the
+variable
+.BR exp_timeout .
+A value of -1
+disables a timeout from occurring.
+A value of 0 causes the expect function to return immediately (i.e., poll)
+after one read().
+However it must be preceded by a function such as select, poll, or
+an event manager callback to guarantee that there is data to be read.
+
+If the variable exp_full_buffer is 1, then EXP_FULLBUFFER is returned
+if exp_buffer fills with no pattern having matched.
+
+When the expect function returns,
+.B exp_buffer
+points to the buffer
+of characters that was being considered for matching.
+.B exp_buffer_end
+points to one past the last character in exp_buffer.
+If a match occurred,
+.B exp_match
+points into
+.B exp_buffer
+where the match began.
+.B exp_match_end
+points to one character past where the match ended.
+.PP
+Each time new input arrives, it is compared to each pattern in the
+order they are listed. Thus, you may test for absence of a match by
+making the last pattern something guaranteed to appear, such as a
+prompt. In situations where there is no prompt, you must check for
+.B EXP_TIMEOUT
+(just like you would if you were interacting manually). More philosophy
+and strategies on specifying
+.B expect
+patterns can be found in the
+documentation on the
+.B expect
+program itself. See SEE ALSO below.
+.PP
+Patterns are the usual C-shell-style regular expressions. For
+example, the following fragment looks for a successful login, such
+as from a telnet dialogue.
+.nf
+
+ switch (exp_expectl(
+ exp_glob,"connected",CONN,
+ exp_glob,"busy",BUSY,
+ exp_glob,"failed",ABORT,
+ exp_glob,"invalid password",ABORT,
+ exp_end)) {
+ case CONN: /* logged in successfully */
+ break;
+ case BUSY: /* couldn't log in at the moment */
+ break;
+ case EXP_TIMEOUT:
+ case ABORT: /* can't log in at any moment! */
+ break;
+ default: /* problem with expect */
+ }
+.fi
+
+Asterisks (as in the
+example above) are a useful shorthand for omitting line-termination
+characters and other detail.
+Patterns must match the entire output of the current process (since
+the previous read on the descriptor or stream).
+More than 2000 bytes of output can
+force earlier bytes to be "forgotten". This may be changed by setting
+the variable
+.BR exp_match_max .
+Note that excessively large values can slow down the pattern matcher.
+.SH RUNNING IN THE BACKGROUND
+.nf
+
+.B extern int exp_disconnected;
+.B int exp_disconnect();
+
+.fi
+It is possible to move a process into the background after it has
+begun running. A typical use for this is to read passwords and then
+go into the background to sleep before using the passwords to do real
+work.
+.PP
+To move a process into the background, fork, call exp_disconnect() in the
+child process and exit() in the parent process. This disassociates
+your process from the controlling terminal. If you wish to move a
+process into the background in a different way, you must set the
+variable exp_disconnected to 1. This allows processes spawned after
+this point to be started correctly.
+.SH MULTIPLEXING
+By default, the expect functions block inside of a read on a single file
+descriptor. If you want to wait on patterns from multiple file
+descriptors,
+use select, poll, or an event manager.
+They will tell you what file descriptor is ready to read.
+
+When a file descriptor is ready to read, you can use the expect
+functions to do one and only read by setting timeout to 0.
+.SH SLAVE CONTROL
+
+.nf
+
+.B void
+.B exp_slave_control(fd,enable)
+.B int fd;
+.B int enable;
+
+.fi
+
+Pty trapping is normally done automatically by the expect functions.
+However, if you want to issue an ioctl, for example, directly on the
+slave device, you should temporary disable trapping.
+
+Pty trapping can be controlled with exp_slave_control. The first
+argument is the file descriptor corresponding to the spawned process.
+The second argument is a 0 if trapping is to be disabled and 1 if it
+is to be enabled.
+
+.SH ERRORS
+All functions indicate errors by returning \-1 and setting errno.
+.PP
+Errors that occur after the spawn functions fork (e.g., attempting to
+spawn a non-existent program) are written to the process's stderr,
+and will be read by the first
+.BR expect .
+.SH SIGNALS
+.nf
+.B extern int exp_reading;
+.B extern jmp_buf exp_readenv;
+.fi
+
+.B expect
+uses alarm() to timeout, thus if you generate alarms during
+.BR expect ,
+it will timeout prematurely.
+.PP
+Internally,
+.B expect
+calls read() which can be interrupted by signals. If
+you define signal handlers, you can choose to restart or abort
+.BR expect 's
+internal read. The variable,
+.BR exp_reading ,
+is true if (and only if)
+.BR expect 's
+read has been interrupted. longjmp(exp_readenv,EXP_ABORT) will abort
+the read. longjmp(exp_readenv,EXP_RESTART) will restart the read.
+.SH LOGGING
+.nf
+
+.B extern int exp_loguser;
+.B extern int exp_logfile_all
+.B extern FILE *exp_logfile;
+.fi
+
+If
+.B exp_loguser
+is nonzero,
+.B expect
+sends any output from the spawned process to
+stdout. Since interactive programs typically echo their input, this
+usually suffices to show both sides of the conversation. If
+.B exp_logfile
+is also nonzero, this same output is written to the stream defined by
+.BR exp_logfile .
+If
+.B exp_logfile_all
+is non-zero,
+.B exp_logfile
+is written regardless of the value of
+.BR exp_loguser .
+
+.SH DEBUGGING
+While I consider the library to be easy to use, I think that the
+standalone expect program is much, much, easier to use than working
+with the C compiler and its usual edit, compile, debug cycle. Unlike
+typical C programs, most of the debugging isn't getting the C compiler
+to accept your programs - rather, it is getting the dialogue correct.
+Also, translating scripts from expect to C is usually not necessary.
+For example, the speed of interactive dialogues is virtually never an
+issue. So please try the standalone 'expect' program first. I
+suspect it is a more appropriate solution for most people than the
+library.
+.PP
+Nonetheless, if you feel compelled to debug in C,
+here are some tools to help you.
+.nf
+
+.B extern int exp_is_debugging;
+.B extern FILE *exp_debugfile;
+.fi
+
+While expect dialogues seem very intuitive, trying to codify them in a
+program can reveal many surprises in a program's interface. Therefore
+a variety of debugging aids are available. They are controlled by the
+above variables, all 0 by default.
+
+Debugging information internal to
+.B expect
+is sent to stderr when
+.B exp_is_debugging
+is non-zero. The debugging information includes
+every character received, and every attempt made to match the current
+input against the patterns. In addition, non-printable characters are
+translated to a printable form. For example, a control-C appears as a
+caret followed by a C. If
+.B exp_logfile
+is non-zero, this information
+is also written to that stream.
+.PP
+If
+.B exp_debugfile
+is non-zero, all normal and debugging information is
+written to that stream, regardless of the value of
+.BR exp_is_debugging .
+.SH CAVEATS
+The stream versions of the
+.B expect
+functions are much slower than the
+file descriptor versions because there is no way to portably read
+an unknown number of bytes without the potential of timing out.
+Thus, characters are read one at a time. You are therefore strongly
+encouraged to use the file descriptor versions of
+.B expect
+(although,
+automated versions of interactive programs don't usually demand high speed
+anyway).
+.PP
+You can actually get the best of both worlds, writing with the usual
+stream functions and reading with the file descriptor versions of
+.B expect
+as long as you don't attempt to intermix other stream input
+functions (e.g., fgetc).
+To do this, pass fileno(stream) as the file descriptor each time.
+Fortunately, there is little reason to use anything but the
+.B expect
+functions when reading from interactive programs.
+.PP
+There is no matching exp_pclose to exp_popen (unlike popen and pclose).
+It only takes two functions to close down a connection (fclose() followed
+by waiting on the pid), but it is not uncommon to separate these two
+actions by large time intervals, so the function seems of little value.
+.PP
+If you are running on a Cray running Unicos (all I know for sure from
+experience), you must run your compiled program as root or setuid. The
+problem is that the Cray only allows root processes to open ptys.
+You should observe as much precautions as possible: If you don't need
+permissions, setuid(0) only immediately before calling one of the spawn
+functions and immediately set it back afterwards.
+.PP
+Normally,
+.B spawn
+takes little time to execute. If you notice spawn taking a
+significant amount of time, it is probably encountering ptys that are
+wedged. A number of tests are run on ptys to avoid entanglements with
+errant processes. (These take 10 seconds per wedged pty.) Running
+expect with the \-d option will show if
+.B expect
+is encountering many ptys in odd states. If you cannot kill
+the processes to which these ptys are attached, your only recourse may
+be to reboot.
+.SH BUGS
+The
+.B exp_fexpect
+functions don't work at all under HP-UX - it appears to be a bug in getc.
+Follow the
+advice (above) about using the
+.B exp_expect
+functions (which doesn't need to call getc). If you fix the problem (before
+I do - please check the latest release) let me know.
+.SH SEE ALSO
+An alternative to this library is the
+.B expect
+program.
+.B expect
+interprets scripts written in a high-level language
+which direct the dialogue.
+In addition, the user can take control and interact directly when desired.
+If it is not absolutely necessary to write your own C program, it is much
+easier to use
+.B expect
+to perform the entire interaction.
+It is described further in the following references:
+.PP
+.I
+"expect: Curing Those Uncontrollable Fits of Interactivity" \fRby Don Libes,
+Proceedings of the Summer 1990 USENIX Conference,
+Anaheim, California, June 11-15, 1990.
+.PP
+.I
+"Using expect to Automate System Administration Tasks" \fRby Don Libes,
+Proceedings of the 1990 USENIX Large Installation Systems Administration
+Conference, Colorado Springs, Colorado, October 17-19, 1990.
+.PP
+expect(1), alarm(3), read(2), write(2), fdopen(3), execve(2), execvp(3),
+longjmp(3), pty(4).
+.PP
+There are several examples C programs in the test directory of
+.BR expect 's
+source distribution which use the expect library.
+.PP
+.SH AUTHOR
+Don Libes, libes@nist.gov, National Institute of Standards and Technology
+.SH ACKNOWLEDGEMENTS
+Thanks to John Ousterhout (UCBerkeley) for supplying the pattern
+matcher.
+.PP
+Design and implementation of the
+.B expect
+library was paid for by the U.S. government and is therefore in the public
+domain.
+However the author and NIST would like credit
+if this program and documentation or portions of them are used.
diff --git a/expect/mkinstalldirs b/expect/mkinstalldirs
new file mode 100755
index 00000000000..0801ec2c966
--- /dev/null
+++ b/expect/mkinstalldirs
@@ -0,0 +1,32 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d in ${1+"$@"} ; do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+ mkdir "$pathcomp" || errstatus=$?
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/expect/pkgIndex.in b/expect/pkgIndex.in
new file mode 100644
index 00000000000..1107e5487e7
--- /dev/null
+++ b/expect/pkgIndex.in
@@ -0,0 +1,10 @@
+# Tcl package index file, version 1.0
+# This file is sourced either when an application starts up or
+# by a "package unknown" script. It invokes the
+# "package ifneeded" command to set up package-related
+# information so that packages will be loaded automatically
+# in response to "package require" commands. When this
+# script is sourced, the variable $dir must contain the
+# full path name of this file's directory.
+
+package ifneeded Expect @EXP_VERSION_FULL@ [list load [file join $dir .. @EXP_SHARED_LIB_FILE@]]
diff --git a/expect/pty_sgttyb.c b/expect/pty_sgttyb.c
new file mode 100644
index 00000000000..aeb38984698
--- /dev/null
+++ b/expect/pty_sgttyb.c
@@ -0,0 +1,248 @@
+/* pty_bsd.c - routines to allocate ptys - BSD version
+
+Written by: Don Libes, NIST, 2/6/90
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include <stdio.h> /* tmp for debugging */
+#include <signal.h>
+
+#if defined(SIGCLD) && !defined(SIGCHLD)
+#define SIGCHLD SIGCLD
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+/*** #include <sys/ioctl.h> ***/
+#include <sys/file.h>
+#include <signal.h>
+#include <setjmp.h>
+#include "expect_cf.h"
+#include "exp_rename.h"
+#include "exp_tty_in.h"
+#include "exp_pty.h"
+
+void debuglog();
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+static char master_name[] = "/dev/ptyXX"; /* master */
+static char slave_name[] = "/dev/ttyXX"; /* slave */
+static char *tty_type; /* ptr to char [pt] denoting
+ whether it is a pty or tty */
+static char *tty_bank; /* ptr to char [p-z] denoting
+ which bank it is */
+static char *tty_num; /* ptr to char [0-f] denoting
+ which number it is */
+char *exp_pty_slave_name;
+char *exp_pty_error;
+
+static void
+pty_stty(s,name)
+char *s; /* args to stty */
+char *name; /* name of pty */
+{
+#define MAX_ARGLIST 10240
+ char buf[MAX_ARGLIST]; /* overkill is easier */
+ RETSIGTYPE (*old)(); /* save old sigalarm handler */
+
+#ifdef STTY_READS_STDOUT
+ sprintf(buf,"/bin/stty %s > %s",s,name);
+#else
+ sprintf(buf,"/bin/stty %s < %s",s,name);
+#endif
+ old = signal(SIGCHLD, SIG_DFL);
+ system(buf);
+ signal(SIGCHLD, old); /* restore signal handler */
+}
+
+int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */
+static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */
+
+#ifdef TIOCGWINSZ
+static struct winsize winsize = {0, 0};
+#endif
+#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
+static struct ttysize winsize = {0, 0};
+#endif
+
+exp_tty exp_tty_original;
+
+#define GET_TTYTYPE 0
+#define SET_TTYTYPE 1
+static void
+ttytype(request,fd,ttycopy,ttyinit,s)
+int request;
+int fd;
+ /* following are used only if request == SET_TTYTYPE */
+int ttycopy; /* if true, copy from /dev/tty */
+int ttyinit; /* if true, initialize to sane state */
+char *s; /* stty args */
+{
+ static struct tchars tc; /* special characters */
+ static struct ltchars lc; /* local special characters */
+ static struct winsize win; /* window size */
+ static int lb; /* local modes */
+ static int l; /* line discipline */
+
+ if (request == GET_TTYTYPE) {
+ if (-1 == ioctl(fd, TIOCGETP, (char *)&exp_tty_original)
+ || -1 == ioctl(fd, TIOCGETC, (char *)&tc)
+ || -1 == ioctl(fd, TIOCGETD, (char *)&l)
+ || -1 == ioctl(fd, TIOCGLTC, (char *)&lc)
+ || -1 == ioctl(fd, TIOCLGET, (char *)&lb)
+ || -1 == ioctl(fd, TIOCGWINSZ, (char *)&win)) {
+ knew_dev_tty = FALSE;
+ exp_dev_tty = -1;
+ }
+#ifdef TIOCGWINSZ
+ ioctl(fd,TIOCGWINSZ,&winsize);
+#endif
+#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
+ ioctl(fd,TIOCGSIZE,&winsize);
+#endif
+ } else { /* type == SET_TTYTYPE */
+ if (ttycopy && knew_dev_tty) {
+ (void) ioctl(fd, TIOCSETP, (char *)&exp_tty_current);
+ (void) ioctl(fd, TIOCSETC, (char *)&tc);
+ (void) ioctl(fd, TIOCSLTC, (char *)&lc);
+ (void) ioctl(fd, TIOCLSET, (char *)&lb);
+ (void) ioctl(fd, TIOCSETD, (char *)&l);
+ (void) ioctl(fd, TIOCSWINSZ, (char *)&win);
+#ifdef TIOCSWINSZ
+ ioctl(fd,TIOCSWINSZ,&winsize);
+#endif
+#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
+ ioctl(fd,TIOCGSIZE,&winsize);
+#endif
+ }
+
+#ifdef __CENTERLINE__
+#undef DFLT_STTY
+#define DFLT_STTY "sane"
+#endif
+
+/* Apollo Domain doesn't need this */
+#ifdef DFLT_STTY
+ if (ttyinit) {
+ /* overlay parms originally supplied by Makefile */
+ pty_stty(DFLT_STTY,slave_name);
+ }
+#endif
+
+ /* lastly, give user chance to override any terminal parms */
+ if (s) {
+ pty_stty(s,slave_name);
+ }
+ }
+}
+
+void
+exp_init_pty()
+{
+ tty_type = & slave_name[strlen("/dev/")];
+ tty_bank = &master_name[strlen("/dev/pty")];
+ tty_num = &master_name[strlen("/dev/ptyp")];
+
+ exp_dev_tty = open("/dev/tty",O_RDWR);
+
+#if experimental
+ /* code to allocate force expect to get a controlling tty */
+ /* even if it doesn't start with one (i.e., under cron). */
+ /* This code is not necessary, but helpful for testing odd things. */
+ if (exp_dev_tty == -1) {
+ /* give ourselves a controlling tty */
+ int master = getptymaster();
+ fcntl(master,F_SETFD,1); /* close-on-exec */
+ setpgrp(0,0);
+ close(0);
+ close(1);
+ getptyslave(exp_get_var(exp_interp,"stty_init"));
+ close(2);
+ fcntl(0,F_DUPFD,2); /* dup 0 onto 2 */
+ }
+#endif
+
+ knew_dev_tty = (exp_dev_tty != -1);
+ if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
+}
+
+/* returns fd of master end of pseudotty */
+int
+getptymaster()
+{
+ int master = -1;
+ char *hex, *bank;
+ struct stat statbuf;
+
+ exp_pty_error = 0;
+
+ if (exp_pty_test_start() == -1) return -1;
+
+ for (bank = "pqrstuvwxyzPQRSTUVWXYZ";*bank;bank++) {
+ *tty_bank = *bank;
+ *tty_num = '0';
+ if (stat(master_name, &statbuf) < 0) break;
+ for (hex = "0123456789abcdef";*hex;hex++) {
+ *tty_num = *hex;
+
+ /* generate slave name from master */
+ strcpy(slave_name,master_name);
+ *tty_type = 't';
+
+ master = exp_pty_test(master_name,slave_name,
+ *tty_bank,tty_num);
+ if (master >= 0) goto done;
+ }
+ }
+ done:
+ exp_pty_test_end();
+ exp_pty_slave_name = slave_name;
+ return(master);
+}
+
+/* see comment in pty_termios.c */
+/*ARGSUSED*/
+void
+exp_slave_control(master,control)
+int master;
+int control;
+{
+}
+
+int
+getptyslave(ttycopy,ttyinit,stty_args)
+int ttycopy;
+int ttyinit;
+char *stty_args;
+{
+ int slave;
+
+ if (0 > (slave = open(slave_name, O_RDWR))) return(-1);
+
+ if (0 == slave) {
+ /* if opened in a new process, slave will be 0 (and */
+ /* ultimately, 1 and 2 as well) */
+
+ /* duplicate 0 onto 1 and 2 to prepare for stty */
+ fcntl(0,F_DUPFD,1);
+ fcntl(0,F_DUPFD,2);
+ }
+
+ ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
+ (void) exp_pty_unlock();
+ return(slave);
+}
+
+void
+exp_pty_exit()
+{
+ /* a stub so we can do weird things on the cray */
+}
diff --git a/expect/pty_termios.c b/expect/pty_termios.c
new file mode 100644
index 00000000000..113d9cfbc9e
--- /dev/null
+++ b/expect/pty_termios.c
@@ -0,0 +1,752 @@
+/* pty_termios.c - routines to allocate ptys - termios version
+
+Written by: Don Libes, NIST, 2/6/90
+
+This file is in the public domain. However, the author and NIST
+would appreciate credit if you use this file or parts of it.
+
+*/
+
+#include <stdio.h>
+#include <signal.h>
+
+#if defined(SIGCLD) && !defined(SIGCHLD)
+#define SIGCHLD SIGCLD
+#endif
+
+#include "expect_cf.h"
+
+/*
+ The following functions are linked from the Tcl library. They
+ don't cause anything else in the library to be dragged in, so it
+ shouldn't cause any problems (e.g., bloat).
+
+ The functions are relatively small but painful enough that I don't care
+ to recode them. You may, if you absolutely want to get rid of any
+ vestiges of Tcl.
+*/
+extern char *TclGetRegError();
+
+
+
+#if defined(HAVE_PTYM) && defined(HAVE_PTMX)
+/*
+ * HP-UX 10.0 with streams (optional) have both PTMX and PTYM. I don't
+ * know which is preferred but seeing as how the HP trap stuff is so
+ * unusual, it is probably safer to stick with the native HP pty support,
+ * too.
+ */
+#undef HAVE_PTMX
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef NO_STDLIB_H
+#include "../compat/stdlib.h"
+#else
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_SYSMACROS_H
+#include <sys/sysmacros.h>
+#endif
+
+#ifdef HAVE_PTYTRAP
+#include <sys/ptyio.h>
+#endif
+
+#include <sys/file.h>
+
+#ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#else
+# include <fcntl.h>
+#endif
+
+#if defined(_SEQUENT_)
+# include <sys/strpty.h>
+#endif
+
+#if defined(HAVE_PTMX) && !defined(__CYGWIN32__)
+# include <sys/stropts.h>
+#endif
+
+#include "exp_win.h"
+
+#include "exp_tty_in.h"
+#include "exp_rename.h"
+#include "exp_pty.h"
+
+void debuglog();
+
+#include <errno.h>
+/*extern char *sys_errlist[];*/
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+/* Convex getpty is different than older-style getpty */
+/* Convex getpty is really just a cover function that does the traversal */
+/* across the domain of pty names. It makes no attempt to verify that */
+/* they can actually be used. Indded, the logic in the man page is */
+/* wrong because it will allow you to allocate ptys that your own account */
+/* already has in use. */
+#if defined(HAVE_GETPTY) && defined(CONVEX)
+#undef HAVE_GETPTY
+#define HAVE_CONVEX_GETPTY
+extern char *getpty();
+static char *master_name;
+static char slave_name[] = "/dev/ptyXX";
+static char *tty_bank; /* ptr to char [p-z] denoting
+ which bank it is */
+static char *tty_num; /* ptr to char [0-f] denoting
+ which number it is */
+#endif
+
+#if defined(_SEQUENT_) && !defined(HAVE_PTMX)
+/* old-style SEQUENT, new-style uses ptmx */
+static char *master_name, *slave_name;
+#endif /* _SEQUENT */
+
+/* very old SGIs prefer _getpty over ptc */
+#if defined(HAVE__GETPTY) && defined(HAVE_PTC) && !defined(HAVE_GETPTY)
+#undef HAVE_PTC
+#endif
+
+#if defined(HAVE_PTC)
+static char slave_name[] = "/dev/ttyqXXX";
+/* some machines (e.g., SVR4.0 StarServer) have all of these and */
+/* HAVE_PTC works best */
+#undef HAVE_GETPTY
+#undef HAVE__GETPTY
+#endif
+
+#if defined(HAVE__GETPTY) || defined(HAVE_PTC_PTS) || defined(HAVE_PTMX)
+static char *slave_name;
+#endif
+
+#if defined(HAVE_GETPTY)
+#include <sys/vty.h>
+static char master_name[MAXPTYNAMELEN];
+static char slave_name[MAXPTYNAMELEN];
+#endif
+
+#if !defined(HAVE_GETPTY) && !defined(HAVE__GETPTY) && !defined(HAVE_PTC) && !defined(HAVE_PTC_PTS) && !defined(HAVE_PTMX) && !defined(HAVE_CONVEX_GETPTY) && !defined(_SEQUENT_) && !defined(HAVE_SCO_CLIST_PTYS) && !defined(HAVE_OPENPTY)
+#ifdef HAVE_PTYM
+ /* strange order and missing d is intentional */
+static char banks[] = "pqrstuvwxyzabcefghijklo";
+static char master_name[] = "/dev/ptym/ptyXXXX";
+static char slave_name[] = "/dev/pty/ttyXXXX";
+static char *slave_bank;
+static char *slave_num;
+#else
+static char banks[] = "pqrstuvwxyzPQRSTUVWXYZ";
+static char master_name[] = "/dev/ptyXX";
+static char slave_name [] = "/dev/ttyXX";
+#endif /* HAVE_PTYM */
+
+static char *tty_type; /* ptr to char [pt] denoting
+ whether it is a pty or tty */
+static char *tty_bank; /* ptr to char [p-z] denoting
+ which bank it is */
+static char *tty_num; /* ptr to char [0-f] denoting
+ which number it is */
+#endif
+
+#if defined(HAVE_SCO_CLIST_PTYS)
+# define MAXPTYNAMELEN 64
+static char master_name[MAXPTYNAMELEN];
+static char slave_name[MAXPTYNAMELEN];
+#endif /* HAVE_SCO_CLIST_PTYS */
+
+#ifdef HAVE_OPENPTY
+static char master_name[64];
+static char slave_name[64];
+#endif
+
+char *exp_pty_slave_name;
+char *exp_pty_error;
+
+#if 0
+static void
+pty_stty(s,name)
+char *s; /* args to stty */
+char *name; /* name of pty */
+{
+#define MAX_ARGLIST 10240
+ char buf[MAX_ARGLIST]; /* overkill is easier */
+ RETSIGTYPE (*old)(); /* save old sigalarm handler */
+ int pid;
+
+ old = signal(SIGCHLD, SIG_DFL);
+ switch (pid = fork()) {
+ case 0: /* child */
+ exec_stty("/bin/stty","/bin/stty",s);
+ break;
+ case -1: /* fail */
+ default: /* parent */
+ waitpid(pid);
+ break;
+ }
+
+ signal(SIGCHLD, old); /* restore signal handler */
+}
+
+exec_stty(s)
+char *s;
+{
+ char *args[50];
+ char *cp;
+ int argi = 0;
+ int quoting = FALSE;
+ int in_token = FALSE; /* TRUE if we are reading a token */
+
+ args[0] = cp = s;
+ while (*s) {
+ if (quoting) {
+ if (*s == '\\' && *(s+1) == '"') { /* quoted quote */
+ s++; /* get past " */
+ *cp++ = *s++;
+ } else if (*s == '\"') { /* close quote */
+ end_token
+ quoting = FALSE;
+ } else *cp++ = *s++; /* suck up anything */
+ } else if (*s == '\"') { /* open quote */
+ in_token = TRUE;
+ quoting = TRUE;
+ s++;
+ } else if (isspace(*s)) {
+ end_token
+ } else {
+ *cp++ = *s++;
+ in_token = TRUE;
+ }
+ }
+ end_token
+ args[argi] = (char *) 0; /* terminate argv */
+ execvp(args[0],args);
+}
+#endif /*0*/
+
+static void
+pty_stty(s,name)
+char *s; /* args to stty */
+char *name; /* name of pty */
+{
+#define MAX_ARGLIST 10240
+ char buf[MAX_ARGLIST]; /* overkill is easier */
+ RETSIGTYPE (*old)(); /* save old sigalarm handler */
+
+#ifdef STTY_READS_STDOUT
+ sprintf(buf,"/bin/stty %s > %s",s,name);
+#else
+#ifdef __CYGWIN32__
+ sprintf(buf,"stty %s < %s",s,name);
+#else
+ sprintf(buf,"/bin/stty %s < %s",s,name);
+#endif
+#endif
+ old = signal(SIGCHLD, SIG_DFL);
+ system(buf);
+ signal(SIGCHLD, old); /* restore signal handler */
+}
+
+int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */
+static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */
+
+exp_tty exp_tty_original;
+
+#define GET_TTYTYPE 0
+#define SET_TTYTYPE 1
+static void
+ttytype(request,fd,ttycopy,ttyinit,s)
+int request;
+int fd;
+ /* following are used only if request == SET_TTYTYPE */
+int ttycopy; /* true/false, copy from /dev/tty */
+int ttyinit; /* if true, initialize to sane state */
+char *s; /* stty args */
+{
+ if (request == GET_TTYTYPE) {
+#ifdef HAVE_TCSETATTR
+ if (-1 == tcgetattr(fd, &exp_tty_original)) {
+#else
+ if (-1 == ioctl(fd, TCGETS, (char *)&exp_tty_original)) {
+#endif
+ knew_dev_tty = FALSE;
+ exp_dev_tty = -1;
+ }
+ exp_window_size_get(fd);
+ } else { /* type == SET_TTYTYPE */
+ if (ttycopy && knew_dev_tty) {
+#ifdef HAVE_TCSETATTR
+ (void) tcsetattr(fd, TCSADRAIN, &exp_tty_current);
+#else
+ (void) ioctl(fd, TCSETS, (char *)&exp_tty_current);
+#endif
+
+ exp_window_size_set(fd);
+ }
+
+#ifdef __CENTERLINE__
+#undef DFLT_STTY
+#define DFLT_STTY "sane"
+#endif
+
+/* Apollo Domain doesn't need this */
+#ifdef DFLT_STTY
+ if (ttyinit) {
+ /* overlay parms originally supplied by Makefile */
+/* As long as BSD stty insists on stdout == stderr, we can no longer write */
+/* diagnostics to parent stderr, since stderr has is now child's */
+/* Maybe someday they will fix stty? */
+/* debuglog("getptyslave: (default) stty %s\n",DFLT_STTY);*/
+ pty_stty(DFLT_STTY,slave_name);
+ }
+#endif
+
+ /* lastly, give user chance to override any terminal parms */
+ if (s) {
+ /* give user a chance to override any terminal parms */
+/* debuglog("getptyslave: (user-requested) stty %s\n",s);*/
+ pty_stty(s,slave_name);
+ }
+ }
+}
+
+void
+exp_init_pty()
+{
+#if !defined(HAVE_GETPTY) && !defined(HAVE__GETPTY) && !defined(HAVE_PTC) && !defined(HAVE_PTC_PTS) && !defined(HAVE_PTMX) && !defined(HAVE_CONVEX_GETPTY) && !defined(_SEQUENT_) && !defined(HAVE_SCO_CLIST_PTYS) && !defined(HAVE_OPENPTY)
+#ifdef HAVE_PTYM
+ static char dummy;
+ tty_bank = &master_name[strlen("/dev/ptym/pty")];
+ tty_num = &master_name[strlen("/dev/ptym/ptyX")];
+ slave_bank = &slave_name[strlen("/dev/pty/tty")];
+ slave_num = &slave_name[strlen("/dev/pty/ttyX")];
+#else
+ tty_bank = &master_name[strlen("/dev/pty")];
+ tty_num = &master_name[strlen("/dev/ptyp")];
+ tty_type = &slave_name[strlen("/dev/")];
+#endif
+
+#endif /* HAVE_PTYM */
+
+
+ exp_dev_tty = open("/dev/tty",O_RDWR);
+ knew_dev_tty = (exp_dev_tty != -1);
+ if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
+}
+
+#ifndef R_OK
+/* 3b2 doesn't define these according to jthomas@nmsu.edu. */
+#define R_OK 04
+#define W_OK 02
+#endif
+
+int
+getptymaster()
+{
+ char *hex, *bank;
+ struct stat stat_buf;
+ int master = -1;
+ int slave = -1;
+ int num;
+
+ exp_pty_error = 0;
+
+#define TEST_PTY 1
+
+#if defined(HAVE_PTMX) || defined(HAVE_PTMX_BSD)
+#undef TEST_PTY
+#if defined(HAVE_PTMX_BSD)
+ if ((master = open("/dev/ptmx_bsd", O_RDWR)) == -1) return(-1);
+#else
+ if ((master = open("/dev/ptmx", O_RDWR)) == -1) return(-1);
+#endif
+ if ((slave_name = (char *)ptsname(master)) == NULL || unlockpt(master)) {
+ close(master);
+ return(-1);
+ } else if (grantpt(master)) {
+ static char buf[500];
+ exp_pty_error = buf;
+ sprintf(exp_pty_error,"grantpt(%d) failed - likely reason is that your system administrator (in a rage of blind passion to rid the system of security holes) removed setuid from the utility used internally by grantpt to change pty permissions. Tell your system admin to reestablish setuid on the utility. Get the utility name by running Expect under truss or trace.");
+ close(master);
+ return(-1);
+ }
+#ifdef TIOCFLUSH
+ (void) ioctl(master,TIOCFLUSH,(char *)0);
+#endif /* TIOCFLUSH */
+
+ exp_pty_slave_name = slave_name;
+ return(master);
+#endif
+
+#if defined(HAVE__GETPTY) /* SGI needs it this way */
+#undef TEST_PTY
+ slave_name = _getpty(&master, O_RDWR, 0600, 0);
+ if (slave_name == NULL)
+ return (-1);
+ exp_pty_slave_name = slave_name;
+ return(master);
+#endif
+
+#if defined(HAVE_PTC) && !defined(HAVE__GETPTY) /* old SGI, version 3 */
+#undef TEST_PTY
+ master = open("/dev/ptc", O_RDWR);
+ if (master >= 0) {
+ int ptynum;
+
+ if (fstat(master, &stat_buf) < 0) {
+ close(master);
+ return(-1);
+ }
+ ptynum = minor(stat_buf.st_rdev);
+ sprintf(slave_name,"/dev/ttyq%d",ptynum);
+ }
+ exp_pty_slave_name = slave_name;
+ return(master);
+#endif
+
+#if defined(HAVE_GETPTY) && !defined(HAVE__GETPTY)
+#undef TEST_PTY
+ master = getpty(master_name, slave_name, O_RDWR);
+ /* is it really necessary to verify slave side is usable? */
+ exp_pty_slave_name = slave_name;
+ return master;
+#endif
+
+#if defined(HAVE_PTC_PTS)
+#undef TEST_PTY
+ master = open("/dev/ptc",O_RDWR);
+ if (master >= 0) {
+ /* never fails */
+ slave_name = ttyname(master);
+ }
+ exp_pty_slave_name = slave_name;
+ return(master);
+#endif
+
+#if defined(_SEQUENT_) && !defined(HAVE_PTMX)
+#undef TEST_PTY
+ /* old-style SEQUENT, new-style uses ptmx */
+ master = getpseudotty(&slave_name, &master_name);
+ exp_pty_slave_name = slave_name;
+ return(master);
+#endif /* _SEQUENT_ */
+
+#if defined(HAVE_OPENPTY)
+#undef TEST_PTY
+ if (openpty(&master, &slave, master_name, 0, 0) != 0) {
+ close(master);
+ close(slave);
+ return -1;
+ }
+ strcpy(slave_name, ttyname(slave));
+ exp_pty_slave_name = slave_name;
+ close(slave);
+ return master;
+#endif /* HAVE_OPENPTY */
+
+#if defined(TEST_PTY)
+ /*
+ * all pty allocation mechanisms after this require testing
+ */
+ if (exp_pty_test_start() == -1) return -1;
+
+#if !defined(HAVE_CONVEX_GETPTY) && !defined(HAVE_PTYM) && !defined(HAVE_SCO_CLIST_PTYS)
+ for (bank = banks;*bank;bank++) {
+ *tty_bank = *bank;
+ *tty_num = '0';
+ if (stat(master_name, &stat_buf) < 0) break;
+ for (hex = "0123456789abcdef";*hex;hex++) {
+ *tty_num = *hex;
+ strcpy(slave_name,master_name);
+ *tty_type = 't';
+ master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num);
+ if (master >= 0) goto done;
+ }
+ }
+#endif
+
+#ifdef HAVE_SCO_CLIST_PTYS
+ for (num = 0; ; num++) {
+ char num_str [16];
+
+ sprintf (num_str, "%d", num);
+ sprintf (master_name, "%s%s", "/dev/ptyp", num_str);
+ if (stat (master_name, &stat_buf) < 0)
+ break;
+ sprintf (slave_name, "%s%s", "/dev/ttyp", num_str);
+
+ master = exp_pty_test (master_name, slave_name, 0, num_str);
+ if (master >= 0)
+ goto done;
+ }
+#endif
+
+#ifdef HAVE_PTYM
+ /* systems with PTYM follow this idea:
+
+ /dev/ptym/pty[a-ce-z][0-9a-f] master pseudo terminals
+ /dev/pty/tty[a-ce-z][0-9a-f] slave pseudo terminals
+ /dev/ptym/pty[a-ce-z][0-9][0-9] master pseudo terminals
+ /dev/pty/tty[a-ce-z][0-9][0-9] slave pseudo terminals
+
+ SPPUX (Convex's HPUX compatible) follows the PTYM convention but
+ extends it:
+
+ /dev/ptym/pty[a-ce-z][0-9][0-9][0-9] master pseudo terminals
+ /dev/pty/tty[a-ce-z][0-9][0-9][0-9] slave pseudo terminals
+
+ The code does not distinguish between HPUX and SPPUX because there
+ is no reason to. HPUX will merely fail the extended SPPUX tests.
+ In fact, most SPPUX systems will fail simply because few systems
+ will actually have the extended ptys. However, the tests are
+ fast so it is no big deal.
+ */
+
+ /*
+ * pty[a-ce-z][0-9a-f]
+ */
+
+ for (bank = banks;*bank;bank++) {
+ *tty_bank = *bank;
+ sprintf(tty_num,"0");
+ if (stat(master_name, &stat_buf) < 0) break;
+ *(slave_num+1) = '\0';
+ for (hex = "0123456789abcdef";*hex;hex++) {
+ *tty_num = *hex;
+ *slave_bank = *tty_bank;
+ *slave_num = *tty_num;
+ master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num);
+ if (master >= 0) goto done;
+ }
+ }
+
+ /*
+ * tty[p-za-ce-o][0-9][0-9]
+ */
+
+ for (bank = banks;*bank;bank++) {
+ *tty_bank = *bank;
+ sprintf(tty_num,"00");
+ if (stat(master_name, &stat_buf) < 0) break;
+ for (num = 0; num<100; num++) {
+ *slave_bank = *tty_bank;
+ sprintf(tty_num,"%02d",num);
+ strcpy(slave_num,tty_num);
+ master = exp_pty_test(master_name,slave_name,tty_bank,tty_num);
+ if (master >= 0) goto done;
+ }
+ }
+
+ /*
+ * tty[p-za-ce-o][0-9][0-9][0-9]
+ */
+ for (bank = banks;*bank;bank++) {
+ *tty_bank = *bank;
+ sprintf(tty_num,"000");
+ if (stat(master_name, &stat_buf) < 0) break;
+ for (num = 0; num<1000; num++) {
+ *slave_bank = *tty_bank;
+ sprintf(tty_num,"%03d",num);
+ strcpy(slave_num,tty_num);
+ master = exp_pty_test(master_name,slave_name,tty_bank,tty_num);
+ if (master >= 0) goto done;
+ }
+ }
+
+#endif /* HAVE_PTYM */
+
+#if defined(HAVE_CONVEX_GETPTY)
+ for (;;) {
+ if ((master_name = getpty()) == NULL) return -1;
+
+ strcpy(slave_name,master_name);
+ slave_name[5] = 't';/* /dev/ptyXY ==> /dev/ttyXY */
+
+ tty_bank = &slave_name[8];
+ tty_num = &slave_name[9];
+ master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num);
+ if (master >= 0) goto done;
+ }
+#endif
+
+ done:
+ exp_pty_test_end();
+ exp_pty_slave_name = slave_name;
+ return(master);
+
+#endif /* defined(TEST_PTY) */
+}
+
+/* if slave is opened in a child, slave_control(1) must be executed after */
+/* master is opened (when child is opened is irrelevent) */
+/* if slave is opened in same proc as master, slave_control(1) must executed */
+/* after slave is opened */
+/*ARGSUSED*/
+void
+exp_slave_control(master,control)
+int master;
+int control; /* if 1, enable pty trapping of close/open/ioctl */
+{
+#ifdef HAVE_PTYTRAP
+ ioctl(master, TIOCTRAP, &control);
+#endif /* HAVE_PTYTRAP */
+}
+
+int
+getptyslave(ttycopy,ttyinit,stty_args)
+int ttycopy;
+int ttyinit;
+char *stty_args;
+{
+ int slave, slave2;
+ char buf[10240];
+
+ if (0 > (slave = open(slave_name, O_RDWR))) return(-1);
+
+#if defined(HAVE_PTMX_BSD)
+ if (ioctl (slave, I_LOOK, buf) != 0)
+ if (ioctl (slave, I_PUSH, "ldterm")) {
+ debuglog("ioctl(%s,I_PUSH,\"ldterm\") = %s\n",Tcl_ErrnoMsg(errno));
+ }
+#else
+#if defined(HAVE_PTMX) && ! defined(__CYGWIN32__)
+ if (ioctl(slave, I_PUSH, "ptem")) {
+ debuglog("ioctl(%s,I_PUSH,\"ptem\") = %s\n",Tcl_ErrnoMsg(errno));
+ }
+ if (ioctl(slave, I_PUSH, "ldterm")) {
+ debuglog("ioctl(%s,I_PUSH,\"ldterm\") = %s\n",Tcl_ErrnoMsg(errno));
+ }
+ if (ioctl(slave, I_PUSH, "ttcompat")) {
+ debuglog("ioctl(%s,I_PUSH,\"ttcompat\") = %s\n",Tcl_ErrnoMsg(errno));
+ }
+#endif
+#endif
+
+ if (0 == slave) {
+ /* if opened in a new process, slave will be 0 (and */
+ /* ultimately, 1 and 2 as well) */
+
+ /* duplicate 0 onto 1 and 2 to prepare for stty */
+ fcntl(0,F_DUPFD,1);
+ fcntl(0,F_DUPFD,2);
+ }
+
+ ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
+
+#if 0
+#ifdef HAVE_PTYTRAP
+ /* do another open, to tell master that slave is done fiddling */
+ /* with pty and master does not have to wait to do further acks */
+ if (0 > (slave2 = open(slave_name, O_RDWR))) return(-1);
+ close(slave2);
+#endif /* HAVE_PTYTRAP */
+#endif
+
+ (void) exp_pty_unlock();
+ return(slave);
+}
+
+#ifdef HAVE_PTYTRAP
+#include <sys/ptyio.h>
+#include <sys/time.h>
+
+/* This function attempts to deal with HP's pty interface. This
+function simply returns an indication of what was trapped (or -1 for
+failure), the parent deals with the details.
+
+Originally, I tried to just trap open's but that is not enough. When
+the pty is initialized, ioctl's are generated and if not trapped will
+hang the child if no further trapping is done. (This could occur if
+parent spawns a process and then immediatley does a close.) So
+instead, the parent must trap the ioctl's. It probably suffices to
+trap the write ioctl's (and tiocsctty which some hp's need) -
+conceivably, stty could be smart enough not to do write's if the tty
+settings are already correct. In that case, we'll have to rethink
+this.
+
+Suggestions from HP engineers encouraged. I cannot imagine how this
+interface was intended to be used!
+
+*/
+
+int
+exp_wait_for_slave_open(fd)
+int fd;
+{
+ fd_set excep;
+ struct timeval t;
+ struct request_info ioctl_info;
+ int rc;
+ int found = 0;
+
+ int maxfds = sysconf(_SC_OPEN_MAX);
+
+ t.tv_sec = 30; /* 30 seconds */
+ t.tv_usec = 0;
+
+ FD_ZERO(&excep);
+ FD_SET(fd,&excep);
+
+ rc = select(maxfds,
+ (SELECT_MASK_TYPE *)0,
+ (SELECT_MASK_TYPE *)0,
+ (SELECT_MASK_TYPE *)&excep,
+ &t);
+ if (rc != 1) {
+ debuglog("spawned process never started, errno = %d\n",errno);
+ return(-1);
+ }
+ if (ioctl(fd,TIOCREQCHECK,&ioctl_info) < 0) {
+ debuglog("ioctl(TIOCREQCHECK) failed, errno = %d\n",errno);
+ return(-1);
+ }
+
+ found = ioctl_info.request;
+
+ debuglog("trapped pty op = %x",found);
+ if (found == TIOCOPEN) {
+ debuglog(" TIOCOPEN");
+ } else if (found == TIOCCLOSE) {
+ debuglog(" TIOCCLOSE");
+ }
+
+#ifdef TIOCSCTTY
+ if (found == TIOCSCTTY) {
+ debuglog(" TIOCSCTTY");
+ }
+#endif
+
+ if (found & IOC_IN) {
+ debuglog(" IOC_IN (set)");
+ } else if (found & IOC_OUT) {
+ debuglog(" IOC_OUT (get)");
+ }
+
+ debuglog("\n");
+
+ if (ioctl(fd, TIOCREQSET, &ioctl_info) < 0) {
+ debuglog("ioctl(TIOCREQSET) failed, errno = %d\n",errno);
+ return(-1);
+ }
+ return(found);
+}
+#endif
+
+void
+exp_pty_exit()
+{
+ /* a stub so we can do weird things on the cray */
+}
diff --git a/expect/pty_unicos.c b/expect/pty_unicos.c
new file mode 100644
index 00000000000..7cc76eab601
--- /dev/null
+++ b/expect/pty_unicos.c
@@ -0,0 +1,419 @@
+/* pty_unicos.c - routines to allocate ptys - for CRAY UNICOS 5.1 and 6.0 */
+
+/*
+
+Original by: Don Libes, NIST, 2/6/90
+Hacked for Unicos 5.1 by: Frank Terhaar-Yonkers, US EPA, 1/10/91
+Hacked for Unicos 6.0 by: Pete TerMaat, pete@willow.cray.com, 3/27/91
+
+Design and implementation of this program was paid for by U.S. tax
+dollars. Therefore it is public domain. However, the author and NIST
+would appreciate credit if this program or parts of it are used.
+
+*/
+
+#include "expect_cf.h"
+#include <stdio.h>
+#include <signal.h>
+
+#if defined(SIGCLD) && !defined(SIGCHLD)
+#define SIGCHLD SIGCLD
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#else
+extern int fork(), execl(), wait();
+#endif
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#else
+# include <fcntl.h>
+#endif
+/*#if CRAY>=60*/
+#if defined(HAVE_TERMIOS)
+# include <sys/termios.h>
+#else
+# include <sys/termio.h>
+/*#endif /* 60 */*/
+#endif /* defined(HAVE_TERMIOS) */
+#if CRAY>=70 && defined(_CRAY2)
+#include <sys/session.h>
+#endif /* 70 */
+#include <sys/pty.h>
+#include <pwd.h>
+#include <utmp.h>
+#include <signal.h>
+#include "exp_tty_in.h"
+#include "exp_rename.h"
+
+#ifdef HAVE_SYSCONF_H
+#include <sys/sysconfig.h>
+#endif
+
+void debuglog();
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif /* MAXHOSTNAMELEN */
+
+static char linep[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+static char linet[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+static int lowpty;
+static int highpty;
+static int realuid;
+static int realgid;
+static int *ptys;
+static char myname[32];
+static char hostname[MAXHOSTNAMELEN];
+char *exp_pty_slave_name;
+char *exp_pty_error;
+
+static void
+pty_stty(s,name)
+char *s; /* args to stty */
+char *name; /* name of pty */
+{
+#define MAX_ARGLIST 10240
+ char buf[MAX_ARGLIST]; /* overkill is easier */
+ RETSIGTYPE (*old)(); /* save old sigalarm handler */
+
+#ifdef STTY_READS_STDOUT
+ sprintf(buf,"/bin/stty %s > %s",s,name);
+#else
+ sprintf(buf,"/bin/stty %s < %s",s,name);
+#endif
+ old = signal(SIGCHLD, SIG_DFL);
+ system(buf);
+ signal(SIGCHLD, old); /* restore signal handler */
+}
+
+int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */
+static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */
+
+#ifdef TIOCGWINSZ
+static struct winsize winsize = {0, 0};
+#endif
+#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
+static struct ttysize winsize = {0, 0};
+#endif
+
+/*struct termio exp_tty_original;*/
+exp_tty exp_tty_original;
+
+#define GET_TTYTYPE 0
+#define SET_TTYTYPE 1
+static void
+ttytype(request,fd,ttycopy,ttyinit,s)
+int request;
+int fd;
+ /* following are used only if request == SET_TTYTYPE */
+int ttycopy; /* true/false, copy from /dev/tty */
+int ttyinit; /* if true, initialize to sane state */
+char *s; /* stty args, used only if request == SET_TTYTYPE */
+{
+ if (request == GET_TTYTYPE) {
+ if (-1 == ioctl(fd, TCGETA, (char *)&exp_tty_original)) {
+ knew_dev_tty = FALSE;
+ exp_dev_tty = -1;
+ }
+#ifdef TIOCGWINSZ
+ ioctl(fd,TIOCGWINSZ,&winsize);
+#endif
+#if defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
+ ioctl(fd,TIOCGSIZE,&winsize);
+#endif
+ } else { /* type == SET_TTYTYPE */
+ if (ttycopy && knew_dev_tty) {
+ (void) ioctl(fd, TCSETA, (char *)&exp_tty_current);
+#ifdef TIOCSWINSZ
+ ioctl(fd,TIOCSWINSZ,&winsize);
+#endif
+#if defined(TIOCSSIZE) && !defined(TIOCSWINSZ)
+ ioctl(fd,TIOCGSIZE,&winsize);
+#endif
+ }
+
+ if (ttyinit) {
+ /* overlay parms originally supplied by Makefile */
+ pty_stty(DFLT_STTY,linet);
+ }
+
+ /* lastly, give user chance to override any terminal parms */
+ if (s) {
+ pty_stty(s,linet);
+ }
+ }
+}
+
+void
+exp_init_pty()
+{
+ int npty;
+ char *myline;
+
+ lowpty=0;
+#ifdef _SC_CRAY_NPTY
+ highpty=sysconf(_SC_CRAY_NPTY);
+#else
+ highpty=128;
+#endif /* _SC_CRAY_NPTY */
+
+ ptys = (int *) malloc(sizeof(int)*(highpty+1));
+ if (ptys == NULL) {
+ fprintf(stderr,"exp_init_pty: couldn't allocate pty array\n");
+ exit(1);
+ }
+ for (npty = lowpty;npty <= highpty;npty++)
+ ptys[npty] = 0;
+
+ realuid=getuid(); /* get REAL uid */
+ realgid=getgid(); /* get REAL uid */
+
+ exp_dev_tty = open("/dev/tty",O_RDWR);
+ knew_dev_tty = (exp_dev_tty != -1);
+ if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0);
+
+ /*
+ * Acquire (as root) current user name and host.
+ */
+ (void) cuserid(myname);
+ (void) gethostname(hostname,sizeof(hostname));
+
+ /*
+ * Set the real and effective userids to root using 'setuid'. Then
+ * set the real and effective userids to the actual user using
+ * 'setreuid'. This allows using 'seteuid' to go back and forth from
+ * root and the actual userid. Don't ask me why it works.
+ */
+ setuid(0);
+ setreuid(realuid,realuid);
+}
+
+/* returns fd of master end of pseudotty */
+int
+getptymaster()
+{
+ struct stat sb;
+ int master;
+ int npty;
+
+ exp_pty_error = 0;
+
+ debuglog("getptymaster: lowpty=%d highpty=%d\n",lowpty,highpty);
+ for (npty = lowpty; npty <= highpty; npty++) {
+ if (seteuid(0) == -1) { /* we need to be root! */
+ debuglog("getptymaster: seteuid root errno=%d\n",
+ errno);
+ }
+ (void) sprintf(linep, "/dev/pty/%03d", npty);
+ master = open(linep, O_RDWR);
+
+ if (master < 0) {
+ debuglog("getptymaster: open linep=%s errno=%d\n",
+ linep,errno);
+ continue;
+ }
+
+ (void) sprintf(linet, "/dev/ttyp%03d", npty);
+ if(stat(linet, &sb) < 0) {
+ debuglog("getptymaster: stat linet=%s errno=%d\n",
+ linet,errno);
+ (void) close(master);
+ continue;
+ }
+ if (sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
+ if (chown(linet, realuid, realgid) == -1) {
+ debuglog("getptymaster: chown linet=%s errno=%d\n",
+ linet,errno);
+ }
+ if (chmod(linet, 0600) == -1) {
+ debuglog("getptymaster: chmod linet=%s errno=%d\n",
+ linet,errno);
+ }
+ (void)close(master);
+ master = open(linep, 2);
+ if (master < 0) {
+ debuglog("getptymaster: reopen linep=%s errno=%d\n",
+ linep,errno);
+ continue;
+ }
+ }
+ if (seteuid(realuid) == -1) { /* back to who we are! */
+ debuglog("getptymaster: seteuid user errno=%d\n",
+ errno);
+ }
+ if (access(linet, R_OK|W_OK) != 0) {
+ debuglog("getptymaster: access linet=%s errno=%d\n",
+ linet,errno);
+ (void) close(master);
+ continue;
+ }
+ debuglog("getptymaster: allocated %s\n",linet);
+ ptys[npty] = -1;
+ exp_pty_slave_name = linet;
+ return(master);
+ }
+ if (seteuid(realuid) == -1) { /* back to who we are! */
+ debuglog("getptymaster: seteuid user errno=%d\n",errno);
+ }
+ return(-1);
+}
+
+/* see comment in pty_termios.c */
+/*ARGSUSED*/
+void
+exp_slave_control(master,control)
+int master;
+int control;
+{
+}
+
+int
+getptyslave(ttycopy,ttyinit,stty_args)
+int ttycopy;
+int ttyinit;
+char *stty_args;
+{
+ int slave;
+
+ if (0 > (slave = open(linet, O_RDWR))) {
+ debuglog("getptyslave: open linet=%s errno=%d\n",linet,errno);
+ return(-1);
+ }
+
+ /* sanity check - if slave not 0, skip rest of this and return */
+ /* to what will later be detected as an error in caller */
+ if (0 != slave) {
+ debuglog("getptyslave: slave fd not 0\n");
+ return(slave);
+ }
+
+ if (0 == slave) {
+ /* if opened in a new process, slave will be 0 (and */
+ /* ultimately, 1 and 2 as well) */
+
+ /* duplicate 0 onto 1 and 2 to prepare for stty */
+ fcntl(0,F_DUPFD,1);
+ fcntl(0,F_DUPFD,2);
+ }
+
+ ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args);
+ return(slave);
+}
+
+setptyutmp()
+{
+ struct utmp utmp;
+
+ if (seteuid(0) == -1) { /* Need to be root */
+ debuglog("setptyutmp: setuid root errno=%d\n",errno);
+ return(-1);
+ }
+ (void) time(&utmp.ut_time);
+ utmp.ut_type = USER_PROCESS;
+ utmp.ut_pid = getpid();
+ strncpy(utmp.ut_user,myname,sizeof(utmp.ut_user));
+ strncpy(utmp.ut_host,hostname,sizeof(utmp.ut_host));
+ strncpy(utmp.ut_line,linet+5,sizeof(utmp.ut_line));
+ strncpy(utmp.ut_id,linet+8,sizeof(utmp.ut_id));
+ if (pututline(&utmp) == NULL) {
+ debuglog("setptyutmp: pututline failed\n");
+ }
+ endutent();
+ if (seteuid(realuid) == -1)
+ debuglog("setptyutmp: seteuid user errno=%d\n",errno);
+ return(0);
+}
+
+setptypid(pid)
+int pid;
+{
+ int npty;
+
+ for (npty = lowpty; npty <= highpty; npty++) {
+ if (ptys[npty] < 0) {
+ debuglog("setptypid: ttyp%03d pid=%d\n",npty,pid);
+ ptys[npty] = pid;
+ break;
+ }
+ }
+}
+
+ttyp_reset()
+{
+ int npty;
+
+ if (seteuid(0) == -1) { /* we need to be root! */
+ debuglog("ttyp_reset: seteuid root errno=%d\n",errno);
+ }
+ for (npty = lowpty; npty <= highpty; npty++) {
+ if (ptys[npty] <= 0)
+ continue;
+
+ (void) sprintf(linet, "/dev/ttyp%03d", npty);
+ debuglog("ttyp_reset: resetting %s, killing %d\n",
+ linet,ptys[npty]);
+ if (chown(linet,0,0) == -1) {
+ debuglog("ttyp_reset: chown %s errno=%d\n",linet,errno);
+ }
+ if (chmod(linet, 0666) == -1) {
+ debuglog("ttyp_reset: chmod %s errno=%d\n",linet,errno);
+ }
+ resetptyutmp();
+ if (kill(ptys[npty],SIGKILL) == -1) {
+ debuglog("ttyp_reset: kill pid=%d errno=%d\n",
+ ptys[npty],errno);
+ }
+ }
+ if (seteuid(realuid) == -1) { /* Back to who we really are */
+ debuglog("ttyp_reset: seteuid user errno=%d\n",errno);
+ }
+}
+
+void
+exp_pty_exit()
+{
+ ttyp_reset();
+}
+
+resetptyutmp()
+{
+ struct utmp utmp;
+
+ (void) setutent ();
+ /* set up entry to search for */
+ (void) strncpy(utmp.ut_id, linet + strlen(linet) - 4,
+ sizeof (utmp.ut_id));
+ utmp.ut_type = USER_PROCESS;
+
+ /* position to entry in utmp file */
+ if(getutid(&utmp) == NULL) {
+ debuglog("resetptyutmp: no utmp entry for %s\n",linet);
+ return(-1); /* no utmp entry for this line ??? */
+ }
+
+ /* set up the new entry */
+ strncpy(utmp.ut_name,"",sizeof(utmp.ut_name));
+ strncpy(utmp.ut_host,"",sizeof(utmp.ut_host));
+ time(&utmp.ut_time);
+ utmp.ut_type = DEAD_PROCESS;
+ utmp.ut_exit.e_exit = 0;
+
+ /* write out the entry */
+ pututline(&utmp);
+
+ /* close the file */
+ (void) endutent();
+ return(0);
+}
diff --git a/expect/tests/README b/expect/tests/README
new file mode 100644
index 00000000000..6b6dc890c21
--- /dev/null
+++ b/expect/tests/README
@@ -0,0 +1,91 @@
+Expect Test Suite
+--------------
+
+This directory contains a set of validation tests for the Expect
+commands. Each of the files whose name ends in ".test" is intended to
+fully exercise one or a few Expect commands. The commands tested by a
+given file are listed in the first line of the file.
+
+You can run the tests in two ways:
+ (a) type "make test" in the parent directory to this one; this
+ will run all of the tests.
+ (b) start up expect in this directory, then "source" the test
+ file (for example, type "source parse.test"). To run all
+ of the tests, type "source all".
+In either case no output will be generated if all goes well, except
+for a listing of the tests. If there are errors then additional
+messages will appear in the format described below.
+
+The rest of this file provides additional information on the
+features of the testing environment.
+
+This approach to testing (and most of this file) was copied from the
+Tcl distribution.
+
+Definitions file:
+-----------------
+
+The file "defs" defines a collection of procedures and variables
+used to run the tests. It is read in automatically by each of the
+.test files if needed, but once it has been read once it will not
+be read again by the .test files. If you change defs while running
+tests you'll have to "source" it by hand to load its new contents.
+
+Test output:
+------------
+
+Normally, output only appears when there are errors. However, if
+the variable VERBOSE is set to 1 then tests will be run in "verbose"
+mode and output will be generated for each test regardless of
+whether it succeeded or failed. Test output consists of the
+following information:
+
+ - the test identifier (which can be used to locate the test code
+ in the .test file)
+ - a brief description of the test
+ - the contents of the test code
+ - the actual results produced by the tests
+ - a "PASSED" or "FAILED" message
+ - the expected results (if the test failed)
+
+You can set VERBOSE either interactively (after the defs file has been
+read in), or you can change the default value in "defs".
+
+Selecting tests for execution:
+------------------------------
+
+Normally, all the tests in a file are run whenever the file is
+"source"d. However, you can select a specific set of tests using
+the global variable TESTS. This variable contains a pattern; any
+test whose identifier matches TESTS will be run. For example,
+the following interactive command causes all of the "for" tests in
+groups 2 and 4 to be executed:
+
+ set TESTS {for-[24]*}
+
+TESTS defaults to *, but you can change the default in "defs" if
+you wish.
+
+Saving keystrokes:
+------------------
+
+A convenience procedure named "dotests" is included in file
+"defs". It takes two arguments--the name of the test file (such
+as "parse.test"), and a pattern selecting the tests you want to
+execute. It sets TESTS to the second argument, calls "source" on
+the file specified in the first argument, and restores TESTS to
+its pre-call value at the end.
+
+Batch vs. interactive execution:
+--------------------------------
+
+The tests can be run in either batch or interactive mode. Batch
+mode refers to using I/O redirection from a UNIX shell. For example,
+the following command causes the tests in the file named "parse.test"
+to be executed:
+
+ expect < parse.test > parse.test.results
+
+Users who want to execute the tests in this fashion need to first
+ensure that the file "defs" has proper values for the global
+variables that control the testing environment (VERBOSE and TESTS).
diff --git a/expect/tests/all b/expect/tests/all
new file mode 100644
index 00000000000..4cf88f929ce
--- /dev/null
+++ b/expect/tests/all
@@ -0,0 +1,10 @@
+# This file contains a top-level script to run all of the Tcl
+# tests. Execute it by invoking "source all" when running tclTest
+# in this directory.
+#
+
+foreach i [lsort [glob *.test]] {
+ puts stdout $i
+ source $i
+}
+exit ;# required for DejaGNU, I don't know why - DEL \ No newline at end of file
diff --git a/expect/tests/cat.test b/expect/tests/cat.test
new file mode 100644
index 00000000000..af6272e103c
--- /dev/null
+++ b/expect/tests/cat.test
@@ -0,0 +1,26 @@
+# Commands covered: cat (UNIX)
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+#exp_internal -f /dev/ttyp5 0
+
+catch {unset x}
+
+log_user 0
+
+test cat-1.1 {basic cat operation} {
+ exp_spawn cat -u
+ exp_send "\r"
+ set timeout 10
+ expect \r {set x 1} timeout {set x 0}
+ exp_close
+ exp_wait
+ set x
+} {1}
+
+#exp_internal 0
+
diff --git a/expect/tests/defs b/expect/tests/defs
new file mode 100644
index 00000000000..f94f22f1e96
--- /dev/null
+++ b/expect/tests/defs
@@ -0,0 +1,136 @@
+# This file contains support code for the Tcl test suite. It is
+# normally sourced by the individual files in the test suite before
+# they run their tests. This improved approach to testing was designed
+# and initially implemented by Mary Ann May-Pumphrey of Sun Microsystems.
+
+if ![info exists VERBOSE] {
+ set VERBOSE 0
+}
+set TESTS {}
+set auto_noexec 1
+set auto_noload 1
+catch {rename unknown ""}
+
+# If tests are being run as root, issue a warning message and set a
+# variable to prevent some tests from running at all.
+
+set user {}
+catch {set user [exec whoami]}
+if {$user == "root"} {
+ puts stdout "Warning: you're executing as root. I'll have to"
+ puts stdout "skip some of the tests, since they'll fail as root."
+}
+
+# Some of the tests don't work on some system configurations due to
+# configuration quirks, not due to Tcl problems; in order to prevent
+# false alarms, these tests are only run in the master source directory
+# at Berkeley. The presence of a file "Berkeley" in this directory is
+# used to indicate that these tests should be run.
+
+set atBerkeley [file exists Berkeley]
+
+proc print_verbose {test_name test_description contents_of_test code answer} {
+ puts stdout "\n"
+ puts stdout "==== $test_name $test_description"
+ puts stdout "==== Contents of test case:"
+ puts stdout "$contents_of_test"
+ if {$code != 0} {
+ if {$code == 1} {
+ puts stdout "==== Test generated error:"
+ puts stdout $answer
+ } elseif {$code == 2} {
+ puts stdout "==== Test generated return exception; result was:"
+ puts stdout $answer
+ } elseif {$code == 3} {
+ puts stdout "==== Test generated break exception"
+ } elseif {$code == 4} {
+ puts stdout "==== Test generated continue exception"
+ } else {
+ puts stdout "==== Test generated exception $code; message was:"
+ puts stdout $answer
+ }
+ } else {
+ puts stdout "==== Result was:"
+ puts stdout "$answer"
+ }
+}
+
+proc test {test_name test_description contents_of_test passing_results} {
+ global VERBOSE
+ global TESTS
+ if {[string compare $TESTS ""] != 0} then {
+ set ok 0
+ foreach test $TESTS {
+ if [string match $test $test_name] then {
+ set ok 1
+ break
+ }
+ }
+ if !$ok then return
+ }
+ set code [catch {uplevel $contents_of_test} answer]
+ if {$code != 0} {
+ print_verbose $test_name $test_description $contents_of_test \
+ $code $answer
+ } elseif {[string compare $answer $passing_results] == 0} then {
+ if $VERBOSE then {
+ print_verbose $test_name $test_description $contents_of_test \
+ $code $answer
+ puts stdout "++++ $test_name PASSED"
+ }
+ } else {
+ print_verbose $test_name $test_description $contents_of_test $code \
+ $answer
+ puts stdout "---- Result should have been:"
+ puts stdout "$passing_results"
+ puts stdout "---- $test_name FAILED"
+ }
+}
+
+# stick it in a file, run, and test by looking at output
+proc ftest {test_name test_description contents_of_test passing_results} {
+ global VERBOSE
+ global TESTS
+ global objdir
+ if {[string compare $TESTS ""] != 0} then {
+ set ok 0
+ foreach test $TESTS {
+ if [string match $test $test_name] then {
+ set ok 1
+ break
+ }
+ }
+ if !$ok then return
+ }
+
+ set file [open /tmp/[pid] w]
+ puts $file $contents_of_test
+ close $file
+
+ set code [catch {exec $objdir/expect /tmp/[pid]} answer]
+ if {$code != 0} {
+ print_verbose $test_name $test_description $contents_of_test \
+ $code $answer
+ } elseif {[string compare $answer $passing_results] == 0} then {
+ if $VERBOSE then {
+ print_verbose $test_name $test_description $contents_of_test \
+ $code $answer
+ puts stdout "++++ $test_name PASSED"
+ }
+ } else {
+ print_verbose $test_name $test_description $contents_of_test $code \
+ $answer
+ puts stdout "---- Result should have been:"
+ puts stdout "$passing_results"
+ puts stdout "---- $test_name FAILED"
+ }
+ catch {exec rm -f /tmp/[pid]}
+}
+
+proc dotests {file args} {
+ global TESTS
+ set savedTests $TESTS
+ set TESTS $args
+ source $file
+ set TESTS $savedTests
+}
diff --git a/expect/tests/expect.test b/expect/tests/expect.test
new file mode 100644
index 00000000000..73bfdb2fdaa
--- /dev/null
+++ b/expect/tests/expect.test
@@ -0,0 +1,96 @@
+# Commands covered: cat (UNIX), expect
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+catch {unset x}
+
+log_user 0
+
+exp_spawn cat -u
+exp_stty -echo < $spawn_out(slave,name)
+
+test expect-1.1 {exact pattern} {
+ expect "*"
+ exp_send "a\r"
+
+ set timeout 10
+ set x 0
+ expect -ex a {set x 1}
+ set x
+} {1}
+
+test expect-1.2 {exact pattern buffering} {
+ expect "*"
+ exp_send "hiahi\r"
+
+ set timeout 10
+ set x 0
+ expect -ex hi
+ expect -ex hi {set x 1}
+ set x
+} {1}
+
+# if only this test fails, then configure has guessed incorrectly and
+# stty accesses the control terminal from stdout. The quick fix is
+# to edit expect_cf.h and define STTY_READS_STDOUT to 1. (It should
+# be commented out.) If you figure out a way to fix the configure test,
+# let me know. Else, let me know a way to test for your particular
+# machine and os version so it can be hardwired.
+test expect-1.3 {exact pattern failure} {
+ expect "*"
+ exp_send "hiahi\r"
+
+ set timeout 10
+ set x 0
+ expect -ex hi {set x 1}
+ expect -ex hi {set x 2}
+ expect -ex hi {set x 3}
+ set x
+} {2}
+
+test expect-1.4 {glob pattern} {
+ expect "*"
+ exp_send "a\r"
+
+ set timeout 10
+ set x 0
+ expect "a" {set x 1}
+ set x
+} {1}
+
+test expect-1.5 {glob pattern buffering} {
+ expect "*"
+ exp_send "a\r"
+
+ set timeout 10
+ set x 0
+ expect "*" {set x 1}
+ set x
+} {1}
+
+test expect-1.6 {glob buffer} {
+ expect "*"
+ exp_send "philosophic\r"
+
+ set timeout 10
+ set x 0
+ expect "hi"
+ set x [string match *phi $expect_out(buffer)]
+} {1}
+
+test expect-1.7 {glob string} {
+ expect "*"
+ exp_send "philosophic\r"
+
+ set timeout 10
+ set x 0
+ expect "hi"
+ set expect_out(0,string)
+} {hi}
+
+close
+wait
diff --git a/expect/tests/pid.test b/expect/tests/pid.test
new file mode 100644
index 00000000000..76167e30986
--- /dev/null
+++ b/expect/tests/pid.test
@@ -0,0 +1,36 @@
+# Commands covered: pid
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+catch {unset x}
+
+#exp_internal -f /dev/ttyp5 0
+
+test pid-1.2 {basic pid operation} {
+ set cat [exp_spawn -noecho cat]
+ set x [expr 0!=$cat]
+ set y [expr 0==[string compare $cat [exp_pid -i $spawn_id]]]
+ exp_close;exp_wait
+ list $x $y
+} {1 1}
+
+test pid-1.3 {basic pid operation} {
+ exp_spawn -noecho cat; set cat $spawn_id
+ exp_spawn -noecho cat; set cat2 $spawn_id
+ set x [expr {0!=[string compare [exp_pid -i $cat2] [exp_pid -i $cat]]}]
+ exp_close -i $cat;exp_wait -i $cat;exp_close -i $cat2;exp_wait -i $cat2
+ set x
+} {1}
+
+test pid-1.4 {basic pid operation} {
+ list [catch {exp_pid -i 100} msg] $msg
+} {1 {exp_pid: invalid spawn id (100)}}
+
+test pid-1.5 {basic pid operation} {
+ list [catch {exp_pid -j} msg] $msg
+} {1 {usage: -i spawn_id}}
+
diff --git a/expect/tests/spawn.test b/expect/tests/spawn.test
new file mode 100644
index 00000000000..09593c32c00
--- /dev/null
+++ b/expect/tests/spawn.test
@@ -0,0 +1,65 @@
+# Commands covered: spawn
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+log_user 0
+
+#exp_internal -f /dev/ttyp5 0
+
+test spawn-1.1 {basic spawn operation} {
+ set x [catch {exp_spawn cat}]
+ set first_spawn_id $spawn_id; # save for later test
+ exp_close;exp_wait
+ set x
+} {0}
+
+test spawn-1.2 {spawn cat, then simple send/expect sequence} {
+ set cat [exp_spawn -noecho cat -u]
+ exp_send "a\r"
+ expect "a" {set x 1} timeout {set x 0}
+ exp_close;exp_wait
+ set x
+} {1}
+
+test spawn-1.3 {spawn two processes simultaneously} {
+ exp_spawn -noecho cat; set cat $spawn_id
+ exp_spawn -noecho cat; set cat2 $spawn_id
+ set x [expr {0!=[string compare [exp_pid -i $cat2] [exp_pid -i $cat]]}]
+ exp_close -i $cat;exp_wait -i $cat;exp_close -i $cat2;exp_wait -i $cat2
+ set x
+} {1}
+
+test spawn-1.4 {spawn open file} {
+ set x 0
+ set y 0
+
+ set file [open /tmp/[pid] w]
+ puts $file "testing expect's spawn -open"
+ exp_close $file
+ set pid [exp_spawn -open [open /tmp/[pid]]]
+ expect "testing expect's spawn -open" {set x 1}
+ expect eof {set y 1}
+ exec rm /tmp/[pid]
+ exp_wait
+ list $x $y $pid
+} {1 1 0}
+
+test spawn-1.5 {spawn with no fd leak} {
+ exp_spawn cat
+ set x [expr $first_spawn_id==$spawn_id]
+ exp_close; exp_wait
+ set x
+} {1}
+
+# looks to be some control-char problem
+#ftest spawn-1.6 {spawn with echo} {
+# exp_spawn cat
+#} {spawn cat}
+
+#ftest spawn-1.7 {spawn with -noecho} {
+# exp_spawn -noecho cat
+#} {}
diff --git a/expect/tests/stty.test b/expect/tests/stty.test
new file mode 100644
index 00000000000..f07a8717b62
--- /dev/null
+++ b/expect/tests/stty.test
@@ -0,0 +1,26 @@
+# Commands covered: stty
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+#exp_internal -f /dev/ttyp5 0
+
+catch {unset x}
+
+log_user 0
+
+test stty-1.1 {basic stty operation} {
+ exp_spawn cat -u
+ catch {exp_stty < $spawn_out(slave,name)}
+} {0}
+
+test stty-1.2 {basic stty operation} {
+ exp_spawn cat -u
+ catch {exp_stty -echo < $spawn_out(slave,name)}
+} {0}
+
+#exp_internal 0
+
diff --git a/expect/testsuite/ChangeLog b/expect/testsuite/ChangeLog
new file mode 100644
index 00000000000..f848829d389
--- /dev/null
+++ b/expect/testsuite/ChangeLog
@@ -0,0 +1,49 @@
+Thu Mar 26 22:17:45 1998 Felix Lee <flee@cygnus.como>
+
+ * configure.in: sinclude(../aclocal.m4)
+ * configure: rebuilt
+
+Tue Mar 24 16:21:05 1998 Stu Grossman <grossman@bhuna.cygnus.co.uk>
+
+ * configure: Regenerate with autoconf 2.12.1 to fix shell issues for
+ NT native builds.
+
+Sun Dec 28 11:05:45 1997 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in: Change "gxx_includedir" to "gxx_include_dir".
+
+Wed Sep 4 15:55:40 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * expect.tests/expect-tests.exp: Use regexp submatches, not
+ lindex, to extract test names.
+
+Mon Aug 26 12:07:17 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure: Rebuilt.
+
+ * Makefile.in (configure): --localdir is always "..".
+
+Fri Aug 23 15:55:37 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (.PHONY): New target.
+
+Fri Aug 23 13:45:41 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (configure): Delete dependencies.
+
+Mon Feb 22 07:54:03 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * expect/testsuite: made modifications to testcases, etc., to allow
+ them to work properly given the reorganization of deja-gnu and the
+ relocation of the testcases from deja-gnu to a "tool" subdirectory.
+
+Sun Feb 21 10:55:55 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * expect/testsuite: Initial creation of expect/testsuite.
+ Migrated dejagnu testcases and support files for testing nm to
+ expect/testsuite from deja-gnu. These files were moved "as is"
+ with no modifications. This migration is part of a major overhaul
+ of dejagnu. The modifications to these testcases, etc., which
+ will allow them to work with the new version of dejagnu will be
+ made in a future update.
+
diff --git a/expect/testsuite/Makefile.in b/expect/testsuite/Makefile.in
new file mode 100644
index 00000000000..605d9015981
--- /dev/null
+++ b/expect/testsuite/Makefile.in
@@ -0,0 +1,103 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+host = @host@
+bindir = @bindir@
+libdir = @libdir@
+tooldir = $(libdir)/$(target_alias)
+
+includedir = @includedir@
+gxx_include_dir = $(tooldir)/g++-include
+targetdir = $(datadir)/$(target_alias)
+
+SHELL = /bin/sh
+
+CC = @CC@
+TCLHDIR = @TCLHDIR@
+
+CC_FOR_TARGET = ` \
+ if [ -f $${rootme}../gcc/Makefile ] ; then \
+ echo $${rootme}../gcc/xgcc -B$${rootme}../gcc/; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(CC); \
+ else \
+ t='$(program_transform_name)'; echo gcc | sed -e '' $$t; \
+ fi; \
+ fi`
+
+EXPECT = `if [ -f $${rootme}/expect ] ; \
+ then echo $${rootme}/expect ; \
+ else echo expect; fi`
+
+RUNTEST = ` \
+ if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \
+ echo ${srcdir}/../../dejagnu/runtest ; \
+ else echo runtest ; fi`
+RUNTESTFLAGS =
+
+all:
+
+.PHONY: info install-info check installcheck
+info:
+install-info:
+check:
+installcheck:
+.NOEXPORT:
+
+check: exp_test site.exp
+ rootme=`cd .. && pwd`; export rootme; \
+ EXPECT=${EXPECT}; export EXPECT; \
+ if [ -f ../expect ] ; then \
+ TCL_LIBRARY=`echo ${TCLHDIR} | sed -e 's/-I//' -e 's/generic//'`/library ; \
+ export TCL_LIBRARY ; \
+ else true ; fi ; \
+ $(RUNTEST) $(RUNTESTFLAGS) --tool expect EXPECT=$$EXPECT --srcdir $(srcdir)
+
+install:
+uninstall: force
+
+exp_test.o: ${srcdir}/exp_test.c
+
+site.exp: ./config.status
+ @echo "Making a new config file..."
+ -@rm -f ./tmp?
+ @touch site.exp
+ -@mv site.exp site.bak
+ @echo "## these variables are automatically generated by make ##" > ./tmp0
+ @echo "# Do not edit here. If you wish to override these values" >> ./tmp0
+ @echo "# add them to the last section" >> ./tmp0
+ @echo "set tool expect" >> ./tmp0
+ @echo "set srcdir ${srcdir}" >> ./tmp0
+ @echo "set objdir `pwd`" >> ./tmp0
+ @echo "set host_triplet ${host}" >> ./tmp0
+ @echo "## All variables above are generated by configure. Do Not Edit ##" >> ./tmp0
+ @cat ./tmp0 > site.exp
+ @cat site.bak | sed \
+ -e '1,/^## All variables above are.*##/ d' >> site.exp
+ @rm -f ./tmp1 ./tmp0
+
+clean mostlyclean:
+ -rm -f *~ core *.o a.out *.x
+
+distclean realclean: clean
+ -rm -f *~ core
+ -rm -f Makefile config.status
+ -rm -fr *.log summary detail
+
+Makefile : $(srcdir)/Makefile.in $(host_makefile_frag)
+ $(SHELL) ./config.status
+
+# Original aclocal.m4 comes from DejaGnu
+# CYGNUS LOCAL: this hack lets "make -f Makefile.in" produce a configure file
+.PHONY: configure
+configure:
+ @echo "Rebuilding configure..."
+ (cd ${srcdir}; autoconf --localdir=..)
+
+config.status: $(srcdir)/configure
+ @echo "Rebuilding config.status..."
+ $(SHELL) ./config.status --recheck
+
+force:
diff --git a/expect/testsuite/config/default.exp b/expect/testsuite/config/default.exp
new file mode 100644
index 00000000000..f48ae3c3c23
--- /dev/null
+++ b/expect/testsuite/config/default.exp
@@ -0,0 +1,107 @@
+# Copyright (C) 1988, 1990, 1991, 1992, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+global EXPECT
+if ![info exists EXPECT] then {
+ set EXPECT $objdir/expect
+}
+
+set eprompt "expect\[0-9.\-\]*> "
+global eprompt
+
+#
+# expect_version -- extract and print the version number of expect
+#
+proc expect_version { } {
+ global EXPECT
+
+ catch {exec echo "puts \[exp_version\]\n" | $EXPECT} version
+ if [info exists version] then {
+ clone_output "[which $EXPECT] version is $version\n"
+ unset version
+}
+}
+
+#
+# expect_exit -- exit the test driver for expect
+#
+proc expect_exit {} {
+}
+
+#
+# expect_start -- start expect
+#
+proc expect_start { } {
+ global spawn_id
+ global srcdir
+ global EXPECT
+ global eprompt
+ global objdir
+
+ set defs "$srcdir/../tests/defs"
+
+ if {[which $EXPECT] != 0} then {
+ spawn $EXPECT
+ } else {
+ error "Can't find $EXPECT"
+ }
+
+ expect {
+ -re "expect.*> " {
+ verbose "Started the child expect shell"
+ }
+ timeout {
+ error "Timed out starting the child expect shell."
+ }
+ }
+
+ exp_send "set objdir $objdir\r"
+ verbose "Sourcing $defs..."
+ exp_send "source $defs\r"
+ expect {
+ -re ".*source $defs.*$" {
+ verbose "Sourced $defs"
+ }
+ "Error: couldn't read file*" {
+ error "Couldn't source $defs"
+ return -1
+ }
+ -re "$eprompt" {
+ verbose "Got prompt, sourced $defs"
+ }
+ timeout {
+ error "Timed out sourcing $defs."
+ return 1
+ }
+ }
+
+ sleep 2
+ exp_send "set VERBOSE 1\r"
+ expect {
+ -re "set VERBOSE 1\[\r\n\]*1\[\r\n\]*$eprompt" {
+ verbose "Set verbose flag for tests"
+ }
+ timeout {
+ perror "Timed out setting verbose flag."
+ }
+ }
+ return $spawn_id
+}
diff --git a/expect/testsuite/configure b/expect/testsuite/configure
new file mode 100755
index 00000000000..e9cea55e51d
--- /dev/null
+++ b/expect/testsuite/configure
@@ -0,0 +1,1385 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-tclconfig directory containing tcl configuration (tclConfig.sh)"
+ac_help="$ac_help
+ --with-tclinclude directory where tcl private headers are"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=exp_test.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+#
+# Ok, lets find the tcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tclconfig
+#
+
+if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ # Check whether --with-tclconfig or --without-tclconfig was given.
+if test "${with_tclconfig+set}" = set; then
+ withval="$with_tclconfig"
+ with_tclconfig=${withval}
+fi
+
+ echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6
+echo "configure:545: checking for Tcl configuration" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+
+ # First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ { echo "configure: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" 1>&2; exit 1; }
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[7-9]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[7-9]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[7-9]* 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9]* 2>/dev/null` ; do
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+fi
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG="# no Tcl configs found"
+ echo "configure: warning: Can't find Tcl configuration definitions" 1>&2
+ else
+ no_tcl=
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ echo "$ac_t""found $TCLCONFIG" 1>&6
+ fi
+fi
+
+
+ . $TCLCONFIG
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+CC=$TCL_CC
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:630: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:659: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ ac_prog_rejected=no
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:707: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 717 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:741: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:746: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:755: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:770: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+# If we cannot compile and link a trivial program, we can't expect anything to work
+echo $ac_n "checking whether the compiler ($CC) actually works""... $ac_c" 1>&6
+echo "configure:799: checking whether the compiler ($CC) actually works" >&5
+cat > conftest.$ac_ext <<EOF
+#line 801 "configure"
+#include "confdefs.h"
+
+int main() {
+/* don't need anything here */
+; return 0; }
+EOF
+if { (eval echo configure:808: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ c_compiles=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ c_compiles=no
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 820 "configure"
+#include "confdefs.h"
+
+int main() {
+/* don't need anything here */
+; return 0; }
+EOF
+if { (eval echo configure:827: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ c_links=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ c_links=no
+fi
+rm -f conftest*
+
+if test x"${c_compiles}" = x"no" ; then
+ { echo "configure: error: the native compiler is broken and won't compile." 1>&2; exit 1; }
+fi
+
+if test x"${c_links}" = x"no" ; then
+ { echo "configure: error: the native compiler is broken and won't link." 1>&2; exit 1; }
+fi
+echo "$ac_t""yes" 1>&6
+
+
+# This is for LynxOS, which needs a flag to force true POSIX when
+# building. It's weirder than that, cause the flag varies depending
+# how old the compiler is. So...
+# -X is for the old "cc" and "gcc" (based on 1.42)
+# -mposix is for the new gcc (at least 2.5.8)
+# This modifies the value of $CC to have the POSIX flag added
+# so it'll configure correctly
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:856: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 871 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:877: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 888 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:894: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+
+echo $ac_n "checking if running LynxOS""... $ac_c" 1>&6
+echo "configure:918: checking if running LynxOS" >&5
+if eval "test \"`echo '$''{'ac_cv_os_lynx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 923 "configure"
+#include "confdefs.h"
+/*
+ * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__"
+ */
+#if defined(__Lynx__) || defined(Lynx)
+yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_lynx=yes
+else
+ rm -rf conftest*
+ ac_cv_os_lynx=no
+fi
+rm -f conftest*
+
+fi
+
+#
+if test "$ac_cv_os_lynx" = "yes" ; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define LYNX 1
+EOF
+
+ echo $ac_n "checking whether -mposix or -X is available""... $ac_c" 1>&6
+echo "configure:953: checking whether -mposix or -X is available" >&5
+ if eval "test \"`echo '$''{'ac_cv_c_posix_flag'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 958 "configure"
+#include "confdefs.h"
+
+int main() {
+
+ /*
+ * This flag varies depending on how old the compiler is.
+ * -X is for the old "cc" and "gcc" (based on 1.42).
+ * -mposix is for the new gcc (at least 2.5.8).
+ */
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ choke me
+ #endif
+
+; return 0; }
+EOF
+if { (eval echo configure:974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_posix_flag=" -mposix"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_posix_flag=" -X"
+fi
+rm -f conftest*
+fi
+
+ CC="$CC $ac_cv_c_posix_flag"
+ echo "$ac_t""$ac_cv_c_posix_flag" 1>&6
+ else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+#
+# Ok, lets find the tcl source trees so we can use the headers
+# Warning: transition of version 9 to 10 will break this algorithm
+# because 10 sorts before 9. We also look for just tcl. We have to
+# be careful that we don't match stuff like tclX by accident.
+# the alternative search directory is involked by --with-tclinclude
+#
+no_tcl=true
+echo $ac_n "checking for Tcl private headers""... $ac_c" 1>&6
+echo "configure:1002: checking for Tcl private headers" >&5
+# Check whether --with-tclinclude or --without-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then
+ withval="$with_tclinclude"
+ with_tclinclude=${withval}
+fi
+
+if eval "test \"`echo '$''{'ac_cv_c_tclh'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+# first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
+ else
+ { echo "configure: error: ${with_tclinclude} directory doesn't contain private headers" 1>&2; exit 1; }
+ fi
+fi
+
+# next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" != x ; then
+ if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/../generic; pwd)`
+ fi
+fi
+
+# next check in private source directory
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[7-9]* 2>/dev/null` \
+ ${srcdir}/../../tcl \
+ `ls -dr ${srcdir}/../../tcl[7-9]* 2>/dev/null` \
+ ${srcdir}/../../../tcl \
+ `ls -dr ${srcdir}/../../../tcl[7-9]* 2>/dev/null ` ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# finally check in a few common install locations
+#
+# since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ for i in \
+ `ls -dr /usr/local/src/tcl[7-9]* 2>/dev/null` \
+ `ls -dr /usr/local/lib/tcl[7-9]* 2>/dev/null` \
+ /usr/local/src/tcl \
+ /usr/local/lib/tcl \
+ ${prefix}/include ; do
+ if test -f $i/generic/tclInt.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+# see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ ac_safe=`echo "tclInt.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for tclInt.h""... $ac_c" 1>&6
+echo "configure:1068: checking for tclInt.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1073 "configure"
+#include "confdefs.h"
+#include <tclInt.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1078: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_cv_c_tclh=installed
+else
+ echo "$ac_t""no" 1>&6
+ac_cv_c_tclh=""
+fi
+
+fi
+
+fi
+
+if test x"${ac_cv_c_tclh}" = x ; then
+ TCLHDIR="# no Tcl private headers found"
+ { echo "configure: error: Can't find Tcl private headers" 1>&2; exit 1; }
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" = x"installed" ; then
+ echo "$ac_t""is installed" 1>&6
+ TCLHDIR=""
+ else
+ echo "$ac_t""found in ${ac_cv_c_tclh}" 1>&6
+ # this hack is cause the TCLHDIR won't print if there is a "-I" in it.
+ TCLHDIR="-I${ac_cv_c_tclh}"
+ fi
+fi
+
+
+
+
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@TCL_DEFS@%$TCL_DEFS%g
+s%@TCL_SHLIB_CFLAGS@%$TCL_SHLIB_CFLAGS%g
+s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g
+s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g
+s%@TCL_RANLIB@%$TCL_RANLIB%g
+s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g
+s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@TCLHDIR@%$TCLHDIR%g
+s%@host@%$host%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/expect/testsuite/configure.in b/expect/testsuite/configure.in
new file mode 100644
index 00000000000..e6117e5b4fc
--- /dev/null
+++ b/expect/testsuite/configure.in
@@ -0,0 +1,25 @@
+dnl Process this file with autoconf to produce a configure script.
+sinclude(../aclocal.m4)
+AC_INIT(exp_test.c)
+
+CY_AC_PATH_TCLCONFIG
+CY_AC_LOAD_TCLCONFIG
+CC=$TCL_CC
+
+AC_PROG_CC
+CY_AC_C_WORKS
+
+# This is for LynxOS, which needs a flag to force true POSIX when
+# building. It's weirder than that, cause the flag varies depending
+# how old the compiler is. So...
+# -X is for the old "cc" and "gcc" (based on 1.42)
+# -mposix is for the new gcc (at least 2.5.8)
+# This modifies the value of $CC to have the POSIX flag added
+# so it'll configure correctly
+CY_AC_TCL_LYNX_POSIX
+CY_AC_PATH_TCLH
+
+AC_SUBST(CC)
+AC_SUBST(TCLHDIR)
+AC_SUBST(host)
+AC_OUTPUT(Makefile)
diff --git a/expect/testsuite/exp_test.c b/expect/testsuite/exp_test.c
new file mode 100644
index 00000000000..29f8d1c2638
--- /dev/null
+++ b/expect/testsuite/exp_test.c
@@ -0,0 +1,33 @@
+/*
+ * exp-test -- this is a simple C program to test the interactive functions of expect.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#define ARRAYSIZE 128
+
+main (argc, argv)
+int argc;
+char *argv[];
+{
+ char line[ARRAYSIZE];
+
+ do {
+ memset (line, 0, ARRAYSIZE);
+ fgets (line, ARRAYSIZE, stdin);
+ *(line + strlen(line)-1) = '\0'; /* get rid of the newline */
+
+ /* look for a few simple commands */
+ if (strncmp (line,"prompt ", 6) == 0) {
+ printf ("%s (y or n) ?", line + 6);
+ if (getchar() == 'y')
+ puts ("YES");
+ else
+ puts ("NO");
+ }
+ if (strncmp (line, "print ", 6) == 0) {
+ puts (line + 6);
+ }
+ } while (strncmp (line, "quit", 4));
+}
diff --git a/expect/testsuite/expect.tests/expect-tests.exp b/expect/testsuite/expect.tests/expect-tests.exp
new file mode 100644
index 00000000000..31bfa13f8b2
--- /dev/null
+++ b/expect/testsuite/expect.tests/expect-tests.exp
@@ -0,0 +1,104 @@
+# Copyright (C) 1988, 1990, 1991, 1992, 1996, 1997 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+#
+# the initial work on the version of these tests from the tcl release was done
+# by Mary Ann May-Pumphrey of Sun Microsystems.
+#
+if $tracelevel then {
+ strace $tracelevel
+ }
+
+expect_before buffer_full { error "Buffer full" }
+expect_start
+
+set timeoutmsg "Timed out: Never got started, "
+set timeout 20
+set file all
+set command "unidentified test in $file"
+
+if ![file exists ${srcdir}/../tests] {
+ perror "The source for the test cases is missing." 0
+ return -1
+}
+send "cd ${srcdir}/../tests\r"
+expect {
+ -re "set VERBOSE 1\[\r\n\]*1\[\r\n\]*$eprompt" {
+ verbose "Set verbose flag for tests"
+ exp_continue
+ }
+ -re "cd $srcdir/../tests\[\r\n\]*$eprompt" {
+ verbose "Changed directory to $srcdir/../tests" 2
+ }
+ -re "no files matched glob pattern" {
+ warning "Didn't cd to $srcdir/../tests"
+ }
+ timeout {
+ perror "Couldn't change directories" 0
+ return -1
+ }
+}
+
+exp_send "source $file\r"
+expect {
+ -re "source $file\[\r\n\]*$eprompt" {
+ verbose "Sourced test $file ..."
+ set timeoutmsg "Never got to the end of "
+ exp_continue
+ }
+ "install Tcl or set your TCL_LIBRARY environment variable" {
+ perror "You need to set the TCL_LIBRARY environment variable"
+ return -1
+ }
+ -re "no files matched glob pattern" {
+ warning "Didn't cd to $srcdir/../tests"
+ }
+ -re "\[\r\n\]*\\+\\+\\+\\+ (\[a-z\]*-\[.0-9\]*) PASSED\[\r\n\]*" {
+ pass $expect_out(1,string)
+ exp_continue
+ }
+ -re "\[\r\n\]*\\+* (\[a-z\]*-\[.0-9\]*) FAILED\[\r\n\]*" {
+ fail $expect_out(1,string)
+ exp_continue
+ }
+ -re "Test generated error:\[\r\n\]*.*\[\r\n\]*" {
+ regsub "Test generated error:\[\r\n\]+" $expect_out(0,string) "" tmp
+ regsub -all "\[\r\n\]*\[a-z.\]test\[\r\n\]*" $tmp "" tmp
+ regsub -all "\[\r\n\]*" $tmp "" tmp
+ perror "Got a test case bug \"$tmp\""
+ exp_continue
+ }
+ -re "\[x\]+ \[a-i\]+ \[A-K\]+ \[0-9\]+ " {
+ verbose "Got standard output message from exec 8.1 test." 3
+ exp_continue
+ }
+ "*Error: bad option *" {
+ fail "$command (Got a bad option)"
+ }
+ eof {
+ verbose "Done" 2
+ }
+ timeout {
+ warning "$timeoutmsg $file"
+ }
+}
+
+catch close
diff --git a/expect/vgrindefs b/expect/vgrindefs
new file mode 100644
index 00000000000..414057c8f29
--- /dev/null
+++ b/expect/vgrindefs
@@ -0,0 +1,30 @@
+# vgrindefs for Expect
+# Author: Brian Fitzgerald <fitz@mml0.meche.rpi.edu>
+# Department of Mechanical Engineering
+# Rensselaer Polytechnic Institute
+# Date: Sat, 12 Oct 91 13:41:36 EDT
+#
+# To install this file, append it to /usr/lib/vgrindefs
+#
+# vgrind is a troff pretty-printer. For example, to use it on a Sun with the
+# Adobe Transcript package, install this file and do:
+#
+# setenv TROFF ptroff
+# vgrind -lexpect file
+#
+expect|tcl:\
+ :pb=(^|;)\d?proc\d\p\d:\
+ :id=!$%&'()*+,-./\:<=>?@^_`|}~:\
+ :bb={:be=}:\
+ :cb=#:ce=$:\
+ :sb=":se=\e":\
+ :kw=debug disconnect exit\
+ expect expect_user expect_before expect_after expect_version\
+ fork\
+ interact log_file log_user overlay\
+ send send_spawn send_user send_log send_error\
+ spawn system trace trap wait\
+ break case catch concat continue error eval exec expr file for foreach\
+ format glob global history if then else index info length list print\
+ proc range rename return scan set source string time uplevel upvar:
+
diff --git a/tcl/cygwin/Makefile.in b/tcl/cygwin/Makefile.in
new file mode 100644
index 00000000000..0d614ae5b65
--- /dev/null
+++ b/tcl/cygwin/Makefile.in
@@ -0,0 +1,1089 @@
+#
+# This file is a Makefile for Tcl. If it has the name "Makefile.in"
+# then it is a template for a Makefile; to generate the actual Makefile,
+# run "./configure", which is a configuration script generated by the
+# "autoconf" program (constructs like "@foo@" will get replaced in the
+# actual Makefile.
+#
+# SCCS: @(#) Makefile.in 1.190 97/11/05 10:57:38
+
+# Current Tcl version; used in various names.
+
+VERSION = @TCL_VERSION@
+
+#----------------------------------------------------------------
+# Things you can change to personalize the Makefile for your own
+# site (you can make these changes in either Makefile.in or
+# Makefile, but changes to Makefile will get lost if you re-run
+# the configuration script).
+#----------------------------------------------------------------
+
+# Default top-level directories in which to install architecture-
+# specific files (exec_prefix) and machine-independent files such
+# as scripts (prefix). The values specified here may be overridden
+# at configure-time with the --exec-prefix and --prefix options
+# to the "configure" script.
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+# The following definition can be set to non-null for special systems
+# like AFS with replication. It allows the pathnames used for installation
+# to be different than those used for actually reference files at
+# run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix
+# when installing files.
+INSTALL_ROOT =
+
+# Directory from which applications will reference the library of Tcl
+# scripts (note: you can set the TCL_LIBRARY environment variable at
+# run-time to override this value):
+TCL_LIBRARY = @datadir@/tcl$(VERSION)
+
+# Package search path.
+TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
+
+# Path name to use when installing library scripts:
+SCRIPT_INSTALL_DIR = $(INSTALL_ROOT)$(TCL_LIBRARY)
+
+# Directory in which to install libtcl.so or libtcl.a:
+LIB_INSTALL_DIR = $(INSTALL_ROOT)@libdir@
+
+# Path to use at runtime to refer to LIB_INSTALL_DIR:
+LIB_RUNTIME_DIR = @libdir@
+
+# Directory in which to install the program tclsh:
+BIN_INSTALL_DIR = $(INSTALL_ROOT)@bindir@
+
+# Directory in which to install the include file tcl.h:
+INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)@includedir@
+
+# Top-level directory in which to install manual entries:
+MAN_INSTALL_DIR = $(INSTALL_ROOT)@mandir@
+
+# Directory in which to install manual entry for tclsh:
+MAN1_INSTALL_DIR = $(MAN_INSTALL_DIR)/man1
+
+# Directory in which to install manual entries for Tcl's C library
+# procedures:
+MAN3_INSTALL_DIR = $(MAN_INSTALL_DIR)/man3
+
+# Directory in which to install manual entries for the built-in
+# Tcl commands:
+MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann
+
+# To change the compiler switches, for example to change from -O
+# to -g, change the following line:
+#CFLAGS = -O
+
+# CYGNUS LOCAL: Set CFLAGS from configure script.
+CFLAGS = @CFLAGS@
+
+# To disable ANSI-C procedure prototypes reverse the comment characters
+# on the following lines:
+PROTO_FLAGS =
+#PROTO_FLAGS = -DNO_PROTOTYPE
+
+# Mathematical functions like sin and atan2 are enabled for expressions
+# by default. To disable them, reverse the comment characters on the
+# following pairs of lines:
+MATH_FLAGS =
+#MATH_FLAGS = -DTCL_NO_MATH
+MATH_LIBS = @MATH_LIBS@
+#MATH_LIBS =
+
+# If you use the setenv, putenv, or unsetenv procedures to modify
+# environment variables in your application and you'd like those
+# modifications to appear in the "env" Tcl variable, switch the
+# comments on the two lines below so that Tcl provides these
+# procedures instead of your standard C library.
+
+ENV_FLAGS =
+#ENV_FLAGS = -DTclSetEnv=setenv -DTcl_PutEnv=putenv -DTclUnsetEnv=unsetenv
+
+# To compile for non-UNIX systems (so that only the non-UNIX-specific
+# commands are available), reverse the comment characters on the
+# following pairs of lines. In addition, you'll have to provide your
+# own replacement for the "panic" procedure (see panic.c for what
+# the current one does).
+GENERIC_FLAGS =
+#GENERIC_FLAGS = -DTCL_GENERIC_ONLY
+UNIX_OBJS = tclMtherr.o tclUnixChan.o tclUnixEvent.o tclUnixFCmd.o \
+ tclUnixFile.o tclUnixPipe.o tclUnixSock.o \
+ tclUnixTime.o tclUnixInit.o
+#UNIX_OBJS =
+NOTIFY_OBJS = tclUnixNotfy.o
+#NOTIFY_OBJS =
+
+# To enable memory debugging reverse the comment characters on the following
+# lines. Warning: if you enable memory debugging, you must do it
+# *everywhere*, including all the code that calls Tcl, and you must use
+# ckalloc and ckfree everywhere instead of malloc and free.
+MEM_DEBUG_FLAGS =
+#MEM_DEBUG_FLAGS = -DTCL_MEM_DEBUG
+
+# To enable compilation debugging reverse the comment characters on
+# one of the following lines.
+COMPILE_DEBUG_FLAGS =
+#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_STATS
+#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+
+# Some versions of make, like SGI's, use the following variable to
+# determine which shell to use for executing commands:
+SHELL = @SHELL@
+
+# Tcl used to let the configure script choose which program to use
+# for installing, but there are just too many different versions of
+# "install" around; better to use the install-sh script that comes
+# with the distribution, which is slower but guaranteed to work.
+
+INSTALL = @srcdir@/install-sh -c
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+# The following symbol defines additional compiler flags to enable
+# Tcl itself to be a shared library. If Tcl isn't going to be a
+# shared library then the symbol has an empty definition.
+
+TCL_SHLIB_CFLAGS = @TCL_SHLIB_CFLAGS@
+#TCL_SHLIB_CFLAGS =
+
+# The symbols below provide support for dynamic loading and shared
+# libraries. See configure.in for a description of what the
+# symbols mean. The values of the symbols are normally set by the
+# configure script. You shouldn't normally need to modify any of
+# these definitions by hand.
+
+SHLIB_LD = @SHLIB_LD@
+
+SHLIB_SUFFIX = @SHLIB_SUFFIX@
+#SHLIB_SUFFIX =
+
+TCL_SHARED_LIB_SUFFIX = @TCL_SHARED_LIB_SUFFIX@
+TCL_UNSHARED_LIB_SUFFIX = @TCL_UNSHARED_LIB_SUFFIX@
+TCL_SHARED_LIB_FILE = @TCL_SHARED_LIB_FILE@
+TCL_UNSHARED_LIB_FILE = @TCL_UNSHARED_LIB_FILE@
+
+DLTEST_TARGETS = dltest/pkg5${SHLIB_SUFFIX} dltest/Makefile
+
+# The following symbol is defined to "$(DLTEST_TARGETS)" if dynamic
+# loading is available; this causes everything in the "dltest"
+# subdirectory to be built when making "tcltest. If dynamic loading
+# isn't available, configure defines this symbol to an empty string,
+# in which case the shared libraries aren't built.
+BUILD_DLTEST = @BUILD_DLTEST@
+#BUILD_DLTEST =
+
+TCL_LIB_FILE = @TCL_LIB_FILE@
+#TCL_LIB_FILE = libtcl.a
+
+TCL_LIB_FLAG = @TCL_LIB_FLAG@
+#TCL_LIB_FLAG = -ltcl
+
+#----------------------------------------------------------------
+# The information below is modified by the configure script when
+# Makefile is generated from Makefile.in. You shouldn't normally
+# modify any of this stuff by hand.
+#----------------------------------------------------------------
+
+COMPAT_OBJS = @LIBOBJS@
+
+AC_FLAGS = @DEFS@
+RANLIB = @RANLIB@
+SRC_DIR = @srcdir@
+TOP_DIR = @srcdir@/..
+GENERIC_DIR = $(TOP_DIR)/generic
+COMPAT_DIR = $(TOP_DIR)/compat
+TOOL_DIR = $(TOP_DIR)/tools
+DLTEST_DIR = @srcdir@/dltest
+UNIX_DIR = @srcdir@/../unix
+CC = @CC@
+
+#----------------------------------------------------------------
+# The information below should be usable as is. The configure
+# script won't modify it and you shouldn't need to modify it
+# either.
+#----------------------------------------------------------------
+
+
+CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} \
+-I${GENERIC_DIR} -I${SRC_DIR} \
+${AC_FLAGS} ${MATH_FLAGS} ${GENERIC_FLAGS} ${PROTO_FLAGS} ${MEM_DEBUG_FLAGS} \
+${COMPILE_DEBUG_FLAGS} ${ENV_FLAGS} -DTCL_SHLIB_EXT=\"${SHLIB_SUFFIX}\" -D__TCL_UNIX_VARIANT
+
+LIBS = @DL_LIBS@ @LIBS@ $(MATH_LIBS)
+
+DEPEND_SWITCHES = ${CFLAGS} -I${GENERIC_DIR} -I${SRC_DIR} \
+${AC_FLAGS} ${MATH_FLAGS} \
+${GENERIC_FLAGS} ${PROTO_FLAGS} ${MEM_DEBUG_FLAGS} \
+-DTCL_SHLIB_EXT=\"${SHLIB_SUFFIX}\"
+
+TCLSH_OBJS = tclAppInit.o
+
+TCLTEST_OBJS = tclTestInit.o tclTest.o tclTestObj.o \
+ tclTestProcBodyObj.o tclUnixTest.o
+
+XTTEST_OBJS = tclTest.o tclTestObj.o tclTestProcBodyObj.o \
+ tclUnixTest.o tclXtNotify.o \
+ tclXtTest.o xtTestInit.o
+
+GENERIC_OBJS = panic.o regexp.o tclAsync.o tclBasic.o tclBinary.o tclCkalloc.o \
+ tclClock.o tclCmdAH.o tclCmdIL.o tclCmdMZ.o tclCompExpr.o \
+ tclCompile.o tclDate.o tclEnv.o tclEvent.o tclExecute.o \
+ tclFCmd.o tclFileName.o tclGet.o tclHash.o tclHistory.o \
+ tclIndexObj.o tclInterp.o tclIO.o tclIOCmd.o tclIOSock.o \
+ tclIOUtil.o tclLink.o tclListObj.o tclLoad.o tclMain.o tclNamesp.o \
+ tclNotify.o tclObj.o tclParse.o tclPipe.o tclPkg.o tclPosixStr.o \
+ tclPreserve.o tclProc.o tclStringObj.o tclTimer.o tclUtil.o tclVar.o \
+ tclResolve.o
+
+OBJS = ${GENERIC_OBJS} ${UNIX_OBJS} ${NOTIFY_OBJS} ${COMPAT_OBJS} @DL_OBJS@
+
+GENERIC_HDRS = \
+ $(GENERIC_DIR)/tclRegexp.h \
+ $(GENERIC_DIR)/tcl.h \
+ $(GENERIC_DIR)/tclInt.h \
+ $(GENERIC_DIR)/tclPort.h \
+ $(GENERIC_DIR)/tclPatch.h
+
+GENERIC_SRCS = \
+ $(GENERIC_DIR)/regexp.c \
+ $(GENERIC_DIR)/tclAsync.c \
+ $(GENERIC_DIR)/tclBasic.c \
+ $(GENERIC_DIR)/tclBinary.c \
+ $(GENERIC_DIR)/tclCkalloc.c \
+ $(GENERIC_DIR)/tclClock.c \
+ $(GENERIC_DIR)/tclCmdAH.c \
+ $(GENERIC_DIR)/tclCmdIL.c \
+ $(GENERIC_DIR)/tclCmdMZ.c \
+ $(GENERIC_DIR)/tclCompExpr.c \
+ $(GENERIC_DIR)/tclCompile.c \
+ $(GENERIC_DIR)/tclDate.c \
+ $(GENERIC_DIR)/tclEnv.c \
+ $(GENERIC_DIR)/tclEvent.c \
+ $(GENERIC_DIR)/tclExecute.c \
+ $(GENERIC_DIR)/tclFCmd.c \
+ $(GENERIC_DIR)/tclFileName.c \
+ $(GENERIC_DIR)/tclGet.c \
+ $(GENERIC_DIR)/tclHash.c \
+ $(GENERIC_DIR)/tclHistory.c \
+ $(GENERIC_DIR)/tclIndexObj.c \
+ $(GENERIC_DIR)/tclInterp.c \
+ $(GENERIC_DIR)/tclIO.c \
+ $(GENERIC_DIR)/tclIOCmd.c \
+ $(GENERIC_DIR)/tclIOSock.c \
+ $(GENERIC_DIR)/tclIOUtil.c \
+ $(GENERIC_DIR)/tclLink.c \
+ $(GENERIC_DIR)/tclListObj.c \
+ $(GENERIC_DIR)/tclLoad.c \
+ $(GENERIC_DIR)/tclMain.c \
+ $(GENERIC_DIR)/tclNamesp.c \
+ $(GENERIC_DIR)/tclNotify.c \
+ $(GENERIC_DIR)/tclObj.c \
+ $(GENERIC_DIR)/tclParse.c \
+ $(GENERIC_DIR)/tclPipe.c \
+ $(GENERIC_DIR)/tclPkg.c \
+ $(GENERIC_DIR)/tclPosixStr.c \
+ $(GENERIC_DIR)/tclPreserve.c \
+ $(GENERIC_DIR)/tclProc.c \
+ $(GENERIC_DIR)/tclTestProcBodyObj.c \
+ $(GENERIC_DIR)/tclResolve.c \
+ $(GENERIC_DIR)/tclStringObj.c \
+ $(GENERIC_DIR)/tclTest.c \
+ $(GENERIC_DIR)/tclTestObj.c \
+ $(GENERIC_DIR)/tclTimer.c \
+ $(GENERIC_DIR)/tclUtil.c \
+ $(GENERIC_DIR)/tclVar.c
+
+UNIX_HDRS = \
+ $(UNIX_DIR)/tclUnixPort.h
+
+UNIX_SRCS = \
+ $(UNIX_DIR)/tclAppInit.c \
+ $(UNIX_DIR)/tclMtherr.c \
+ $(UNIX_DIR)/tclUnixChan.c \
+ $(UNIX_DIR)/tclUnixEvent.c \
+ $(UNIX_DIR)/tclUnixFCmd.c \
+ $(UNIX_DIR)/tclUnixFile.c \
+ $(UNIX_DIR)/tclUnixNotfy.c \
+ $(UNIX_DIR)/tclUnixPipe.c \
+ $(UNIX_DIR)/tclUnixSock.c \
+ $(UNIX_DIR)/tclUnixTest.c \
+ $(UNIX_DIR)/tclUnixTime.c \
+ $(UNIX_DIR)/tclUnixInit.c
+
+DL_SRCS = \
+ $(UNIX_DIR)/tclLoadAix.c \
+ $(UNIX_DIR)/tclLoadAout.c \
+ $(UNIX_DIR)/tclLoadDl.c \
+ $(UNIX_DIR)/tclLoadDl2.c \
+ $(UNIX_DIR)/tclLoadDld.c \
+ $(GENERIC_DIR)/tclLoadNone.c \
+ $(UNIX_DIR)/tclLoadOSF.c \
+ $(UNIX_DIR)/tclLoadShl.c
+
+# Note: don't include DL_SRCS in SRCS: most of those files won't
+# compile on the current machine, and they will cause problems for
+# things like "make depend".
+
+SRCS = $(GENERIC_SRCS) $(UNIX_SRCS)
+
+all: ${TCL_LIB_FILE} tclsh
+
+# CYGNUS LOCAL
+
+# The shared- and unshared-library cases are separate, so that RANLIB
+# can unconditionally work.
+
+${TCL_SHARED_LIB_FILE}: ${OBJS}
+ rm -f ${TCL_LIB_FILE}
+ @MAKE_LIB@
+
+${TCL_UNSHARED_LIB_FILE}: ${OBJS}
+ rm -f ${TCL_LIB_FILE}
+ @MAKE_LIB@
+ $(RANLIB) ${TCL_LIB_FILE}
+
+# END CYGNUS LOCAL
+
+# Make target which outputs the list of the .o contained in the Tcl lib
+# usefull to build a single big shared library containing Tcl and other
+# extensions. used for the Tcl Plugin. -- dl
+# The dependency on OBJS is not there because we just want the list
+# of objects here, not actually building them
+tclLibObjs:
+ @echo ${OBJS}
+# This targets actually build the objects needed for the lib in the above
+# case
+objs: ${OBJS}
+
+
+tclsh: ${TCLSH_OBJS} ${TCL_LIB_FILE}
+ ${CC} @LD_FLAGS@ ${TCLSH_OBJS} @TCL_BUILD_LIB_SPEC@ ${LIBS} \
+ @TCL_LD_SEARCH_FLAGS@ -o tclsh
+
+tcltest: ${TCLTEST_OBJS} ${TCL_LIB_FILE} ${BUILD_DLTEST}
+ ${CC} @LD_FLAGS@ ${TCLTEST_OBJS} @TCL_BUILD_LIB_SPEC@ ${LIBS} \
+ @TCL_LD_SEARCH_FLAGS@ -o tcltest
+
+xttest: ${XTTEST_OBJS} ${GENERIC_OBJS} ${UNIX_OBJS} ${COMPAT_OBJS} \
+ @DL_OBJS@ ${BUILD_DLTEST}
+ ${CC} ${XTTEST_OBJS} ${GENERIC_OBJS} ${UNIX_OBJS} ${COMPAT_OBJS} \
+ @DL_OBJS@ @TCL_BUILD_LIB_SPEC@ ${LIBS} \
+ @TCL_LD_SEARCH_FLAGS@ -lXt -o xttest
+
+
+# Note, in the target below TCL_LIBRARY needs to be set or else
+# "make test" won't work in the case where the compilation directory
+# isn't the same as the source directory.
+
+test: tcltest
+ LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH; \
+ TCL_LIBRARY=${TOP_DIR}/library; export TCL_LIBRARY; \
+ ( echo cd $(TOP_DIR)/tests\; source all ) | ./tcltest
+
+# Useful target to launch a built tcltest with the proper path,...
+runtest:
+ LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH; \
+ TCL_LIBRARY=${TOP_DIR}/library; export TCL_LIBRARY; \
+ ./tcltest
+
+# The following target outputs the name of the top-level source directory
+# for Tcl (it is used by Tk's configure script, for example). The
+# .NO_PARALLEL line is needed to avoid problems under Sun's "pmake".
+# Note: this target is now obsolete (use the autoconf variable
+# TCL_SRC_DIR from tclConfig.sh instead).
+
+.NO_PARALLEL: topDirName
+topDirName:
+ @cd $(TOP_DIR); pwd
+
+# The following target generates the file generic/tclDate.c
+# from the yacc grammar found in generic/tclGetDate.y. This is
+# only run by hand as yacc is not available in all environments.
+# The name of the .c file is different than the name of the .y file
+# so that make doesn't try to automatically regenerate the .c file.
+
+gendate:
+ yacc -l $(GENERIC_DIR)/tclGetDate.y
+ sed -e 's/yy/TclDate/g' -e '/^#include <values.h>/d' \
+ -e 's/SCCSID/%Z\% %M\% %I\% %E\% %U\%/g' \
+ -e '/#ifdef __STDC__/,/#endif/d' -e '/TclDateerrlab:/d' \
+ -e '/TclDatenewstate:/d' -e '/#pragma/d' \
+ <y.tab.c >$(GENERIC_DIR)/tclDate.c
+ rm y.tab.c
+
+# The following targets generate the shared libraries in dltest that
+# are used for testing; they are included as part of the "tcltest"
+# target (via the BUILD_DLTEST variable) if dynamic loading is supported
+# on this platform. The ".." environment variable stuff is needed
+# because on some platforms tclsh scripts will be executed as part of
+# building the shared libraries, and they need to be able to use the
+# uninstalled tclsh that is present in this directory. The "make tclsh"
+# command is needed for the same reason (must make sure that it exists).
+
+dltest/pkg5${SHLIB_SUFFIX}: dltest/Makefile
+ if test ! -f tclsh; then $(MAKE) tclsh; else true; fi
+ libdir=`cd $(TOP_DIR)/library && pwd`; cd dltest; \
+ PATH=..:${PATH} TCL_LIBRARY=$$libdir $(MAKE)
+
+dltest/Makefile: $(DLTEST_DIR)/configure $(DLTEST_DIR)/Makefile.in tclConfig.sh
+ if test ! -d dltest; then mkdir dltest; else true; fi
+ dldir=`cd $(DLTEST_DIR) && pwd`; cd dltest; \
+ if test -f configure; then ./configure; else $$dldir/configure; fi
+
+install: install-binaries install-libraries install-man
+
+# Note: before running ranlib below, must cd to target directory because
+# some ranlibs write to current directory, and this might not always be
+# possible (e.g. if installing as root).
+
+install-binaries: $(TCL_LIB_FILE) tclsh
+ @for i in $(LIB_INSTALL_DIR) $(BIN_INSTALL_DIR) ; \
+ do \
+ if [ ! -d $$i ] ; then \
+ echo "Making directory $$i"; \
+ mkdir $$i; \
+ chmod 755 $$i; \
+ else true; \
+ fi; \
+ done;
+ @echo "Installing $(TCL_LIB_FILE)"
+ @$(INSTALL_DATA) $(TCL_LIB_FILE) $(LIB_INSTALL_DIR)/$(TCL_LIB_FILE)
+ @(cd $(LIB_INSTALL_DIR); $(RANLIB) $(TCL_LIB_FILE))
+ @chmod 555 $(LIB_INSTALL_DIR)/$(TCL_LIB_FILE)
+ @echo "Installing tclsh"
+ @$(INSTALL_PROGRAM) tclsh $(BIN_INSTALL_DIR)/tclsh
+ @echo "Installing tclConfig.sh"
+ @$(INSTALL_DATA) tclConfig.sh $(LIB_INSTALL_DIR)/tclConfig.sh
+
+install-libraries:
+ @for i in $(INSTALL_ROOT)@datadir@ $(INCLUDE_INSTALL_DIR) \
+ $(SCRIPT_INSTALL_DIR) ; \
+ do \
+ if [ ! -d $$i ] ; then \
+ echo "Making directory $$i"; \
+ mkdir $$i; \
+ chmod 755 $$i; \
+ else true; \
+ fi; \
+ done;
+ @for i in http2.0 http1.0 opt0.1; \
+ do \
+ if [ ! -d $(SCRIPT_INSTALL_DIR)/$$i ] ; then \
+ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
+ mkdir $(SCRIPT_INSTALL_DIR)/$$i; \
+ chmod 755 $(SCRIPT_INSTALL_DIR)/$$i; \
+ else true; \
+ fi; \
+ done;
+ @echo "Installing tcl.h"
+ @$(INSTALL_DATA) $(GENERIC_DIR)/tcl.h $(INCLUDE_INSTALL_DIR)/tcl.h
+ @for i in $(TOP_DIR)/library/*.tcl $(TOP_DIR)/library/tclIndex $(UNIX_DIR)/tclAppInit.c $(UNIX_DIR)/ldAix; \
+ do \
+ echo "Installing $$i"; \
+ $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR); \
+ done;
+ @for i in http2.0 http1.0 opt0.1; \
+ do \
+ for j in $(TOP_DIR)/library/$$i/*.tcl ; \
+ do \
+ echo "Installing $$j"; \
+ $(INSTALL_DATA) $$j $(SCRIPT_INSTALL_DIR)/$$i; \
+ done; \
+ done;
+
+# CYGNUS LOCAL: install-minimal target.
+install-minimal:
+ @for i in $(INSTALL_ROOT)@datadir@ $(INCLUDE_INSTALL_DIR) \
+ $(SCRIPT_INSTALL_DIR) ; \
+ do \
+ if [ ! -d $$i ] ; then \
+ echo "Making directory $$i"; \
+ mkdir $$i; \
+ chmod 755 $$i; \
+ else true; \
+ fi; \
+ done;
+ @for i in http2.0 http1.0 opt0.1; \
+ do \
+ if [ ! -d $(SCRIPT_INSTALL_DIR)/$$i ] ; then \
+ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
+ mkdir $(SCRIPT_INSTALL_DIR)/$$i; \
+ chmod 755 $(SCRIPT_INSTALL_DIR)/$$i; \
+ else true; \
+ fi; \
+ done;
+ @for i in $(TOP_DIR)/library/*.tcl $(TOP_DIR)/library/tclIndex $(UNIX_DIR)/ldAix; \
+ do \
+ echo "Installing $$i"; \
+ $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR); \
+ done;
+ @for i in http2.0 http1.0 opt0.1; \
+ do \
+ for j in $(TOP_DIR)/library/$$i/*.tcl ; \
+ do \
+ echo "Installing $$j"; \
+ $(INSTALL_DATA) $$j $(SCRIPT_INSTALL_DIR)/$$i; \
+ done; \
+ done;
+
+install-man:
+ @for i in $(MAN_INSTALL_DIR) $(MAN1_INSTALL_DIR) $(MAN3_INSTALL_DIR) ; \
+ do \
+ if [ ! -d $$i ] ; then \
+ echo "Making directory $$i"; \
+ mkdir $$i; \
+ chmod 755 $$i; \
+ else true; \
+ fi; \
+ done;
+ @cd $(TOP_DIR)/doc; for i in *.1; \
+ do \
+ echo "Installing doc/$$i"; \
+ rm -f $(MAN1_INSTALL_DIR)/$$i; \
+ sed -e '/man\.macros/r man.macros' -e '/man\.macros/d' \
+ $$i > $(MAN1_INSTALL_DIR)/$$i; \
+ chmod 644 $(MAN1_INSTALL_DIR)/$$i; \
+ done;
+ $(UNIX_DIR)/mkLinks $(MAN1_INSTALL_DIR)
+ @cd $(TOP_DIR)/doc; for i in *.3; \
+ do \
+ echo "Installing doc/$$i"; \
+ rm -f $(MAN3_INSTALL_DIR)/$$i; \
+ sed -e '/man\.macros/r man.macros' -e '/man\.macros/d' \
+ $$i > $(MAN3_INSTALL_DIR)/$$i; \
+ chmod 644 $(MAN3_INSTALL_DIR)/$$i; \
+ done;
+ @cd $(TOP_DIR)/doc; for i in *.n; \
+ do \
+ echo "Installing doc/$$i"; \
+ name=`echo $$i | sed -e 's/n$$/3/'`; \
+ rm -f $(MAN3_INSTALL_DIR)/$$name; \
+ sed -e '/man\.macros/r man.macros' -e '/man\.macros/d' \
+ $$i > $(MAN3_INSTALL_DIR)/$$name; \
+ chmod 644 $(MAN3_INSTALL_DIR)/$$name; \
+ done;
+ $(UNIX_DIR)/mkLinks $(MAN3_INSTALL_DIR)
+
+Makefile: $(UNIX_DIR)/Makefile.in config.status
+ $(SHELL) config.status
+
+config.status: $(UNIX_DIR)/configure
+ ./config.status --recheck
+
+mostlyclean: clean
+clean:
+ rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \
+ errors tclsh tcltest lib.exp
+ if test -f dltest/Makefile; then cd dltest; $(MAKE) clean; fi
+
+distclean: clean
+ rm -rf Makefile config.status config.cache config.log tclConfig.sh \
+ SUNWtcl.* prototype
+ if test -f dltest/Makefile; then cd dltest; $(MAKE) distclean; fi
+
+depend:
+ makedepend -- $(DEPEND_SWITCHES) -- $(SRCS)
+
+bp: $(UNIX_DIR)/bp.c
+ $(CC) $(CC_SWITCHES) $(UNIX_DIR)/bp.c -o bp
+
+# Test binaries. The rules for tclTestInit.o and xtTestInit.o are
+# complicated because they are compiled from tclAppInit.c. Can't use
+# the "-o" option because this doesn't work on some strange compilers
+# (e.g. UnixWare).
+
+tclTestInit.o: $(UNIX_DIR)/tclAppInit.c
+ @if test -f tclAppInit.o ; then \
+ rm -f tclAppInit.sav; \
+ mv tclAppInit.o tclAppInit.sav; \
+ fi;
+ $(CC) -c $(CC_SWITCHES) -DTCL_TEST $(UNIX_DIR)/tclAppInit.c
+ rm -f tclTestInit.o
+ mv tclAppInit.o tclTestInit.o
+ @if test -f tclAppInit.sav ; then \
+ mv tclAppInit.sav tclAppInit.o; \
+ fi;
+
+xtTestInit.o: $(UNIX_DIR)/tclAppInit.c
+ @if test -f tclAppInit.o ; then \
+ rm -f tclAppInit.sav; \
+ mv tclAppInit.o tclAppInit.sav; \
+ fi;
+ $(CC) -c $(CC_SWITCHES) -DTCL_TEST -DTCL_XT_TEST \
+ $(UNIX_DIR)/tclAppInit.c
+ rm -f xtTestInit.o
+ mv tclAppInit.o xtTestInit.o
+ @if test -f tclAppInit.sav ; then \
+ mv tclAppInit.sav tclAppInit.o; \
+ fi;
+
+# Object files used on all Unix systems:
+
+panic.o: $(GENERIC_DIR)/panic.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/panic.c
+
+regexp.o: $(GENERIC_DIR)/regexp.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/regexp.c
+
+tclAppInit.o: $(UNIX_DIR)/tclAppInit.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclAppInit.c
+
+tclAsync.o: $(GENERIC_DIR)/tclAsync.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclAsync.c
+
+tclBasic.o: $(GENERIC_DIR)/tclBasic.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclBasic.c
+
+tclBinary.o: $(GENERIC_DIR)/tclBinary.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclBinary.c
+
+tclCkalloc.o: $(GENERIC_DIR)/tclCkalloc.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCkalloc.c
+
+tclClock.o: $(GENERIC_DIR)/tclClock.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclClock.c
+
+tclCmdAH.o: $(GENERIC_DIR)/tclCmdAH.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdAH.c
+
+tclCmdIL.o: $(GENERIC_DIR)/tclCmdIL.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdIL.c
+
+tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdMZ.c
+
+tclDate.o: $(GENERIC_DIR)/tclDate.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclDate.c
+
+tclCompExpr.o: $(GENERIC_DIR)/tclCompExpr.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompExpr.c
+
+tclCompile.o: $(GENERIC_DIR)/tclCompile.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompile.c
+
+tclEnv.o: $(GENERIC_DIR)/tclEnv.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclEnv.c
+
+tclEvent.o: $(GENERIC_DIR)/tclEvent.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclEvent.c
+
+tclExecute.o: $(GENERIC_DIR)/tclExecute.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclExecute.c
+
+tclFCmd.o: $(GENERIC_DIR)/tclFCmd.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclFCmd.c
+
+tclFileName.o: $(GENERIC_DIR)/tclFileName.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclFileName.c
+
+tclGet.o: $(GENERIC_DIR)/tclGet.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclGet.c
+
+tclHash.o: $(GENERIC_DIR)/tclHash.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclHash.c
+
+tclHistory.o: $(GENERIC_DIR)/tclHistory.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclHistory.c
+
+tclIndexObj.o: $(GENERIC_DIR)/tclIndexObj.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclIndexObj.c
+
+tclInterp.o: $(GENERIC_DIR)/tclInterp.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclInterp.c
+
+tclIO.o: $(GENERIC_DIR)/tclIO.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclIO.c
+
+tclIOCmd.o: $(GENERIC_DIR)/tclIOCmd.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclIOCmd.c
+
+tclIOSock.o: $(GENERIC_DIR)/tclIOSock.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclIOSock.c
+
+tclIOUtil.o: $(GENERIC_DIR)/tclIOUtil.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclIOUtil.c
+
+tclLink.o: $(GENERIC_DIR)/tclLink.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLink.c
+
+tclListObj.o: $(GENERIC_DIR)/tclListObj.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclListObj.c
+
+tclObj.o: $(GENERIC_DIR)/tclObj.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclObj.c
+
+tclLoad.o: $(GENERIC_DIR)/tclLoad.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLoad.c
+
+tclLoadAix.o: $(UNIX_DIR)/tclLoadAix.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadAix.c
+
+tclLoadAout.o: $(UNIX_DIR)/tclLoadAout.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadAout.c
+
+tclLoadDl.o: $(UNIX_DIR)/tclLoadDl.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDl.c
+
+tclLoadDl2.o: $(UNIX_DIR)/tclLoadDl2.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDl2.c
+
+tclLoadDld.o: $(UNIX_DIR)/tclLoadDld.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDld.c
+
+tclLoadNone.o: $(GENERIC_DIR)/tclLoadNone.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLoadNone.c
+
+tclLoadOSF.o: $(UNIX_DIR)/tclLoadOSF.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadOSF.c
+
+tclLoadShl.o: $(UNIX_DIR)/tclLoadShl.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadShl.c
+
+tclMain.o: $(GENERIC_DIR)/tclMain.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclMain.c
+
+tclMtherr.o: $(UNIX_DIR)/tclMtherr.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclMtherr.c
+
+tclNamesp.o: $(GENERIC_DIR)/tclNamesp.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclNamesp.c
+
+tclNotify.o: $(GENERIC_DIR)/tclNotify.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclNotify.c
+
+tclParse.o: $(GENERIC_DIR)/tclParse.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclParse.c
+
+tclPipe.o: $(GENERIC_DIR)/tclPipe.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPipe.c
+
+tclPkg.o: $(GENERIC_DIR)/tclPkg.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPkg.c
+
+tclPosixStr.o: $(GENERIC_DIR)/tclPosixStr.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPosixStr.c
+
+tclPreserve.o: $(GENERIC_DIR)/tclPreserve.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPreserve.c
+
+tclProc.o: $(GENERIC_DIR)/tclProc.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclProc.c
+
+tclResolve.o: $(GENERIC_DIR)/tclResolve.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclResolve.c
+
+tclStringObj.o: $(GENERIC_DIR)/tclStringObj.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclStringObj.c
+
+tclUtil.o: $(GENERIC_DIR)/tclUtil.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclUtil.c
+
+tclVar.o: $(GENERIC_DIR)/tclVar.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclVar.c
+
+tclTest.o: $(GENERIC_DIR)/tclTest.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTest.c
+
+tclTestObj.o: $(GENERIC_DIR)/tclTestObj.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTestObj.c
+
+tclTestProcBodyObj.o: $(GENERIC_DIR)/tclTestProcBodyObj.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTestProcBodyObj.c
+
+tclTimer.o: $(GENERIC_DIR)/tclTimer.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTimer.c
+
+tclUnixChan.o: $(UNIX_DIR)/tclUnixChan.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixChan.c
+
+tclUnixEvent.o: $(UNIX_DIR)/tclUnixEvent.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixEvent.c
+
+tclUnixFCmd.o: $(UNIX_DIR)/tclUnixFCmd.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixFCmd.c
+
+tclUnixFile.o: $(UNIX_DIR)/tclUnixFile.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixFile.c
+
+tclUnixNotfy.o: $(UNIX_DIR)/tclUnixNotfy.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixNotfy.c
+
+tclUnixPipe.o: $(UNIX_DIR)/tclUnixPipe.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixPipe.c
+
+tclUnixSock.o: $(UNIX_DIR)/tclUnixSock.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixSock.c
+
+tclUnixTest.o: $(UNIX_DIR)/tclUnixTest.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixTest.c
+
+tclUnixTime.o: $(UNIX_DIR)/tclUnixTime.c
+ $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixTime.c
+
+tclUnixInit.o: $(UNIX_DIR)/tclUnixInit.c tclConfig.sh
+ $(CC) -c $(CC_SWITCHES) -DTCL_LIBRARY=\"${TCL_LIBRARY}\" \
+ -DTCL_PACKAGE_PATH="\"${TCL_PACKAGE_PATH}\"" \
+ $(UNIX_DIR)/tclUnixInit.c
+
+# compat binaries
+
+fixstrtod.o: $(COMPAT_DIR)/fixstrtod.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/fixstrtod.c
+
+getcwd.o: $(COMPAT_DIR)/getcwd.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/getcwd.c
+
+opendir.o: $(COMPAT_DIR)/opendir.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/opendir.c
+
+strncasecmp.o: $(COMPAT_DIR)/strncasecmp.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strncasecmp.c
+
+strstr.o: $(COMPAT_DIR)/strstr.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strstr.c
+
+strtod.o: $(COMPAT_DIR)/strtod.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strtod.c
+
+strtol.o: $(COMPAT_DIR)/strtol.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strtol.c
+
+strtoul.o: $(COMPAT_DIR)/strtoul.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strtoul.c
+
+tmpnam.o: $(COMPAT_DIR)/tmpnam.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/tmpnam.c
+
+waitpid.o: $(COMPAT_DIR)/waitpid.c
+ $(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/waitpid.c
+
+.c.o:
+ $(CC) -c $(CC_SWITCHES) $<
+
+#
+# Target to check for proper usage of UCHAR macro.
+#
+
+checkuchar:
+ -egrep isalnum\|isalpha\|iscntrl\|isdigit\|islower\|isprint\|ispunct\|isspace\|isupper\|isxdigit\|toupper\|tolower $(SRCS) | grep -v UCHAR
+
+#
+# Target to make sure that only symbols with "Tcl" prefixes are
+# exported.
+#
+
+checkexports: $(TCL_LIB_FILE)
+ -nm -p $(TCL_LIB_FILE) | awk '$$2 ~ /[TDB]/ { print $$3 }' | sort -n | grep -v '^[Tt]cl'
+
+#
+# Target to create a proper Tcl distribution from information in the
+# master source directory. DISTDIR must be defined to indicate where
+# to put the distribution.
+#
+
+DISTNAME = tcl@TCL_VERSION@@TCL_PATCH_LEVEL@
+ZIPNAME = tcl@TCL_MAJOR_VERSION@@TCL_MINOR_VERSION@@TCL_PATCH_LEVEL@.zip
+DISTDIR = $(DISTROOT)/$(DISTNAME)
+#$(UNIX_DIR)/configure: $(UNIX_DIR)/configure.in
+# autoconf $(UNIX_DIR)/configure.in > $(UNIX_DIR)/configure
+dist: $(UNIX_DIR)/configure
+ rm -rf $(DISTDIR)
+ mkdir $(DISTDIR)
+ mkdir $(DISTDIR)/unix
+ cp -p $(UNIX_DIR)/*.c $(UNIX_DIR)/*.h $(DISTDIR)/unix
+ rm -f $(DISTDIR)/unix/bp.c
+ cp $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
+ chmod 664 $(DISTDIR)/unix/Makefile.in
+ cp $(UNIX_DIR)/configure $(UNIX_DIR)/configure.in \
+ $(UNIX_DIR)/tclConfig.sh.in $(UNIX_DIR)/install-sh \
+ $(UNIX_DIR)/porting.notes $(UNIX_DIR)/porting.old \
+ $(UNIX_DIR)/README $(UNIX_DIR)/ldAix \
+ $(DISTDIR)/unix
+ chmod 775 $(DISTDIR)/unix/configure $(DISTDIR)/unix/configure.in
+ chmod 775 $(DISTDIR)/unix/ldAix
+ chmod +x $(DISTDIR)/unix/install-sh
+ tclsh $(UNIX_DIR)/mkLinks.tcl \
+ $(UNIX_DIR)/../doc/*.[13n] > $(DISTDIR)/unix/mkLinks
+ chmod +x $(DISTDIR)/unix/mkLinks
+ mkdir $(DISTDIR)/generic
+ cp -p $(GENERIC_DIR)/*.c $(GENERIC_DIR)/*.h $(DISTDIR)/generic
+ cp -p $(GENERIC_DIR)/README $(DISTDIR)/generic
+ cp -p $(GENERIC_DIR)/tclGetDate.y $(DISTDIR)/generic
+ cp -p $(TOP_DIR)/changes $(TOP_DIR)/README* $(TOP_DIR)/license.terms \
+ $(DISTDIR)
+ mkdir $(DISTDIR)/library
+ cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/library/*.tcl \
+ $(TOP_DIR)/library/tclIndex $(DISTDIR)/library
+ for i in http2.0 http1.0 opt0.1; \
+ do \
+ mkdir $(DISTDIR)/library/$$i ;\
+ cp -p $(TOP_DIR)/library/$$i/*.tcl $(DISTDIR)/library/$$i; \
+ done;
+ mkdir $(DISTDIR)/doc
+ cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
+ $(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
+ mkdir $(DISTDIR)/compat
+ cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/compat/*.c \
+ $(TOP_DIR)/compat/*.h $(TOP_DIR)/compat/README \
+ $(DISTDIR)/compat
+ mkdir $(DISTDIR)/tests
+ cp -p $(TOP_DIR)/license.terms $(DISTDIR)/tests
+ cp -p $(TOP_DIR)/tests/*.test $(TOP_DIR)/tests/README \
+ $(TOP_DIR)/tests/all $(TOP_DIR)/tests/*.tcl \
+ $(TOP_DIR)/tests/defs $(DISTDIR)/tests
+ mkdir $(DISTDIR)/win
+ cp -p $(TOP_DIR)/win/*.c $(TOP_DIR)/win/*.h $(TOP_DIR)/win/*.rc \
+ $(DISTDIR)/win
+ cp -p $(TOP_DIR)/win/*.bat $(DISTDIR)/win
+ cp -p $(TOP_DIR)/win/makefile.* $(DISTDIR)/win
+ cp -p $(TOP_DIR)/win/README $(DISTDIR)/win
+ cp -p $(TOP_DIR)/win/pkgIndex.tcl $(DISTDIR)/win
+ cp -p $(TOP_DIR)/license.terms $(DISTDIR)/win
+ mkdir $(DISTDIR)/mac
+ sccs edit -s $(TOP_DIR)/mac/tclMacProjects.sea.hqx
+ cp -p tclMacProjects.sea.hqx $(DISTDIR)/mac
+ sccs unedit $(TOP_DIR)/mac/tclMacProjects.sea.hqx
+ rm -f tclMacProjects.sea.hqx
+ cp -p $(TOP_DIR)/mac/*.c $(TOP_DIR)/mac/*.h $(TOP_DIR)/mac/*.r \
+ $(DISTDIR)/mac
+ cp -p $(TOP_DIR)/mac/porting.notes $(TOP_DIR)/mac/README $(DISTDIR)/mac
+ cp -p $(TOP_DIR)/mac/*.exp $(TOP_DIR)/mac/*.pch $(DISTDIR)/mac
+ cp -p $(TOP_DIR)/mac/*.doc $(DISTDIR)/mac
+ cp -p $(TOP_DIR)/mac/*.html $(DISTDIR)/mac
+ cp -p $(TOP_DIR)/license.terms $(DISTDIR)/mac
+ mkdir $(DISTDIR)/unix/dltest
+ cp -p $(UNIX_DIR)/dltest/*.c $(UNIX_DIR)/dltest/Makefile.in \
+ $(DISTDIR)/unix/dltest
+ cp -p $(UNIX_DIR)/dltest/configure.in $(UNIX_DIR)/dltest/configure \
+ $(UNIX_DIR)/dltest/README $(DISTDIR)/unix/dltest
+
+#
+# The following target can only be used for non-patch releases. Use
+# the "allpatch" target below for patch releases.
+#
+
+alldist: dist
+ rm -f /proj/tcl/dist/$(DISTNAME).tar.Z \
+ /proj/tcl/dist/$(DISTNAME).tar.gz \
+ /proj/tcl/dist/$(ZIPNAME)
+ cd /proj/tcl/dist; tar cf $(DISTNAME).tar $(DISTNAME); \
+ gzip -9 -c $(DISTNAME).tar > $(DISTNAME).tar.gz; \
+ compress $(DISTNAME).tar; zip -r8 $(ZIPNAME) $(DISTNAME)
+
+#
+# The target below is similar to "alldist" except it works for patch
+# releases. It is needed because patch releases are peculiar: the
+# patch designation appears in the name of the compressed file
+# (e.g. tcl8.0p1.tar.gz) but the extracted source directory doesn't
+# include the patch designation (e.g. tcl8.0).
+#
+
+allpatch: dist
+ rm -f $(DISTROOT)/$(DISTNAME).tar.Z \
+ $(DISTROOT)/$(DISTNAME).tar.gz \
+ $(DISTROOT)/$(ZIPNAME)
+ mv $(DISTROOT)/tcl${VERSION} $(DISTROOT)/old
+ mv $(DISTROOT)/$(DISTNAME) $(DISTROOT)/tcl${VERSION}
+ cd $(DISTROOT); tar cf $(DISTNAME).tar tcl${VERSION}; \
+ gzip -9 -c $(DISTNAME).tar > $(DISTNAME).tar.gz; \
+ compress $(DISTNAME).tar; zip -r8 $(ZIPNAME) tcl${VERSION}
+ mv $(DISTROOT)/tcl${VERSION} $(DISTROOT)/$(DISTNAME)
+ mv $(DISTROOT)/old $(DISTROOT)/tcl${VERSION}
+
+#
+# Target to create a Macintosh version of the distribution. This will
+# do a normal distribution and then massage the output to prepare it
+# for moving to the Mac platform. This requires a few scripts and
+# programs found only in the Tcl group's tool workspace.
+#
+
+macdist: dist
+ rm -f $(DISTDIR)/mac/tclMacProjects.sea.hqx
+ tclsh $(TOOL_DIR)/man2html.tcl $(DISTDIR)/tmp ../.. tcl$(VERSION)
+ mv $(DISTDIR)/tmp/tcl$(VERSION) $(DISTDIR)/html
+ rm -rf $(DISTDIR)/doc
+ rm -rf $(DISTDIR)/tmp
+ tclsh $(TOOL_DIR)/cvtEOL.tcl $(DISTDIR)
+
+#
+# Targets to build Solaris package of the distribution for the current
+# architecture. To build stream packages for both sun4 and i86pc
+# architectures:
+#
+# On the sun4 machine, execute the following:
+# make distclean; ./configure
+# make DISTDIR=<distdir> package
+#
+# Once the build is complete, execute the following on the i86pc
+# machine:
+# make DISTDIR=<distdir> package-quick
+#
+# <distdir> is the absolute path to a directory where the build should
+# take place. These steps will generate the $(PACKAGE).sun4 and
+# $(PACKAGE).i86pc stream packages. It is important that the packages be
+# built in this fashion in order to ensure that the architecture
+# independent files are exactly the same, including timestamps, in
+# both packages.
+#
+
+PACKAGE=SCRPtcl
+
+package: dist package-config package-common package-binaries package-generate
+package-quick: package-config package-binaries package-generate
+
+#
+# Configure for the current architecture in the dist directory.
+#
+package-config:
+ mkdir -p $(DISTDIR)/unix/`arch`
+ cd $(DISTDIR)/unix/`arch`; \
+ ../configure --prefix=/opt/$(PACKAGE)/$(VERSION) \
+ --exec_prefix=/opt/$(PACKAGE)/$(VERSION)/`arch` \
+ --enable-shared
+ mkdir -p $(DISTDIR)/$(PACKAGE)/$(VERSION)
+ mkdir -p $(DISTDIR)/$(PACKAGE)/$(VERSION)/`arch`
+
+#
+# Build and install the architecture independent files in the dist directory.
+#
+
+package-common:
+ cd $(DISTDIR)/unix/`arch`;\
+ $(MAKE); \
+ $(MAKE) prefix=$(DISTDIR)/$(PACKAGE)/$(VERSION) \
+ exec_prefix=$(DISTDIR)/$(PACKAGE)/$(VERSION)/`arch` \
+ install-libraries install-man
+ mkdir -p $(DISTDIR)/$(PACKAGE)/$(VERSION)/bin
+ sed -e "s/TCLVERSION/$(VERSION)/g" < $(UNIX_DIR)/tclsh.sh \
+ > $(DISTDIR)/$(PACKAGE)/$(VERSION)/bin/tclsh$(VERSION)
+ chmod 755 $(DISTDIR)/$(PACKAGE)/$(VERSION)/bin/tclsh$(VERSION)
+
+#
+# Build and install the architecture specific files in the dist directory.
+#
+
+package-binaries:
+ cd $(DISTDIR)/unix/`arch`; \
+ $(MAKE); \
+ $(MAKE) install-binaries prefix=$(DISTDIR)/$(PACKAGE)/$(VERSION) \
+ exec_prefix=$(DISTDIR)/$(PACKAGE)/$(VERSION)/`arch`
+
+#
+# Generate a package from the installed files in the dist directory for the
+# current architecture.
+#
+
+package-generate:
+ pkgproto $(DISTDIR)/$(PACKAGE)/$(VERSION)/bin=bin \
+ $(DISTDIR)/$(PACKAGE)/$(VERSION)/include=include \
+ $(DISTDIR)/$(PACKAGE)/$(VERSION)/lib=lib \
+ $(DISTDIR)/$(PACKAGE)/$(VERSION)/man=man \
+ $(DISTDIR)/$(PACKAGE)/$(VERSION)/`arch`=`arch` \
+ | tclsh $(UNIX_DIR)/mkProto.tcl \
+ $(VERSION) $(UNIX_DIR) > prototype
+ pkgmk -o -d . -f prototype -a `arch`
+ pkgtrans -s . $(PACKAGE).`arch` $(PACKAGE)
+ rm -rf $(PACKAGE)
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/tcl/cygwin/configure b/tcl/cygwin/configure
new file mode 100755
index 00000000000..544655afcdf
--- /dev/null
+++ b/tcl/cygwin/configure
@@ -0,0 +1,5574 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --disable-load disallow dynamic loading and "load" command"
+ac_help="$ac_help
+ --enable-shared build libtcl as a shared library"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=../generic/tcl.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+# SCCS: @(#) configure.in 1.18 98/08/12 17:29:39
+
+TCL_VERSION=8.0
+TCL_MAJOR_VERSION=8
+TCL_MINOR_VERSION=0
+TCL_PATCH_LEVEL=".3"
+VERSION=${TCL_VERSION}
+
+if test "${prefix}" = "NONE"; then
+ prefix=/usr/local
+fi
+if test "${exec_prefix}" = "NONE"; then
+ exec_prefix=$prefix
+fi
+TCL_SRC_DIR=`cd $srcdir/..; pwd`
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:548: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:578: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:608: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:659: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:691: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 702 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:707: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:733: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:738: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:747: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:766: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+
+# CYGNUS LOCAL
+# dje/win32
+AR=${AR-ar}
+# We need this for substitutions in Makefile.in.
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# 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"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:833: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+# END CYGNUS LOCAL
+
+#--------------------------------------------------------------------
+# CYGNUS LOCAL:
+# This is for LynxOS, which needs a flag to force true POSIX when
+# building. It's weirder than that, cause the flag varies depending
+# how old the compiler is. So...
+# -X is for the old "cc" and "gcc" (based on 1.42)
+# -mposix is for the new gcc (at least 2.5.8)
+# This modifies the value of $CC to have the POSIX flag added
+# so everything will configure correctly.
+#--------------------------------------------------------------------
+CY_AC_TCL_LYNX_POSIX
+
+# set the warning flags depending on whether or not we are using gcc
+if test "${GCC}" = "yes" ; then
+ CFLAGS_WARNING="-Wall -Wconversion"
+else
+ CFLAGS_WARNING=""
+fi
+
+#--------------------------------------------------------------------
+# Supply substitutes for missing POSIX library procedures, or
+# set flags so Tcl uses alternate procedures.
+#--------------------------------------------------------------------
+
+# Check if Posix compliant getcwd exists, if not we'll use getwd.
+for ac_func in getcwd
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:915: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 920 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:943: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define USEGETWD 1
+EOF
+
+fi
+done
+
+# Nb: if getcwd uses popen and pwd(1) (like SunOS 4) we should really
+# define USEGETWD even if the posix getcwd exists. Add a test ?
+
+for ac_func in opendir strstr
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:977: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 982 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}"
+fi
+done
+
+
+
+for ac_func in strtol tmpnam waitpid
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1035: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1040 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1063: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}"
+fi
+done
+
+
+echo $ac_n "checking for strerror""... $ac_c" 1>&6
+echo "configure:1090: checking for strerror" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strerror'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1095 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strerror(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strerror();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strerror) || defined (__stub___strerror)
+choke me
+#else
+strerror();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1118: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strerror=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strerror=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strerror`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_STRERROR 1
+EOF
+
+fi
+
+echo $ac_n "checking for getwd""... $ac_c" 1>&6
+echo "configure:1142: checking for getwd" >&5
+if eval "test \"`echo '$''{'ac_cv_func_getwd'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1147 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getwd(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getwd();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_getwd) || defined (__stub___getwd)
+choke me
+#else
+getwd();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_getwd=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_getwd=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'getwd`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_GETWD 1
+EOF
+
+fi
+
+echo $ac_n "checking for wait3""... $ac_c" 1>&6
+echo "configure:1194: checking for wait3" >&5
+if eval "test \"`echo '$''{'ac_cv_func_wait3'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1199 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char wait3(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char wait3();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_wait3) || defined (__stub___wait3)
+choke me
+#else
+wait3();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1222: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_wait3=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_wait3=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'wait3`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_WAIT3 1
+EOF
+
+fi
+
+echo $ac_n "checking for uname""... $ac_c" 1>&6
+echo "configure:1246: checking for uname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_uname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1251 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char uname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char uname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_uname) || defined (__stub___uname)
+choke me
+#else
+uname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_uname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_uname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'uname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_UNAME 1
+EOF
+
+fi
+
+
+#--------------------------------------------------------------------
+# On a few very rare systems, all of the libm.a stuff is
+# already in libc.a. Set compiler flags accordingly.
+# Also, Linux requires the "ieee" library for math to work
+# right (and it must appear before "-lm").
+#--------------------------------------------------------------------
+
+echo $ac_n "checking for sin""... $ac_c" 1>&6
+echo "configure:1306: checking for sin" >&5
+if eval "test \"`echo '$''{'ac_cv_func_sin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1311 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char sin(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char sin();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_sin) || defined (__stub___sin)
+choke me
+#else
+sin();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_sin=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_sin=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'sin`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ MATH_LIBS=""
+else
+ echo "$ac_t""no" 1>&6
+MATH_LIBS="-lm"
+fi
+
+echo $ac_n "checking for main in -lieee""... $ac_c" 1>&6
+echo "configure:1355: checking for main in -lieee" >&5
+ac_lib_var=`echo ieee'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lieee $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1363 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:1370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ MATH_LIBS="-lieee $MATH_LIBS"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+#--------------------------------------------------------------------
+# On AIX systems, libbsd.a has to be linked in to support
+# non-blocking file IO. This library has to be linked in after
+# the MATH_LIBS or it breaks the pow() function. The way to
+# insure proper sequencing, is to add it to the tail of MATH_LIBS.
+# This library also supplies gettimeofday.
+#--------------------------------------------------------------------
+libbsd=no
+if test "`uname -s`" = "AIX" ; then
+ echo $ac_n "checking for gettimeofday in -lbsd""... $ac_c" 1>&6
+echo "configure:1401: checking for gettimeofday in -lbsd" >&5
+ac_lib_var=`echo bsd'_'gettimeofday | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lbsd $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1409 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gettimeofday();
+
+int main() {
+gettimeofday()
+; return 0; }
+EOF
+if { (eval echo configure:1420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ libbsd=yes
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $libbsd = yes; then
+ MATH_LIBS="$MATH_LIBS -lbsd"
+ fi
+fi
+
+#--------------------------------------------------------------------
+# Supply substitutes for missing POSIX header files. Special
+# notes:
+# - stdlib.h doesn't define strtol, strtoul, or
+# strtod insome versions of SunOS
+# - some versions of string.h don't declare procedures such
+# as strstr
+#--------------------------------------------------------------------
+
+echo $ac_n "checking dirent.h""... $ac_c" 1>&6
+echo "configure:1455: checking dirent.h" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1457 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <dirent.h>
+int main() {
+
+#ifndef _POSIX_SOURCE
+# ifdef __Lynx__
+ /*
+ * Generate compilation error to make the test fail: Lynx headers
+ * are only valid if really in the POSIX environment.
+ */
+
+ missing_procedure();
+# endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+
+; return 0; }
+EOF
+if { (eval echo configure:1483: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ tcl_ok=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_ok=no
+fi
+rm -f conftest*
+if test $tcl_ok = no; then
+ cat >> confdefs.h <<\EOF
+#define NO_DIRENT_H 1
+EOF
+
+fi
+echo "$ac_t""$tcl_ok" 1>&6
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1501: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1516 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1522: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1533 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1539: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1550 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1556: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+ac_safe=`echo "errno.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for errno.h""... $ac_c" 1>&6
+echo "configure:1582: checking for errno.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1587 "configure"
+#include "confdefs.h"
+#include <errno.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1592: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_ERRNO_H 1
+EOF
+
+fi
+
+ac_safe=`echo "float.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for float.h""... $ac_c" 1>&6
+echo "configure:1619: checking for float.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1624 "configure"
+#include "confdefs.h"
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1629: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_FLOAT_H 1
+EOF
+
+fi
+
+ac_safe=`echo "values.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for values.h""... $ac_c" 1>&6
+echo "configure:1656: checking for values.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1661 "configure"
+#include "confdefs.h"
+#include <values.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1666: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_VALUES_H 1
+EOF
+
+fi
+
+ac_safe=`echo "limits.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for limits.h""... $ac_c" 1>&6
+echo "configure:1693: checking for limits.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1698 "configure"
+#include "confdefs.h"
+#include <limits.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1703: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_LIMITS_H 1
+EOF
+
+fi
+
+ac_safe=`echo "stdlib.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6
+echo "configure:1730: checking for stdlib.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1735 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1740: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_ok=1
+else
+ echo "$ac_t""no" 1>&6
+tcl_ok=0
+fi
+
+cat > conftest.$ac_ext <<EOF
+#line 1763 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "strtol" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ tcl_ok=0
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 1777 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "strtoul" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ tcl_ok=0
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 1791 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "strtod" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ tcl_ok=0
+fi
+rm -f conftest*
+
+if test $tcl_ok = 0; then
+ cat >> confdefs.h <<\EOF
+#define NO_STDLIB_H 1
+EOF
+
+fi
+ac_safe=`echo "string.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for string.h""... $ac_c" 1>&6
+echo "configure:1812: checking for string.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1817 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1822: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_ok=1
+else
+ echo "$ac_t""no" 1>&6
+tcl_ok=0
+fi
+
+cat > conftest.$ac_ext <<EOF
+#line 1845 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "strstr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ tcl_ok=0
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 1859 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "strerror" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ tcl_ok=0
+fi
+rm -f conftest*
+
+if test $tcl_ok = 0; then
+ cat >> confdefs.h <<\EOF
+#define NO_STRING_H 1
+EOF
+
+fi
+ac_safe=`echo "sys/wait.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/wait.h""... $ac_c" 1>&6
+echo "configure:1880: checking for sys/wait.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1885 "configure"
+#include "confdefs.h"
+#include <sys/wait.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1890: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_SYS_WAIT_H 1
+EOF
+
+fi
+
+ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6
+echo "configure:1917: checking for dlfcn.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1922 "configure"
+#include "confdefs.h"
+#include <dlfcn.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1927: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_DLFCN_H 1
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1956: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1961 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1966: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+#---------------------------------------------------------------------------
+# Determine which interface to use to talk to the serial port.
+# Note that #include lines must begin in leftmost column for
+# some compilers to recognize them as preprocessor directives.
+#---------------------------------------------------------------------------
+
+echo $ac_n "checking termios vs. termio vs. sgtty""... $ac_c" 1>&6
+echo "configure:2000: checking termios vs. termio vs. sgtty" >&5
+if test "$cross_compiling" = yes; then
+ tk_ok=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2005 "configure"
+#include "confdefs.h"
+
+#include <termios.h>
+
+main()
+{
+ struct termios t;
+ if (tcgetattr(0, &t) == 0) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}
+EOF
+if { (eval echo configure:2021: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ tk_ok=termios
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tk_ok=no
+fi
+rm -fr conftest*
+fi
+
+if test $tk_ok = termios; then
+ cat >> confdefs.h <<\EOF
+#define USE_TERMIOS 1
+EOF
+
+else
+if test "$cross_compiling" = yes; then
+ tk_ok=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2043 "configure"
+#include "confdefs.h"
+
+#include <termio.h>
+
+main()
+{
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}
+EOF
+if { (eval echo configure:2058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ tk_ok=termio
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tk_ok=no
+fi
+rm -fr conftest*
+fi
+
+if test $tk_ok = termio; then
+ cat >> confdefs.h <<\EOF
+#define USE_TERMIO 1
+EOF
+
+else
+if test "$cross_compiling" = yes; then
+ tk_ok=none
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2080 "configure"
+#include "confdefs.h"
+
+#include <sgtty.h>
+
+main()
+{
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}
+EOF
+if { (eval echo configure:2096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ tk_ok=sgtty
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tk_ok=none
+fi
+rm -fr conftest*
+fi
+
+if test $tk_ok = sgtty; then
+ cat >> confdefs.h <<\EOF
+#define USE_SGTTY 1
+EOF
+
+fi
+fi
+fi
+echo "$ac_t""$tk_ok" 1>&6
+
+#--------------------------------------------------------------------
+# Include sys/select.h if it exists and if it supplies things
+# that appear to be useful and aren't already in sys/types.h.
+# This appears to be true only on the RS/6000 under AIX. Some
+# systems like OSF/1 have a sys/select.h that's of no use, and
+# other systems like SCO UNIX have a sys/select.h that's
+# pernicious. If "fd_set" isn't defined anywhere then set a
+# special flag.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking fd_set and sys/select""... $ac_c" 1>&6
+echo "configure:2129: checking fd_set and sys/select" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2131 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+fd_set readMask, writeMask;
+; return 0; }
+EOF
+if { (eval echo configure:2138: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ tk_ok=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tk_ok=no
+fi
+rm -f conftest*
+if test $tk_ok = no; then
+ cat > conftest.$ac_ext <<EOF
+#line 2150 "configure"
+#include "confdefs.h"
+#include <sys/select.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "fd_mask" >/dev/null 2>&1; then
+ rm -rf conftest*
+ tk_ok=yes
+fi
+rm -f conftest*
+
+ if test $tk_ok = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_SELECT_H 1
+EOF
+
+ fi
+fi
+echo "$ac_t""$tk_ok" 1>&6
+if test $tk_ok = no; then
+ cat >> confdefs.h <<\EOF
+#define NO_FD_SET 1
+EOF
+
+fi
+
+#------------------------------------------------------------------------------
+# Find out all about time handling differences.
+#------------------------------------------------------------------------------
+
+for ac_hdr in sys/time.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2184: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2189 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2194: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:2221: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2226 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:2235: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:2256: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2261 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:2269: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm=time.h
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+ cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6
+echo "configure:2290: checking for tm_zone in struct tm" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2295 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_cv_struct_tm>
+int main() {
+struct tm tm; tm.tm_zone;
+; return 0; }
+EOF
+if { (eval echo configure:2303: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm_zone=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm_zone=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm_zone" 1>&6
+if test "$ac_cv_struct_tm_zone" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TM_ZONE 1
+EOF
+
+else
+ echo $ac_n "checking for tzname""... $ac_c" 1>&6
+echo "configure:2323: checking for tzname" >&5
+if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2328 "configure"
+#include "confdefs.h"
+#include <time.h>
+#ifndef tzname /* For SGI. */
+extern char *tzname[]; /* RS6000 and others reject char **tzname. */
+#endif
+int main() {
+atoi(*tzname);
+; return 0; }
+EOF
+if { (eval echo configure:2338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_var_tzname=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_var_tzname=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_var_tzname" 1>&6
+ if test $ac_cv_var_tzname = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TZNAME 1
+EOF
+
+ fi
+fi
+
+
+echo $ac_n "checking tm_tzadj in struct tm""... $ac_c" 1>&6
+echo "configure:2361: checking tm_tzadj in struct tm" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2363 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+struct tm tm; tm.tm_tzadj;
+; return 0; }
+EOF
+if { (eval echo configure:2370: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define HAVE_TM_TZADJ 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
+echo $ac_n "checking tm_gmtoff in struct tm""... $ac_c" 1>&6
+echo "configure:2386: checking tm_gmtoff in struct tm" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2388 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+struct tm tm; tm.tm_gmtoff;
+; return 0; }
+EOF
+if { (eval echo configure:2395: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define HAVE_TM_GMTOFF 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
+#
+# Its important to include time.h in this check, as some systems (like convex)
+# have timezone functions, etc.
+#
+have_timezone=no
+echo $ac_n "checking long timezone variable""... $ac_c" 1>&6
+echo "configure:2416: checking long timezone variable" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2418 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+extern long timezone;
+ timezone += 1;
+ exit (0);
+; return 0; }
+EOF
+if { (eval echo configure:2427: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ have_timezone=yes
+ cat >> confdefs.h <<\EOF
+#define HAVE_TIMEZONE_VAR 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
+#
+# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+#
+if test "$have_timezone" = no; then
+ echo $ac_n "checking time_t timezone variable""... $ac_c" 1>&6
+echo "configure:2448: checking time_t timezone variable" >&5
+ cat > conftest.$ac_ext <<EOF
+#line 2450 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+extern time_t timezone;
+ timezone += 1;
+ exit (0);
+; return 0; }
+EOF
+if { (eval echo configure:2459: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ have_timezone=yes
+ cat >> confdefs.h <<\EOF
+#define HAVE_TIMEZONE_VAR 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+fi
+
+#
+# On some systems (eg Solaris 2.5.1, timezone is not declared in
+# time.h unless you jump through hoops. Instead of that, we just
+# declare it ourselves when necessary.
+#
+if test "$have_timezone" = yes; then
+ echo $ac_n "checking for timezone declaration""... $ac_c" 1>&6
+echo "configure:2483: checking for timezone declaration" >&5
+
+ tzrx='^[ ]*extern.*timezone'
+
+ cat > conftest.$ac_ext <<EOF
+#line 2488 "configure"
+#include "confdefs.h"
+#include <time.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$tzrx" >/dev/null 2>&1; then
+ rm -rf conftest*
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_TIMEZONE_DECL 1
+EOF
+
+ echo "$ac_t""found" 1>&6
+else
+ rm -rf conftest*
+ echo "$ac_t""missing" 1>&6
+fi
+rm -f conftest*
+
+fi
+
+#
+# AIX does not have a timezone field in struct tm. When the AIX bsd
+# library is used, the timezone global and the gettimeofday methods are
+# to be avoided for timezone deduction instead, we deduce the timezone
+# by comparing the localtime result on a known GMT value.
+#
+if test $libbsd = yes; then
+ cat >> confdefs.h <<\EOF
+#define USE_DELTA_FOR_TZ 1
+EOF
+
+fi
+
+#--------------------------------------------------------------------
+# Some systems (e.g., IRIX 4.0.5) lack the st_blksize field
+# in struct stat.
+#--------------------------------------------------------------------
+echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6
+echo "configure:2527: checking for st_blksize in struct stat" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2532 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+int main() {
+struct stat s; s.st_blksize;
+; return 0; }
+EOF
+if { (eval echo configure:2540: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_st_blksize=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_st_blksize=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_st_blksize" 1>&6
+if test $ac_cv_struct_st_blksize = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ST_BLKSIZE 1
+EOF
+
+fi
+
+
+#--------------------------------------------------------------------
+# On some systems strstr is broken: it returns a pointer even
+# even if the original string is empty.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking proper strstr implementation""... $ac_c" 1>&6
+echo "configure:2567: checking proper strstr implementation" >&5
+if test "$cross_compiling" = yes; then
+ tcl_ok=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2572 "configure"
+#include "confdefs.h"
+
+extern int strstr();
+int main()
+{
+ exit(strstr("\0test", "test") ? 1 : 0);
+}
+
+EOF
+if { (eval echo configure:2582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ tcl_ok=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tcl_ok=no
+fi
+rm -fr conftest*
+fi
+
+if test $tcl_ok = yes; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""broken, using substitute" 1>&6
+ LIBOBJS="$LIBOBJS strstr.o"
+fi
+
+#--------------------------------------------------------------------
+# Check for strtoul function. This is tricky because under some
+# versions of AIX strtoul returns an incorrect terminator
+# pointer for the string "0".
+#--------------------------------------------------------------------
+
+echo $ac_n "checking for strtoul""... $ac_c" 1>&6
+echo "configure:2608: checking for strtoul" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strtoul'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2613 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strtoul(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strtoul();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strtoul) || defined (__stub___strtoul)
+choke me
+#else
+strtoul();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2636: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strtoul=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strtoul=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strtoul`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_ok=1
+else
+ echo "$ac_t""no" 1>&6
+tcl_ok=0
+fi
+
+if test "$cross_compiling" = yes; then
+ tcl_ok=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2660 "configure"
+#include "confdefs.h"
+
+extern int strtoul();
+int main()
+{
+ char *string = "0";
+ char *term;
+ int value;
+ value = strtoul(string, &term, 0);
+ if ((value != 0) || (term != (string+1))) {
+ exit(1);
+ }
+ exit(0);
+}
+EOF
+if { (eval echo configure:2676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tcl_ok=0
+fi
+rm -fr conftest*
+fi
+
+if test "$tcl_ok" = 0; then
+ test -n "$verbose" && echo " Adding strtoul.o."
+ LIBOBJS="$LIBOBJS strtoul.o"
+fi
+
+#--------------------------------------------------------------------
+# Check for the strtod function. This is tricky because in some
+# versions of Linux strtod mis-parses strings starting with "+".
+#--------------------------------------------------------------------
+
+echo $ac_n "checking for strtod""... $ac_c" 1>&6
+echo "configure:2699: checking for strtod" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strtod'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2704 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strtod(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strtod();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strtod) || defined (__stub___strtod)
+choke me
+#else
+strtod();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2727: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strtod=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strtod=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strtod`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_ok=1
+else
+ echo "$ac_t""no" 1>&6
+tcl_ok=0
+fi
+
+if test "$cross_compiling" = yes; then
+ tcl_ok=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2751 "configure"
+#include "confdefs.h"
+
+extern double strtod();
+int main()
+{
+ char *string = " +69";
+ char *term;
+ double value;
+ value = strtod(string, &term);
+ if ((value != 69) || (term != (string+4))) {
+ exit(1);
+ }
+ exit(0);
+}
+EOF
+if { (eval echo configure:2767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tcl_ok=0
+fi
+rm -fr conftest*
+fi
+
+if test "$tcl_ok" = 0; then
+ test -n "$verbose" && echo " Adding strtod.o."
+ LIBOBJS="$LIBOBJS strtod.o"
+fi
+
+#--------------------------------------------------------------------
+# Under Solaris 2.4, strtod returns the wrong value for the
+# terminating character under some conditions. Check for this
+# and if the problem exists use a substitute procedure
+# "fixstrtod" that corrects the error.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking for strtod""... $ac_c" 1>&6
+echo "configure:2792: checking for strtod" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strtod'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2797 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strtod(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strtod();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strtod) || defined (__stub___strtod)
+choke me
+#else
+strtod();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2820: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strtod=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strtod=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strtod`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_strtod=1
+else
+ echo "$ac_t""no" 1>&6
+tcl_strtod=0
+fi
+
+if test "$tcl_strtod" = 1; then
+ echo $ac_n "checking for Solaris strtod bug""... $ac_c" 1>&6
+echo "configure:2842: checking for Solaris strtod bug" >&5
+ if test "$cross_compiling" = yes; then
+ tcl_ok=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2847 "configure"
+#include "confdefs.h"
+
+extern double strtod();
+int main()
+{
+ char *string = "NaN";
+ char *term;
+ strtod(string, &term);
+ if ((term != string) && (term[-1] == 0)) {
+ exit(1);
+ }
+ exit(0);
+}
+EOF
+if { (eval echo configure:2862: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ tcl_ok=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tcl_ok=0
+fi
+rm -fr conftest*
+fi
+
+ if test $tcl_ok = 1; then
+ echo "$ac_t""ok" 1>&6
+ else
+ echo "$ac_t""buggy" 1>&6
+ LIBOBJS="$LIBOBJS fixstrtod.o"
+ cat >> confdefs.h <<\EOF
+#define strtod fixstrtod
+EOF
+
+ fi
+fi
+
+#--------------------------------------------------------------------
+# Check for various typedefs and provide substitutes if
+# they don't exist.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:2892: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2897 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2905: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2922 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2940 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2961 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2972: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for mode_t""... $ac_c" 1>&6
+echo "configure:2996: checking for mode_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3001 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_mode_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_mode_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_mode_t" 1>&6
+if test $ac_cv_type_mode_t = no; then
+ cat >> confdefs.h <<\EOF
+#define mode_t int
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:3029: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3034 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:3062: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3067 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:3095: checking for uid_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3100 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "uid_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_uid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+
+#--------------------------------------------------------------------
+# If a system doesn't have an opendir function (man, that's old!)
+# then we have to supply a different version of dirent.h which
+# is compatible with the substitute version of opendir that's
+# provided. This version only works with V7-style directories.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking for opendir""... $ac_c" 1>&6
+echo "configure:3137: checking for opendir" >&5
+if eval "test \"`echo '$''{'ac_cv_func_opendir'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3142 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char opendir(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_opendir) || defined (__stub___opendir)
+choke me
+#else
+opendir();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_opendir=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_opendir=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'opendir`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define USE_DIRENT2_H 1
+EOF
+
+fi
+
+
+#--------------------------------------------------------------------
+# The check below checks whether <sys/wait.h> defines the type
+# "union wait" correctly. It's needed because of weirdness in
+# HP-UX where "union wait" is defined in both the BSD and SYS-V
+# environments. Checking the usability of WIFEXITED seems to do
+# the trick.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking union wait""... $ac_c" 1>&6
+echo "configure:3198: checking union wait" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3200 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+int main() {
+
+union wait x;
+WIFEXITED(x); /* Generates compiler error if WIFEXITED
+ * uses an int. */
+
+; return 0; }
+EOF
+if { (eval echo configure:3212: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ tcl_ok=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_ok=no
+fi
+rm -f conftest*
+echo "$ac_t""$tcl_ok" 1>&6
+if test $tcl_ok = no; then
+ cat >> confdefs.h <<\EOF
+#define NO_UNION_WAIT 1
+EOF
+
+fi
+
+#--------------------------------------------------------------------
+# Check to see whether the system supports the matherr function
+# and its associated type "struct exception".
+#--------------------------------------------------------------------
+
+echo $ac_n "checking matherr support""... $ac_c" 1>&6
+echo "configure:3236: checking matherr support" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3238 "configure"
+#include "confdefs.h"
+#include <math.h>
+int main() {
+
+struct exception x;
+x.type = DOMAIN;
+x.type = SING;
+
+; return 0; }
+EOF
+if { (eval echo configure:3249: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ tcl_ok=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_ok=no
+fi
+rm -f conftest*
+echo "$ac_t""$tcl_ok" 1>&6
+if test $tcl_ok = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_MATHERR 1
+EOF
+
+fi
+
+#--------------------------------------------------------------------
+# Check to see whether the system provides a vfork kernel call.
+# If not, then use fork instead. Also, check for a problem with
+# vforks and signals that can cause core dumps if a vforked child
+# resets a signal handler. If the problem exists, then use fork
+# instead of vfork.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:3276: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3281 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:3298: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking for vfork""... $ac_c" 1>&6
+echo "configure:3317: checking for vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3322 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char vfork(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char vfork();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vfork) || defined (__stub___vfork)
+choke me
+#else
+vfork();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_ok=1
+else
+ echo "$ac_t""no" 1>&6
+tcl_ok=0
+fi
+
+if test "$tcl_ok" = 1; then
+ echo $ac_n "checking vfork/signal bug""... $ac_c" 1>&6
+echo "configure:3367: checking vfork/signal bug" >&5;
+ if test "$cross_compiling" = yes; then
+ tcl_ok=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3372 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/wait.h>
+int gotSignal = 0;
+sigProc(sig)
+ int sig;
+{
+ gotSignal = 1;
+}
+main()
+{
+ int pid, sts;
+ (void) signal(SIGCHLD, sigProc);
+ pid = vfork();
+ if (pid < 0) {
+ exit(1);
+ } else if (pid == 0) {
+ (void) signal(SIGCHLD, SIG_DFL);
+ _exit(0);
+ } else {
+ (void) wait(&sts);
+ }
+ exit((gotSignal) ? 0 : 1);
+}
+EOF
+if { (eval echo configure:3400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ tcl_ok=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tcl_ok=0
+fi
+rm -fr conftest*
+fi
+
+ if test "$tcl_ok" = 1; then
+ echo "$ac_t""ok" 1>&6
+ else
+ echo "$ac_t""buggy, using fork instead" 1>&6
+ fi
+fi
+rm -f core
+if test "$tcl_ok" = 0; then
+ cat >> confdefs.h <<\EOF
+#define vfork fork
+EOF
+
+fi
+
+#--------------------------------------------------------------------
+# Check whether there is an strncasecmp function on this system.
+# This is a bit tricky because under SCO it's in -lsocket and
+# under Sequent Dynix it's in -linet.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking for strncasecmp""... $ac_c" 1>&6
+echo "configure:3433: checking for strncasecmp" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strncasecmp'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3438 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strncasecmp(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strncasecmp();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strncasecmp) || defined (__stub___strncasecmp)
+choke me
+#else
+strncasecmp();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strncasecmp=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strncasecmp=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strncasecmp`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_ok=1
+else
+ echo "$ac_t""no" 1>&6
+tcl_ok=0
+fi
+
+if test "$tcl_ok" = 0; then
+ echo $ac_n "checking for strncasecmp in -lsocket""... $ac_c" 1>&6
+echo "configure:3483: checking for strncasecmp in -lsocket" >&5
+ac_lib_var=`echo socket'_'strncasecmp | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsocket $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3491 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strncasecmp();
+
+int main() {
+strncasecmp()
+; return 0; }
+EOF
+if { (eval echo configure:3502: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_ok=1
+else
+ echo "$ac_t""no" 1>&6
+tcl_ok=0
+fi
+
+fi
+if test "$tcl_ok" = 0; then
+ echo $ac_n "checking for strncasecmp in -linet""... $ac_c" 1>&6
+echo "configure:3526: checking for strncasecmp in -linet" >&5
+ac_lib_var=`echo inet'_'strncasecmp | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3534 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strncasecmp();
+
+int main() {
+strncasecmp()
+; return 0; }
+EOF
+if { (eval echo configure:3545: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_ok=1
+else
+ echo "$ac_t""no" 1>&6
+tcl_ok=0
+fi
+
+fi
+if test "$tcl_ok" = 0; then
+ LIBOBJS="$LIBOBJS strncasecmp.o"
+fi
+
+#--------------------------------------------------------------------
+# The code below deals with several issues related to gettimeofday:
+# 1. Some systems don't provide a gettimeofday function at all
+# (set NO_GETTOD if this is the case).
+# 2. SGI systems don't use the BSD form of the gettimeofday function,
+# but they have a BSDgettimeofday function that can be used instead.
+# 3. See if gettimeofday is declared in the <sys/time.h> header file.
+# if not, set the GETTOD_NOT_DECLARED flag so that tclPort.h can
+# declare it.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking for BSDgettimeofday""... $ac_c" 1>&6
+echo "configure:3583: checking for BSDgettimeofday" >&5
+if eval "test \"`echo '$''{'ac_cv_func_BSDgettimeofday'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3588 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char BSDgettimeofday(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char BSDgettimeofday();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_BSDgettimeofday) || defined (__stub___BSDgettimeofday)
+choke me
+#else
+BSDgettimeofday();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_BSDgettimeofday=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_BSDgettimeofday=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'BSDgettimeofday`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_BSDGETTIMEOFDAY 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for gettimeofday""... $ac_c" 1>&6
+echo "configure:3632: checking for gettimeofday" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gettimeofday'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3637 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gettimeofday(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gettimeofday();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gettimeofday) || defined (__stub___gettimeofday)
+choke me
+#else
+gettimeofday();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_gettimeofday=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gettimeofday=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gettimeofday`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NO_GETTOD 1
+EOF
+
+fi
+
+fi
+
+echo $ac_n "checking for gettimeofday declaration""... $ac_c" 1>&6
+echo "configure:3686: checking for gettimeofday declaration" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3688 "configure"
+#include "confdefs.h"
+#include <sys/time.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "gettimeofday" >/dev/null 2>&1; then
+ rm -rf conftest*
+ echo "$ac_t""present" 1>&6
+else
+ rm -rf conftest*
+
+ echo "$ac_t""missing" 1>&6
+ cat >> confdefs.h <<\EOF
+#define GETTOD_NOT_DECLARED 1
+EOF
+
+
+fi
+rm -f conftest*
+
+
+#--------------------------------------------------------------------
+# Interactive UNIX requires -linet instead of -lsocket, plus it
+# needs net/errno.h to define the socket-related error codes.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking for main in -linet""... $ac_c" 1>&6
+echo "configure:3715: checking for main in -linet" >&5
+ac_lib_var=`echo inet'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-linet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3723 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:3730: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -linet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "net/errno.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for net/errno.h""... $ac_c" 1>&6
+echo "configure:3752: checking for net/errno.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3757 "configure"
+#include "confdefs.h"
+#include <net/errno.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3762: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_NET_ERRNO_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+#--------------------------------------------------------------------
+# The following code checks to see whether it is possible to get
+# signed chars on this platform. This is needed in order to
+# properly generate sign-extended ints from character values.
+#--------------------------------------------------------------------
+
+echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
+echo "configure:3794: checking whether char is unsigned" >&5
+if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$GCC" = yes; then
+ # GCC predefines this symbol on systems where it applies.
+cat > conftest.$ac_ext <<EOF
+#line 3801 "configure"
+#include "confdefs.h"
+#ifdef __CHAR_UNSIGNED__
+ yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_c_char_unsigned=yes
+else
+ rm -rf conftest*
+ ac_cv_c_char_unsigned=no
+fi
+rm -f conftest*
+
+else
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3823 "configure"
+#include "confdefs.h"
+/* volatile prevents gcc2 from optimizing the test away on sparcs. */
+#if !defined(__STDC__) || __STDC__ != 1
+#define volatile
+#endif
+main() {
+ volatile char c = 255; exit(c < 0);
+}
+EOF
+if { (eval echo configure:3833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_char_unsigned=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_char_unsigned=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6
+if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
+ cat >> confdefs.h <<\EOF
+#define __CHAR_UNSIGNED__ 1
+EOF
+
+fi
+
+echo $ac_n "checking signed char declarations""... $ac_c" 1>&6
+echo "configure:3857: checking signed char declarations" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3859 "configure"
+#include "confdefs.h"
+
+int main() {
+
+signed char *p;
+p = 0;
+
+; return 0; }
+EOF
+if { (eval echo configure:3869: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ tcl_ok=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_ok=no
+fi
+rm -f conftest*
+echo "$ac_t""$tcl_ok" 1>&6
+if test $tcl_ok = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SIGNED_CHAR 1
+EOF
+
+fi
+
+#--------------------------------------------------------------------
+# Check for the existence of the -lsocket and -lnsl libraries.
+# The order here is important, so that they end up in the right
+# order in the command line generated by make. Here are some
+# special considerations:
+# 1. Use "connect" and "accept" to check for -lsocket, and
+# "gethostbyname" to check for -lnsl.
+# 2. Use each function name only once: can't redo a check because
+# autoconf caches the results of the last check and won't redo it.
+# 3. Use -lnsl and -lsocket only if they supply procedures that
+# aren't already present in the normal libraries. This is because
+# IRIX 5.2 has libraries, but they aren't needed and they're
+# bogus: they goof up name resolution if used.
+# 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+# To get around this problem, check for both libraries together
+# if -lsocket doesn't work by itself.
+#--------------------------------------------------------------------
+
+# CYGNUS LOCAL: Store any socket library(ies) in the cache, and don't
+# mess up the cache values of the functions we check for.
+echo $ac_n "checking for socket libraries""... $ac_c" 1>&6
+echo "configure:3908: checking for socket libraries" >&5
+if eval "test \"`echo '$''{'tcl_cv_lib_sockets'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ tcl_cv_lib_sockets=
+ tcl_checkBoth=0
+ unset ac_cv_func_connect
+ echo $ac_n "checking for connect""... $ac_c" 1>&6
+echo "configure:3916: checking for connect" >&5
+if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3921 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char connect(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+connect();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_connect=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_connect=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_checkSocket=0
+else
+ echo "$ac_t""no" 1>&6
+tcl_checkSocket=1
+fi
+
+ if test "$tcl_checkSocket" = 1; then
+ unset ac_cv_func_connect
+ echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6
+echo "configure:3967: checking for main in -lsocket" >&5
+ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsocket $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3975 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:3982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_cv_lib_sockets="-lsocket"
+else
+ echo "$ac_t""no" 1>&6
+tcl_checkBoth=1
+fi
+
+ fi
+ if test "$tcl_checkBoth" = 1; then
+ tcl_oldLibs=$LIBS
+ LIBS="$LIBS -lsocket -lnsl"
+ unset ac_cv_func_accept
+ echo $ac_n "checking for accept""... $ac_c" 1>&6
+echo "configure:4009: checking for accept" >&5
+if eval "test \"`echo '$''{'ac_cv_func_accept'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4014 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char accept(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char accept();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_accept) || defined (__stub___accept)
+choke me
+#else
+accept();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4037: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_accept=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_accept=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'accept`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_checkNsl=0
+ tcl_cv_lib_sockets="-lsocket -lnsl"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ unset ac_cv_func_accept
+ LIBS=$tcl_oldLibs
+ fi
+ unset ac_cv_func_gethostbyname
+ tcl_oldLibs=$LIBS
+ LIBS="$LIBS $tcl_cv_lib_sockets"
+ echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:4064: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4069 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gethostbyname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+gethostbyname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4092: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
+echo "configure:4110: checking for main in -lnsl" >&5
+ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lnsl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4118 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:4125: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_cv_lib_sockets="$tcl_cv_lib_sockets -lnsl"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+ unset ac_cv_func_gethostbyname
+ LIBS=$tcl_oldLIBS
+
+fi
+
+echo "$ac_t""$tcl_cv_lib_sockets" 1>&6
+test -z "$tcl_cv_lib_sockets" || LIBS="$LIBS $tcl_cv_lib_sockets"
+
+#--------------------------------------------------------------------
+# The statements below define a collection of symbols related to
+# dynamic loading and shared libraries:
+#
+# DL_OBJS - Name of the object file that implements dynamic
+# loading for Tcl on this system.
+# DL_LIBS - Library file(s) to include in tclsh and other base
+# applications in order for the "load" command to work.
+# LD_FLAGS - Flags to pass to the compiler when linking object
+# files into an executable application binary such
+# as tclsh.
+# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile.
+# MAKE_LIB - Command to execute to build the Tcl library;
+# differs depending on whether or not Tcl is being
+# compiled as a shared library.
+# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
+# of a shared library (may request position-independent
+# code, among other things).
+# SHLIB_LD - Base command to use for combining object files
+# into a shared library.
+# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+# creating shared libraries. This symbol typically
+# goes at the end of the "ld" commands that build
+# shared libraries. The value of the symbol is
+# "${LIBS}" if all of the dependent libraries should
+# be specified when creating a shared library. If
+# dependent libraries should not be specified (as on
+# SunOS 4.x, where they cause the link to fail, or in
+# general if Tcl and Tk aren't themselves shared
+# libraries), then this symbol has an empty string
+# as its value.
+# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
+# extensions. An empty string means we don't know how
+# to use shared libraries on this platform.
+# TCL_LIB_FILE - Name of the file that contains the Tcl library, such
+# as libtcl7.8.so or libtcl7.8.a.
+# TCL_LIB_SUFFIX -Specifies everything that comes after the "libtcl"
+# in the shared library name, using the $VERSION variable
+# to put the version in the right place. This is used
+# by platforms that need non-standard library names.
+# Examples: ${VERSION}.so.1.1 on NetBSD, since it needs
+# to have a version after the .so, and ${VERSION}.a
+# on AIX, since the Tcl shared library needs to have
+# a .a extension whereas shared objects for loadable
+# extensions have a .so extension. Defaults to
+# ${VERSION}${SHLIB_SUFFIX}.
+#--------------------------------------------------------------------
+
+# Step 1: set the variable "system" to hold the name and version number
+# for the system. This can usually be done via the "uname" command, but
+# there are a few systems, like Next, where this doesn't work.
+
+echo $ac_n "checking system version (for dynamic loading)""... $ac_c" 1>&6
+echo "configure:4211: checking system version (for dynamic loading)" >&5
+if test -f /usr/lib/NextStep/software_version; then
+ system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+else
+ system=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ echo "$ac_t""unknown (can't find uname command)" 1>&6
+ system=unknown
+ else
+ # Special check for weird MP-RAS system (uname returns weird
+ # results, and the version is kept in special file).
+
+ if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+ system=MP-RAS-`awk '{print $3}' /etc/.relid'`
+ fi
+ if test "`uname -s`" = "AIX" ; then
+ system=AIX-`uname -v`.`uname -r`
+ fi
+ echo "$ac_t""$system" 1>&6
+ fi
+fi
+
+# Step 2: check for existence of -ldl library. This is needed because
+# Linux can use either -ldl or -ldld for dynamic loading.
+
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:4237: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4245 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:4256: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ have_dl=yes
+else
+ echo "$ac_t""no" 1>&6
+have_dl=no
+fi
+
+
+# Step 3: set configuration options based on system name and version.
+
+fullSrcDir=`cd $srcdir; pwd`
+TCL_SHARED_LIB_SUFFIX=""
+TCL_UNSHARED_LIB_SUFFIX=""
+TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`'
+ECHO_VERSION='`echo ${VERSION}`'
+TCL_LIB_VERSIONS_OK=ok
+case $system in
+ AIX-4.[2-9])
+ SHLIB_CFLAGS=""
+ SHLIB_LD="$fullSrcDir/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ AIX=yes
+ TCL_SHARED_LIB_SUFFIX='${VERSION}.a'
+ ;;
+ AIX-*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="$fullSrcDir/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o tclLoadAix.o"
+ DL_LIBS="-lld"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ TCL_SHARED_LIB_SUFFIX='${VERSION}.a'
+ ;;
+ BSD/OS-2.1*|BSD/OS-3*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="shlicc -r"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ dgux*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+ # CYGNUS LOCAL: Handle gcc and versions of HP-UX that can't
+ # do dynamic linking.
+ echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "configure:4334: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4342 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo configure:4353: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ tcl_ok=yes
+else
+ echo "$ac_t""no" 1>&6
+tcl_ok=no
+fi
+
+ if test "$tcl_ok" = "yes"; then
+ if test "$GCC" = yes; then
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="$CC -shared -fPIC"
+ else
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+ fi
+
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".sl"
+ DL_OBJS="tclLoadShl.o"
+ DL_LIBS="-ldld"
+
+ # The GNU linker requires the -export-dynamic
+ # option to make all symbols visible in the dynamic symbol
+ # table. Note that the HP linker will give errors
+ # -export-dynamic, but will still exit successfully.
+ # Adding a -L option will make it fail.
+ hold_ldflags=$LDFLAGS
+ echo $ac_n "checking for the ld -export-dynamic flag""... $ac_c" 1>&6
+echo "configure:4395: checking for the ld -export-dynamic flag" >&5
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic -L`pwd`"
+ cat > conftest.$ac_ext <<EOF
+#line 4398 "configure"
+#include "confdefs.h"
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:4405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ found=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ found=no
+fi
+rm -f conftest*
+ LDFLAGS=$hold_ldflags
+ echo "$ac_t""$found" 1>&6
+ if test $found = yes; then
+ LD_FLAGS="-Wl,-export-dynamic"
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ else
+ LD_FLAGS="-Wl,-E"
+ LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ fi
+ fi
+ # END CYGNUS LOCAL
+ ;;
+ IRIX-4.*)
+ SHLIB_CFLAGS="-G 0"
+ SHLIB_SUFFIX=".a"
+ SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
+ SHLIB_LD_LIBS='${LIBS}'
+ DL_OBJS="tclLoadAout.o"
+ DL_LIBS=""
+ LD_FLAGS="-Wl,-D,08000000"
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ TCL_SHARED_LIB_SUFFIX='${VERSION}.a'
+ ;;
+ IRIX-5.*|IRIX-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ ;;
+ IRIX64-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared -rpath /usr/local/lib"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ ;;
+ Linux*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ if test "$have_dl" = yes; then
+ SHLIB_LD="${CC} -shared"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS="-rdynamic"
+ LD_SEARCH_FLAGS=""
+ else
+ ac_safe=`echo "dld.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for dld.h""... $ac_c" 1>&6
+echo "configure:4471: checking for dld.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4476 "configure"
+#include "confdefs.h"
+#include <dld.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4481: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ SHLIB_LD="ld -shared"
+ DL_OBJS="tclLoadDld.o"
+ DL_LIBS="-ldld"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ ;;
+ MP-RAS-02*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ MP-RAS-*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS="-Wl,-Bexport"
+ LD_SEARCH_FLAGS=""
+ ;;
+ NetBSD-*|FreeBSD-*|OpenBSD-*)
+ # Not available on all versions: check for include file.
+ ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6
+echo "configure:4533: checking for dlfcn.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4538 "configure"
+#include "confdefs.h"
+#include <dlfcn.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4543: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ SHLIB_CFLAGS="-fpic"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ TCL_SHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.so.1.0'
+
+else
+ echo "$ac_t""no" 1>&6
+
+ SHLIB_CFLAGS=""
+ SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".a"
+ DL_OBJS="tclLoadAout.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ TCL_SHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.a'
+
+fi
+
+
+ # FreeBSD doesn't handle version numbers with dots.
+
+ TCL_UNSHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.a'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ NEXTSTEP-*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="cc -nostdlib -r"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadNext.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ OSF1-1.0|OSF1-1.1|OSF1-1.2)
+ # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+ SHLIB_CFLAGS=""
+ # Hack: make package name same as library name
+ SHLIB_LD='ld -R -export $@:'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadOSF.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ OSF1-1.*)
+ # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+ SHLIB_CFLAGS="-fpic"
+ SHLIB_LD="ld -shared"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ OSF1-V*)
+ # Digital OSF/1
+ SHLIB_CFLAGS=""
+ SHLIB_LD='ld -shared -expect_unresolved "*"'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ ;;
+ RISCos-*)
+ SHLIB_CFLAGS="-G 0"
+ SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".a"
+ DL_OBJS="tclLoadAout.o"
+ DL_LIBS=""
+ LD_FLAGS="-Wl,-D,08000000"
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ ;;
+ SCO_SV-3.2*)
+ # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+ # this test works, since "uname -s" was non-standard in 3.2.4 and
+ # below.
+ SHLIB_CFLAGS="-Kpic -belf"
+ SHLIB_LD="ld -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS="-belf -Wl,-Bexport"
+ LD_SEARCH_FLAGS=""
+ ;;
+ SINIX*5.4*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SunOS-4*)
+ # CYGNUS LOCAL: gcc uses a different option than native cc.
+ if test "$GCC" = yes; then
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="$CC -shared -fPIC"
+ else
+ SHLIB_CFLAGS="-PIC"
+ SHLIB_LD="ld"
+ fi
+ # END CYGNUS LOCAL
+
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+
+ # SunOS can't handle version numbers with dots in them in library
+ # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it
+ # requires an extra version number at the end of .so file names.
+ # So, the library has to have a name like libtcl75.so.1.0
+
+ TCL_SHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.so.1.0'
+ TCL_UNSHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.a'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ SunOS-5*)
+ # CYGNUS LOCAL: gcc uses a different option than native cc.
+ if test "$GCC" = yes; then
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="$CC -shared -fPIC"
+ else
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ fi
+ # END CYGNUS LOCAL
+
+ # Note: need the LIBS below, otherwise Tk won't find Tcl's
+ # symbols when dynamically loaded into tclsh.
+
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ # CYGNUS LOCAL: The GNU linker requires the -export-dynamic
+ # option to make all symbols visible in the dynamic symbol
+ # table.
+ hold_ldflags=$LDFLAGS
+ echo $ac_n "checking for the ld -export-dynamic flag""... $ac_c" 1>&6
+echo "configure:4718: checking for the ld -export-dynamic flag" >&5
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
+ cat > conftest.$ac_ext <<EOF
+#line 4721 "configure"
+#include "confdefs.h"
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:4728: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ found=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ found=no
+fi
+rm -f conftest*
+ LDFLAGS=$hold_ldflags
+ echo "$ac_t""$found" 1>&6
+ if test $found = yes; then
+ LD_FLAGS="-Wl,-export-dynamic"
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ else
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ fi
+ # END CYGNUS LOCAL
+ ;;
+ ULTRIX-4.*)
+ SHLIB_CFLAGS="-G 0"
+ SHLIB_SUFFIX=".a"
+ SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
+ SHLIB_LD_LIBS='${LIBS}'
+ DL_OBJS="tclLoadAout.o"
+ DL_LIBS=""
+ # CYGNUS LOCAL: The GNU linker doesn't accept `-D 08000000'. It
+ # doesn't appear to be needed, either.
+ hold_ldflags="$LDFLAGS"
+ echo $ac_n "checking whether ld accepts -D 08000000""... $ac_c" 1>&6
+echo "configure:4760: checking whether ld accepts -D 08000000" >&5
+ LD_FLAGS="-Wl,-D,08000000"
+ LDFLAGS="${LDFLAGS} -Wl,-D,08000000"
+ cat > conftest.$ac_ext <<EOF
+#line 4764 "configure"
+#include "confdefs.h"
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:4771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ found=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ found=no
+fi
+rm -f conftest*
+ LDFLAGS=$hold_ldflags
+ echo "$ac_t""$found" 1>&6
+ if test $found = yes; then
+ LD_FLAGS="-Wl,-D,08000000"
+ else
+ LD_FLAGS=""
+ fi
+ # END CYGNUS LOCAL
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ ;;
+ UNIX_SV* | UnixWare-5*)
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+ # that don't grok the -Bexport option. Test that it does.
+ hold_ldflags=$LDFLAGS
+ echo $ac_n "checking for ld accepts -Bexport flag""... $ac_c" 1>&6
+echo "configure:4802: checking for ld accepts -Bexport flag" >&5
+ LDFLAGS="${LDFLAGS} -Wl,-Bexport"
+ cat > conftest.$ac_ext <<EOF
+#line 4805 "configure"
+#include "confdefs.h"
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:4812: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ found=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ found=no
+fi
+rm -f conftest*
+ LDFLAGS=$hold_ldflags
+ echo "$ac_t""$found" 1>&6
+ if test $found = yes; then
+ LD_FLAGS="-Wl,-Bexport"
+ else
+ LD_FLAGS=""
+ fi
+ LD_SEARCH_FLAGS=""
+ ;;
+esac
+
+# Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic
+# Loading for Tcl -- What Became of It?". Proc. 2nd Tcl/Tk Workshop,
+# New Orleans, LA, Computerized Processes Unlimited, 1994), then we need
+# to determine which of several header files defines the a.out file
+# format (a.out.h, sys/exec.h, or sys/exec_aout.h). At present, we
+# support only a file format that is more or less version-7-compatible.
+# In particular,
+# - a.out files must begin with `struct exec'.
+# - the N_TXTOFF on the `struct exec' must compute the seek address
+# of the text segment
+# - The `struct exec' must contain a_magic, a_text, a_data, a_bss
+# and a_entry fields.
+# The following compilation should succeed if and only if either sys/exec.h
+# or a.out.h is usable for the purpose.
+#
+# Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the
+# `struct exec' includes a second header that contains information that
+# duplicates the v7 fields that are needed.
+
+if test "x$DL_OBJS" = "xtclLoadAout.o" ; then
+ echo $ac_n "checking sys/exec.h""... $ac_c" 1>&6
+echo "configure:4854: checking sys/exec.h" >&5
+ cat > conftest.$ac_ext <<EOF
+#line 4856 "configure"
+#include "confdefs.h"
+#include <sys/exec.h>
+int main() {
+
+ struct exec foo;
+ unsigned long seek;
+ int flag;
+#if defined(__mips) || defined(mips)
+ seek = N_TXTOFF (foo.ex_f, foo.ex_o);
+#else
+ seek = N_TXTOFF (foo);
+#endif
+ flag = (foo.a_magic == OMAGIC);
+ return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
+
+; return 0; }
+EOF
+if { (eval echo configure:4874: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ tcl_ok=usable
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_ok=unusable
+fi
+rm -f conftest*
+ echo "$ac_t""$tcl_ok" 1>&6
+ if test $tcl_ok = usable; then
+ cat >> confdefs.h <<\EOF
+#define USE_SYS_EXEC_H 1
+EOF
+
+ else
+ echo $ac_n "checking a.out.h""... $ac_c" 1>&6
+echo "configure:4892: checking a.out.h" >&5
+ cat > conftest.$ac_ext <<EOF
+#line 4894 "configure"
+#include "confdefs.h"
+#include <a.out.h>
+int main() {
+
+ struct exec foo;
+ unsigned long seek;
+ int flag;
+#if defined(__mips) || defined(mips)
+ seek = N_TXTOFF (foo.ex_f, foo.ex_o);
+#else
+ seek = N_TXTOFF (foo);
+#endif
+ flag = (foo.a_magic == OMAGIC);
+ return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
+
+; return 0; }
+EOF
+if { (eval echo configure:4912: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ tcl_ok=usable
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_ok=unusable
+fi
+rm -f conftest*
+ echo "$ac_t""$tcl_ok" 1>&6
+ if test $tcl_ok = usable; then
+ cat >> confdefs.h <<\EOF
+#define USE_A_OUT_H 1
+EOF
+
+ else
+ echo $ac_n "checking sys/exec_aout.h""... $ac_c" 1>&6
+echo "configure:4930: checking sys/exec_aout.h" >&5
+ cat > conftest.$ac_ext <<EOF
+#line 4932 "configure"
+#include "confdefs.h"
+#include <sys/exec_aout.h>
+int main() {
+
+ struct exec foo;
+ unsigned long seek;
+ int flag;
+#if defined(__mips) || defined(mips)
+ seek = N_TXTOFF (foo.ex_f, foo.ex_o);
+#else
+ seek = N_TXTOFF (foo);
+#endif
+ flag = (foo.a_midmag == OMAGIC);
+ return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
+
+; return 0; }
+EOF
+if { (eval echo configure:4950: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ tcl_ok=usable
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_ok=unusable
+fi
+rm -f conftest*
+ echo "$ac_t""$tcl_ok" 1>&6
+ if test $tcl_ok = usable; then
+ cat >> confdefs.h <<\EOF
+#define USE_SYS_EXEC_AOUT_H 1
+EOF
+
+ else
+ DL_OBJS=""
+ fi
+ fi
+ fi
+fi
+
+# Step 5: disable dynamic loading if requested via a command-line switch.
+
+# Check whether --enable-load or --disable-load was given.
+if test "${enable_load+set}" = set; then
+ enableval="$enable_load"
+ tcl_ok=$enableval
+else
+ tcl_ok=yes
+fi
+
+if test "$tcl_ok" = "no"; then
+ DL_OBJS=""
+fi
+
+if test "x$DL_OBJS" != "x" ; then
+ BUILD_DLTEST="\$(DLTEST_TARGETS)"
+else
+ echo "Can't figure out how to do dynamic loading or shared libraries"
+ echo "on this system."
+ SHLIB_CFLAGS=""
+ SHLIB_LD=""
+ SHLIB_SUFFIX=""
+ DL_OBJS="tclLoadNone.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ BUILD_DLTEST=""
+fi
+
+# If we're running gcc, then change the C flags for compiling shared
+# libraries to the right flags for gcc, instead of those for the
+# standard manufacturer compiler.
+
+if test "$DL_OBJS" != "tclLoadNone.o" ; then
+ if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then
+ case $system in
+ AIX-*)
+ ;;
+ BSD/OS*)
+ ;;
+ IRIX*)
+ ;;
+ NetBSD-*|FreeBSD-*|OpenBSD-*)
+ ;;
+ RISCos-*)
+ ;;
+ ULTRIX-4.*)
+ ;;
+ *)
+ SHLIB_CFLAGS="-fPIC"
+ ;;
+ esac
+ fi
+fi
+
+#--------------------------------------------------------------------
+# The statements below check for systems where POSIX-style
+# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+# On these systems (mostly older ones), use the old BSD-style
+# FIONBIO approach instead.
+#--------------------------------------------------------------------
+
+for ac_hdr in sys/ioctl.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:5039: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5044 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5049: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in sys/filio.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:5079: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5084 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5089: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking FIONBIO vs. O_NONBLOCK for nonblocking I/O""... $ac_c" 1>&6
+echo "configure:5116: checking FIONBIO vs. O_NONBLOCK for nonblocking I/O" >&5
+if test -f /usr/lib/NextStep/software_version; then
+ system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+else
+ system=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ system=unknown
+ else
+ # Special check for weird MP-RAS system (uname returns weird
+ # results, and the version is kept in special file).
+
+ if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+ system=MP-RAS-`awk '{print $3}' /etc/.relid'`
+ fi
+ if test "`uname -s`" = "AIX" ; then
+ system=AIX-`uname -v`.`uname -r`
+ fi
+ fi
+fi
+case $system in
+ # There used to be code here to use FIONBIO under AIX. However, it
+ # was reported that FIONBIO doesn't work under AIX 3.2.5. Since
+ # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
+ # code (JO, 5/31/97).
+
+ OSF*)
+ cat >> confdefs.h <<\EOF
+#define USE_FIONBIO 1
+EOF
+
+ echo "$ac_t""FIONBIO" 1>&6
+ ;;
+ SunOS-4*)
+ cat >> confdefs.h <<\EOF
+#define USE_FIONBIO 1
+EOF
+
+ echo "$ac_t""FIONBIO" 1>&6
+ ;;
+ ULTRIX-4.*)
+ cat >> confdefs.h <<\EOF
+#define USE_FIONBIO 1
+EOF
+
+ echo "$ac_t""FIONBIO" 1>&6
+ ;;
+ *)
+ echo "$ac_t""O_NONBLOCK" 1>&6
+ ;;
+esac
+
+#--------------------------------------------------------------------
+# The statements below define a collection of symbols related to
+# building libtcl as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+realRanlib=$RANLIB
+if test "$TCL_SHARED_LIB_SUFFIX" = "" ; then
+ TCL_SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'
+fi
+if test "$TCL_UNSHARED_LIB_SUFFIX" = "" ; then
+ TCL_UNSHARED_LIB_SUFFIX='${VERSION}.a'
+fi
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ tcl_ok=$enableval
+else
+ tcl_ok=no
+fi
+
+# CYGNUS LOCAL: need extra variables for this information.
+TCL_SHARED_LIB_FILE=dummy1
+TCL_UNSHARED_LIB_FILE=dummy2
+# END CYGNUS LOCAL
+if test "$tcl_ok" = "yes" -a "${SHLIB_SUFFIX}" != "" ; then
+ TCL_SHARED_BUILD=1
+ TCL_SHLIB_CFLAGS="${SHLIB_CFLAGS}"
+ TCL_LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS}"
+ eval "TCL_LIB_FILE=libtcl${TCL_SHARED_LIB_SUFFIX}"
+ TCL_SHARED_LIB_FILE="$TCL_LIB_FILE"
+ if test "x$DL_OBJS" = "xtclLoadAout.o"; then
+ MAKE_LIB="ar cr \${TCL_LIB_FILE} \${OBJS}"
+ else
+ MAKE_LIB="\${SHLIB_LD} -o \${TCL_LIB_FILE} \${OBJS} ${SHLIB_LD_LIBS}"
+ RANLIB=":"
+ fi
+else
+ TCL_SHARED_BUILD=0
+ case $system in
+ BSD/OS*)
+ ;;
+
+ AIX-*)
+ ;;
+
+ *)
+ SHLIB_LD_LIBS=""
+ ;;
+ esac
+ TCL_SHLIB_CFLAGS=""
+ TCL_LD_SEARCH_FLAGS=""
+ eval "TCL_LIB_FILE=libtcl${TCL_UNSHARED_LIB_SUFFIX}"
+ TCL_UNSHARED_LIB_FILE="$TCL_LIB_FILE"
+ MAKE_LIB="$AR cr ${TCL_LIB_FILE} \${OBJS}"
+fi
+
+# Note: in the following variable, it's important to use the absolute
+# path name of the Tcl directory rather than "..": this is because
+# AIX remembers this path and will attempt to use it at run-time to look
+# up the Tcl library.
+
+if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+ TCL_BUILD_LIB_SPEC="-L`pwd` -ltcl${VERSION}"
+ TCL_LIB_SPEC="-L${exec_prefix}/lib -ltcl${VERSION}"
+else
+ TCL_BUILD_LIB_SPEC="-L`pwd` -ltcl`echo ${VERSION} | tr -d .`"
+ TCL_LIB_SPEC="-L${exec_prefix}/lib -ltcl`echo ${VERSION} | tr -d .`"
+fi
+
+TCL_LIB_FULL_PATH="`pwd`/${TCL_LIB_FILE}"
+
+#--------------------------------------------------------------------
+# The statements below define the symbol TCL_PACKAGE_PATH, which
+# gives a list of directories that may contain packages. The list
+# consists of one directory for machine-dependent binaries and
+# another for platform-independent scripts.
+#--------------------------------------------------------------------
+
+if test "$prefix" != "$exec_prefix"; then
+ TCL_PACKAGE_PATH="${exec_prefix}/lib ${prefix}/lib"
+else
+ TCL_PACKAGE_PATH="${prefix}/lib"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# CYGNUS LOCAL
+
+
+# END CYGNUS LOCAL
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile tclConfig.sh" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@RANLIB@%$RANLIB%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@CPP@%$CPP%g
+s%@BUILD_DLTEST@%$BUILD_DLTEST%g
+s%@DL_LIBS@%$DL_LIBS%g
+s%@DL_OBJS@%$DL_OBJS%g
+s%@LD_FLAGS@%$LD_FLAGS%g
+s%@MAKE_LIB@%$MAKE_LIB%g
+s%@MATH_LIBS@%$MATH_LIBS%g
+s%@SHLIB_CFLAGS@%$SHLIB_CFLAGS%g
+s%@SHLIB_LD@%$SHLIB_LD%g
+s%@SHLIB_LD_LIBS@%$SHLIB_LD_LIBS%g
+s%@SHLIB_SUFFIX@%$SHLIB_SUFFIX%g
+s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g
+s%@TCL_LD_SEARCH_FLAGS@%$TCL_LD_SEARCH_FLAGS%g
+s%@TCL_LIB_FILE@%$TCL_LIB_FILE%g
+s%@TCL_LIB_FULL_PATH@%$TCL_LIB_FULL_PATH%g
+s%@TCL_LIB_FLAG@%$TCL_LIB_FLAG%g
+s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g
+s%@TCL_LIB_VERSIONS_OK@%$TCL_LIB_VERSIONS_OK%g
+s%@TCL_MAJOR_VERSION@%$TCL_MAJOR_VERSION%g
+s%@TCL_MINOR_VERSION@%$TCL_MINOR_VERSION%g
+s%@TCL_PACKAGE_PATH@%$TCL_PACKAGE_PATH%g
+s%@TCL_PATCH_LEVEL@%$TCL_PATCH_LEVEL%g
+s%@TCL_SHARED_LIB_SUFFIX@%$TCL_SHARED_LIB_SUFFIX%g
+s%@TCL_SHARED_BUILD@%$TCL_SHARED_BUILD%g
+s%@TCL_SHLIB_CFLAGS@%$TCL_SHLIB_CFLAGS%g
+s%@TCL_SRC_DIR@%$TCL_SRC_DIR%g
+s%@TCL_UNSHARED_LIB_SUFFIX@%$TCL_UNSHARED_LIB_SUFFIX%g
+s%@TCL_VERSION@%$TCL_VERSION%g
+s%@TCL_SHARED_LIB_FILE@%$TCL_SHARED_LIB_FILE%g
+s%@TCL_UNSHARED_LIB_FILE@%$TCL_UNSHARED_LIB_FILE%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile tclConfig.sh"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/tcl/cygwin/configure.in b/tcl/cygwin/configure.in
new file mode 100644
index 00000000000..832db201e05
--- /dev/null
+++ b/tcl/cygwin/configure.in
@@ -0,0 +1,1388 @@
+dnl This file is an input file used by the GNU "autoconf" program to
+dnl generate the file "configure", which is run during Tcl installation
+dnl to configure the system for the local environment.
+
+# CYGNUS LOCAL, need 2.5 or higher for --bindir et al
+AC_PREREQ(2.5)
+# END CYGNUS LOCAL
+
+AC_INIT(../generic/tcl.h)
+# SCCS: @(#) configure.in 1.18 98/08/12 17:29:39
+
+TCL_VERSION=8.0
+TCL_MAJOR_VERSION=8
+TCL_MINOR_VERSION=0
+TCL_PATCH_LEVEL=".3"
+VERSION=${TCL_VERSION}
+
+if test "${prefix}" = "NONE"; then
+ prefix=/usr/local
+fi
+if test "${exec_prefix}" = "NONE"; then
+ exec_prefix=$prefix
+fi
+TCL_SRC_DIR=`cd $srcdir/..; pwd`
+
+AC_PROG_RANLIB
+dnl CYGNUS LOCAL: allow gcc without a special flag
+dnl AC_ARG_ENABLE(gcc, [ --enable-gcc allow use of gcc if available],
+dnl [tcl_ok=$enableval], [tcl_ok=no])
+dnl if test "$tcl_ok" = "yes"; then
+ AC_PROG_CC
+dnl else
+dnl CC=${CC-cc}
+dnl AC_SUBST(CC)
+dnl fi
+dnl END CYGNUS LOCAL
+
+# CYGNUS LOCAL
+# dje/win32
+AR=${AR-ar}
+# We need this for substitutions in Makefile.in.
+AC_PROG_INSTALL
+# END CYGNUS LOCAL
+
+#--------------------------------------------------------------------
+# CYGNUS LOCAL:
+# This is for LynxOS, which needs a flag to force true POSIX when
+# building. It's weirder than that, cause the flag varies depending
+# how old the compiler is. So...
+# -X is for the old "cc" and "gcc" (based on 1.42)
+# -mposix is for the new gcc (at least 2.5.8)
+# This modifies the value of $CC to have the POSIX flag added
+# so everything will configure correctly.
+#--------------------------------------------------------------------
+CY_AC_TCL_LYNX_POSIX
+
+# set the warning flags depending on whether or not we are using gcc
+if test "${GCC}" = "yes" ; then
+ CFLAGS_WARNING="-Wall -Wconversion"
+else
+ CFLAGS_WARNING=""
+fi
+
+#--------------------------------------------------------------------
+# Supply substitutes for missing POSIX library procedures, or
+# set flags so Tcl uses alternate procedures.
+#--------------------------------------------------------------------
+
+# Check if Posix compliant getcwd exists, if not we'll use getwd.
+AC_CHECK_FUNCS(getcwd, , AC_DEFINE(USEGETWD))
+# Nb: if getcwd uses popen and pwd(1) (like SunOS 4) we should really
+# define USEGETWD even if the posix getcwd exists. Add a test ?
+
+AC_REPLACE_FUNCS(opendir strstr)
+
+AC_REPLACE_FUNCS(strtol tmpnam waitpid)
+AC_CHECK_FUNC(strerror, , AC_DEFINE(NO_STRERROR))
+AC_CHECK_FUNC(getwd, , AC_DEFINE(NO_GETWD))
+AC_CHECK_FUNC(wait3, , AC_DEFINE(NO_WAIT3))
+AC_CHECK_FUNC(uname, , AC_DEFINE(NO_UNAME))
+
+#--------------------------------------------------------------------
+# On a few very rare systems, all of the libm.a stuff is
+# already in libc.a. Set compiler flags accordingly.
+# Also, Linux requires the "ieee" library for math to work
+# right (and it must appear before "-lm").
+#--------------------------------------------------------------------
+
+AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
+AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
+
+#--------------------------------------------------------------------
+# On AIX systems, libbsd.a has to be linked in to support
+# non-blocking file IO. This library has to be linked in after
+# the MATH_LIBS or it breaks the pow() function. The way to
+# insure proper sequencing, is to add it to the tail of MATH_LIBS.
+# This library also supplies gettimeofday.
+#--------------------------------------------------------------------
+libbsd=no
+if test "`uname -s`" = "AIX" ; then
+ AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes)
+ if test $libbsd = yes; then
+ MATH_LIBS="$MATH_LIBS -lbsd"
+ fi
+fi
+
+#--------------------------------------------------------------------
+# Supply substitutes for missing POSIX header files. Special
+# notes:
+# - stdlib.h doesn't define strtol, strtoul, or
+# strtod insome versions of SunOS
+# - some versions of string.h don't declare procedures such
+# as strstr
+#--------------------------------------------------------------------
+
+AC_MSG_CHECKING(dirent.h)
+AC_TRY_LINK([#include <sys/types.h>
+#include <dirent.h>], [
+#ifndef _POSIX_SOURCE
+# ifdef __Lynx__
+ /*
+ * Generate compilation error to make the test fail: Lynx headers
+ * are only valid if really in the POSIX environment.
+ */
+
+ missing_procedure();
+# endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+], tcl_ok=yes, tcl_ok=no)
+if test $tcl_ok = no; then
+ AC_DEFINE(NO_DIRENT_H)
+fi
+AC_MSG_RESULT($tcl_ok)
+AC_CHECK_HEADER(errno.h, , AC_DEFINE(NO_ERRNO_H))
+AC_CHECK_HEADER(float.h, , AC_DEFINE(NO_FLOAT_H))
+AC_CHECK_HEADER(values.h, , AC_DEFINE(NO_VALUES_H))
+AC_CHECK_HEADER(limits.h, , AC_DEFINE(NO_LIMITS_H))
+AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
+AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
+AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
+AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
+if test $tcl_ok = 0; then
+ AC_DEFINE(NO_STDLIB_H)
+fi
+AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
+AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
+if test $tcl_ok = 0; then
+ AC_DEFINE(NO_STRING_H)
+fi
+AC_CHECK_HEADER(sys/wait.h, , AC_DEFINE(NO_SYS_WAIT_H))
+AC_CHECK_HEADER(dlfcn.h, , AC_DEFINE(NO_DLFCN_H))
+AC_HAVE_HEADERS(unistd.h)
+
+#---------------------------------------------------------------------------
+# Determine which interface to use to talk to the serial port.
+# Note that #include lines must begin in leftmost column for
+# some compilers to recognize them as preprocessor directives.
+#---------------------------------------------------------------------------
+
+AC_MSG_CHECKING([termios vs. termio vs. sgtty])
+AC_TRY_RUN([
+#include <termios.h>
+
+main()
+{
+ struct termios t;
+ if (tcgetattr(0, &t) == 0) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tk_ok=termios, tk_ok=no, tk_ok=no)
+if test $tk_ok = termios; then
+ AC_DEFINE(USE_TERMIOS)
+else
+AC_TRY_RUN([
+#include <termio.h>
+
+main()
+{
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tk_ok=termio, tk_ok=no, tk_ok=no)
+if test $tk_ok = termio; then
+ AC_DEFINE(USE_TERMIO)
+else
+AC_TRY_RUN([
+#include <sgtty.h>
+
+main()
+{
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tk_ok=sgtty, tk_ok=none, tk_ok=none)
+if test $tk_ok = sgtty; then
+ AC_DEFINE(USE_SGTTY)
+fi
+fi
+fi
+AC_MSG_RESULT($tk_ok)
+
+#--------------------------------------------------------------------
+# Include sys/select.h if it exists and if it supplies things
+# that appear to be useful and aren't already in sys/types.h.
+# This appears to be true only on the RS/6000 under AIX. Some
+# systems like OSF/1 have a sys/select.h that's of no use, and
+# other systems like SCO UNIX have a sys/select.h that's
+# pernicious. If "fd_set" isn't defined anywhere then set a
+# special flag.
+#--------------------------------------------------------------------
+
+AC_MSG_CHECKING([fd_set and sys/select])
+AC_TRY_COMPILE([#include <sys/types.h>],
+ [fd_set readMask, writeMask;], tk_ok=yes, tk_ok=no)
+if test $tk_ok = no; then
+ AC_HEADER_EGREP(fd_mask, sys/select.h, tk_ok=yes)
+ if test $tk_ok = yes; then
+ AC_DEFINE(HAVE_SYS_SELECT_H)
+ fi
+fi
+AC_MSG_RESULT($tk_ok)
+if test $tk_ok = no; then
+ AC_DEFINE(NO_FD_SET)
+fi
+
+#------------------------------------------------------------------------------
+# Find out all about time handling differences.
+#------------------------------------------------------------------------------
+
+AC_CHECK_HEADERS(sys/time.h)
+AC_HEADER_TIME
+AC_STRUCT_TIMEZONE
+
+AC_MSG_CHECKING([tm_tzadj in struct tm])
+AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+ [AC_DEFINE(HAVE_TM_TZADJ)
+ AC_MSG_RESULT(yes)],
+ AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING([tm_gmtoff in struct tm])
+AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+ [AC_DEFINE(HAVE_TM_GMTOFF)
+ AC_MSG_RESULT(yes)],
+ AC_MSG_RESULT(no))
+
+#
+# Its important to include time.h in this check, as some systems (like convex)
+# have timezone functions, etc.
+#
+have_timezone=no
+AC_MSG_CHECKING([long timezone variable])
+AC_TRY_COMPILE([#include <time.h>],
+ [extern long timezone;
+ timezone += 1;
+ exit (0);],
+ [have_timezone=yes
+ AC_DEFINE(HAVE_TIMEZONE_VAR)
+ AC_MSG_RESULT(yes)],
+ AC_MSG_RESULT(no))
+
+#
+# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+#
+if test "$have_timezone" = no; then
+ AC_MSG_CHECKING([time_t timezone variable])
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern time_t timezone;
+ timezone += 1;
+ exit (0);],
+ [have_timezone=yes
+ AC_DEFINE(HAVE_TIMEZONE_VAR)
+ AC_MSG_RESULT(yes)],
+ AC_MSG_RESULT(no))
+fi
+
+#
+# On some systems (eg Solaris 2.5.1, timezone is not declared in
+# time.h unless you jump through hoops. Instead of that, we just
+# declare it ourselves when necessary.
+#
+if test "$have_timezone" = yes; then
+ AC_MSG_CHECKING(for timezone declaration)
+ changequote(<<,>>)
+ tzrx='^[ ]*extern.*timezone'
+ changequote([,])
+ AC_EGREP_HEADER($tzrx, time.h, [
+ AC_DEFINE(HAVE_TIMEZONE_DECL)
+ AC_MSG_RESULT(found)], AC_MSG_RESULT(missing))
+fi
+
+#
+# AIX does not have a timezone field in struct tm. When the AIX bsd
+# library is used, the timezone global and the gettimeofday methods are
+# to be avoided for timezone deduction instead, we deduce the timezone
+# by comparing the localtime result on a known GMT value.
+#
+if test $libbsd = yes; then
+ AC_DEFINE(USE_DELTA_FOR_TZ)
+fi
+
+#--------------------------------------------------------------------
+# Some systems (e.g., IRIX 4.0.5) lack the st_blksize field
+# in struct stat.
+#--------------------------------------------------------------------
+AC_STRUCT_ST_BLKSIZE
+
+#--------------------------------------------------------------------
+# On some systems strstr is broken: it returns a pointer even
+# even if the original string is empty.
+#--------------------------------------------------------------------
+
+AC_MSG_CHECKING([proper strstr implementation])
+AC_TRY_RUN([
+extern int strstr();
+int main()
+{
+ exit(strstr("\0test", "test") ? 1 : 0);
+}
+], tcl_ok=yes, tcl_ok=no, tcl_ok=no)
+if test $tcl_ok = yes; then
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT([broken, using substitute])
+ LIBOBJS="$LIBOBJS strstr.o"
+fi
+
+#--------------------------------------------------------------------
+# Check for strtoul function. This is tricky because under some
+# versions of AIX strtoul returns an incorrect terminator
+# pointer for the string "0".
+#--------------------------------------------------------------------
+
+AC_CHECK_FUNC(strtoul, tcl_ok=1, tcl_ok=0)
+AC_TRY_RUN([
+extern int strtoul();
+int main()
+{
+ char *string = "0";
+ char *term;
+ int value;
+ value = strtoul(string, &term, 0);
+ if ((value != 0) || (term != (string+1))) {
+ exit(1);
+ }
+ exit(0);
+}], , tcl_ok=0, tcl_ok=0)
+if test "$tcl_ok" = 0; then
+ test -n "$verbose" && echo " Adding strtoul.o."
+ LIBOBJS="$LIBOBJS strtoul.o"
+fi
+
+#--------------------------------------------------------------------
+# Check for the strtod function. This is tricky because in some
+# versions of Linux strtod mis-parses strings starting with "+".
+#--------------------------------------------------------------------
+
+AC_CHECK_FUNC(strtod, tcl_ok=1, tcl_ok=0)
+AC_TRY_RUN([
+extern double strtod();
+int main()
+{
+ char *string = " +69";
+ char *term;
+ double value;
+ value = strtod(string, &term);
+ if ((value != 69) || (term != (string+4))) {
+ exit(1);
+ }
+ exit(0);
+}], , tcl_ok=0, tcl_ok=0)
+if test "$tcl_ok" = 0; then
+ test -n "$verbose" && echo " Adding strtod.o."
+ LIBOBJS="$LIBOBJS strtod.o"
+fi
+
+#--------------------------------------------------------------------
+# Under Solaris 2.4, strtod returns the wrong value for the
+# terminating character under some conditions. Check for this
+# and if the problem exists use a substitute procedure
+# "fixstrtod" that corrects the error.
+#--------------------------------------------------------------------
+
+AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+if test "$tcl_strtod" = 1; then
+ AC_MSG_CHECKING([for Solaris strtod bug])
+ AC_TRY_RUN([
+extern double strtod();
+int main()
+{
+ char *string = "NaN";
+ char *term;
+ strtod(string, &term);
+ if ((term != string) && (term[-1] == 0)) {
+ exit(1);
+ }
+ exit(0);
+}], tcl_ok=1, tcl_ok=0, tcl_ok=0)
+ if test $tcl_ok = 1; then
+ AC_MSG_RESULT(ok)
+ else
+ AC_MSG_RESULT(buggy)
+ LIBOBJS="$LIBOBJS fixstrtod.o"
+ AC_DEFINE(strtod, fixstrtod)
+ fi
+fi
+
+#--------------------------------------------------------------------
+# Check for various typedefs and provide substitutes if
+# they don't exist.
+#--------------------------------------------------------------------
+
+AC_TYPE_MODE_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_UID_T
+
+#--------------------------------------------------------------------
+# If a system doesn't have an opendir function (man, that's old!)
+# then we have to supply a different version of dirent.h which
+# is compatible with the substitute version of opendir that's
+# provided. This version only works with V7-style directories.
+#--------------------------------------------------------------------
+
+AC_CHECK_FUNC(opendir, , AC_DEFINE(USE_DIRENT2_H))
+
+#--------------------------------------------------------------------
+# The check below checks whether <sys/wait.h> defines the type
+# "union wait" correctly. It's needed because of weirdness in
+# HP-UX where "union wait" is defined in both the BSD and SYS-V
+# environments. Checking the usability of WIFEXITED seems to do
+# the trick.
+#--------------------------------------------------------------------
+
+AC_MSG_CHECKING([union wait])
+AC_TRY_LINK([#include <sys/types.h>
+#include <sys/wait.h>], [
+union wait x;
+WIFEXITED(x); /* Generates compiler error if WIFEXITED
+ * uses an int. */
+], tcl_ok=yes, tcl_ok=no)
+AC_MSG_RESULT($tcl_ok)
+if test $tcl_ok = no; then
+ AC_DEFINE(NO_UNION_WAIT)
+fi
+
+#--------------------------------------------------------------------
+# Check to see whether the system supports the matherr function
+# and its associated type "struct exception".
+#--------------------------------------------------------------------
+
+AC_MSG_CHECKING([matherr support])
+AC_TRY_COMPILE([#include <math.h>], [
+struct exception x;
+x.type = DOMAIN;
+x.type = SING;
+], tcl_ok=yes, tcl_ok=no)
+AC_MSG_RESULT($tcl_ok)
+if test $tcl_ok = yes; then
+ AC_DEFINE(NEED_MATHERR)
+fi
+
+#--------------------------------------------------------------------
+# Check to see whether the system provides a vfork kernel call.
+# If not, then use fork instead. Also, check for a problem with
+# vforks and signals that can cause core dumps if a vforked child
+# resets a signal handler. If the problem exists, then use fork
+# instead of vfork.
+#--------------------------------------------------------------------
+
+AC_TYPE_SIGNAL()
+AC_CHECK_FUNC(vfork, tcl_ok=1, tcl_ok=0)
+if test "$tcl_ok" = 1; then
+ AC_MSG_CHECKING([vfork/signal bug]);
+ AC_TRY_RUN([
+#include <stdio.h>
+#include <signal.h>
+#include <sys/wait.h>
+int gotSignal = 0;
+sigProc(sig)
+ int sig;
+{
+ gotSignal = 1;
+}
+main()
+{
+ int pid, sts;
+ (void) signal(SIGCHLD, sigProc);
+ pid = vfork();
+ if (pid < 0) {
+ exit(1);
+ } else if (pid == 0) {
+ (void) signal(SIGCHLD, SIG_DFL);
+ _exit(0);
+ } else {
+ (void) wait(&sts);
+ }
+ exit((gotSignal) ? 0 : 1);
+}], tcl_ok=1, tcl_ok=0, tcl_ok=0)
+ if test "$tcl_ok" = 1; then
+ AC_MSG_RESULT(ok)
+ else
+ AC_MSG_RESULT([buggy, using fork instead])
+ fi
+fi
+rm -f core
+if test "$tcl_ok" = 0; then
+ AC_DEFINE(vfork, fork)
+fi
+
+#--------------------------------------------------------------------
+# Check whether there is an strncasecmp function on this system.
+# This is a bit tricky because under SCO it's in -lsocket and
+# under Sequent Dynix it's in -linet.
+#--------------------------------------------------------------------
+
+AC_CHECK_FUNC(strncasecmp, tcl_ok=1, tcl_ok=0)
+if test "$tcl_ok" = 0; then
+ AC_CHECK_LIB(socket, strncasecmp, tcl_ok=1, tcl_ok=0)
+fi
+if test "$tcl_ok" = 0; then
+ AC_CHECK_LIB(inet, strncasecmp, tcl_ok=1, tcl_ok=0)
+fi
+if test "$tcl_ok" = 0; then
+ LIBOBJS="$LIBOBJS strncasecmp.o"
+fi
+
+#--------------------------------------------------------------------
+# The code below deals with several issues related to gettimeofday:
+# 1. Some systems don't provide a gettimeofday function at all
+# (set NO_GETTOD if this is the case).
+# 2. SGI systems don't use the BSD form of the gettimeofday function,
+# but they have a BSDgettimeofday function that can be used instead.
+# 3. See if gettimeofday is declared in the <sys/time.h> header file.
+# if not, set the GETTOD_NOT_DECLARED flag so that tclPort.h can
+# declare it.
+#--------------------------------------------------------------------
+
+AC_CHECK_FUNC(BSDgettimeofday, AC_DEFINE(HAVE_BSDGETTIMEOFDAY),
+ AC_CHECK_FUNC(gettimeofday, , AC_DEFINE(NO_GETTOD)))
+AC_MSG_CHECKING([for gettimeofday declaration])
+AC_EGREP_HEADER(gettimeofday, sys/time.h, AC_MSG_RESULT(present), [
+ AC_MSG_RESULT(missing)
+ AC_DEFINE(GETTOD_NOT_DECLARED)
+])
+
+#--------------------------------------------------------------------
+# Interactive UNIX requires -linet instead of -lsocket, plus it
+# needs net/errno.h to define the socket-related error codes.
+#--------------------------------------------------------------------
+
+AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
+AC_CHECK_HEADER(net/errno.h, AC_DEFINE(HAVE_NET_ERRNO_H))
+
+#--------------------------------------------------------------------
+# The following code checks to see whether it is possible to get
+# signed chars on this platform. This is needed in order to
+# properly generate sign-extended ints from character values.
+#--------------------------------------------------------------------
+
+AC_C_CHAR_UNSIGNED
+AC_MSG_CHECKING([signed char declarations])
+AC_TRY_COMPILE(, [
+signed char *p;
+p = 0;
+], tcl_ok=yes, tcl_ok=no)
+AC_MSG_RESULT($tcl_ok)
+if test $tcl_ok = yes; then
+ AC_DEFINE(HAVE_SIGNED_CHAR)
+fi
+
+#--------------------------------------------------------------------
+# Check for the existence of the -lsocket and -lnsl libraries.
+# The order here is important, so that they end up in the right
+# order in the command line generated by make. Here are some
+# special considerations:
+# 1. Use "connect" and "accept" to check for -lsocket, and
+# "gethostbyname" to check for -lnsl.
+# 2. Use each function name only once: can't redo a check because
+# autoconf caches the results of the last check and won't redo it.
+# 3. Use -lnsl and -lsocket only if they supply procedures that
+# aren't already present in the normal libraries. This is because
+# IRIX 5.2 has libraries, but they aren't needed and they're
+# bogus: they goof up name resolution if used.
+# 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+# To get around this problem, check for both libraries together
+# if -lsocket doesn't work by itself.
+#--------------------------------------------------------------------
+
+# CYGNUS LOCAL: Store any socket library(ies) in the cache, and don't
+# mess up the cache values of the functions we check for.
+AC_CACHE_CHECK([for socket libraries], tcl_cv_lib_sockets,
+ [tcl_cv_lib_sockets=
+ tcl_checkBoth=0
+ unset ac_cv_func_connect
+ AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
+ if test "$tcl_checkSocket" = 1; then
+ unset ac_cv_func_connect
+ AC_CHECK_LIB(socket, main, tcl_cv_lib_sockets="-lsocket",
+ tcl_checkBoth=1)
+ fi
+ if test "$tcl_checkBoth" = 1; then
+ tcl_oldLibs=$LIBS
+ LIBS="$LIBS -lsocket -lnsl"
+ unset ac_cv_func_accept
+ AC_CHECK_FUNC(accept,
+ [tcl_checkNsl=0
+ tcl_cv_lib_sockets="-lsocket -lnsl"])
+ unset ac_cv_func_accept
+ LIBS=$tcl_oldLibs
+ fi
+ unset ac_cv_func_gethostbyname
+ tcl_oldLibs=$LIBS
+ LIBS="$LIBS $tcl_cv_lib_sockets"
+ AC_CHECK_FUNC(gethostbyname, ,
+ [AC_CHECK_LIB(nsl, main,
+ [tcl_cv_lib_sockets="$tcl_cv_lib_sockets -lnsl"])])
+ unset ac_cv_func_gethostbyname
+ LIBS=$tcl_oldLIBS
+])
+test -z "$tcl_cv_lib_sockets" || LIBS="$LIBS $tcl_cv_lib_sockets"
+
+#--------------------------------------------------------------------
+# The statements below define a collection of symbols related to
+# dynamic loading and shared libraries:
+#
+# DL_OBJS - Name of the object file that implements dynamic
+# loading for Tcl on this system.
+# DL_LIBS - Library file(s) to include in tclsh and other base
+# applications in order for the "load" command to work.
+# LD_FLAGS - Flags to pass to the compiler when linking object
+# files into an executable application binary such
+# as tclsh.
+# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile.
+# MAKE_LIB - Command to execute to build the Tcl library;
+# differs depending on whether or not Tcl is being
+# compiled as a shared library.
+# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
+# of a shared library (may request position-independent
+# code, among other things).
+# SHLIB_LD - Base command to use for combining object files
+# into a shared library.
+# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+# creating shared libraries. This symbol typically
+# goes at the end of the "ld" commands that build
+# shared libraries. The value of the symbol is
+# "${LIBS}" if all of the dependent libraries should
+# be specified when creating a shared library. If
+# dependent libraries should not be specified (as on
+# SunOS 4.x, where they cause the link to fail, or in
+# general if Tcl and Tk aren't themselves shared
+# libraries), then this symbol has an empty string
+# as its value.
+# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
+# extensions. An empty string means we don't know how
+# to use shared libraries on this platform.
+# TCL_LIB_FILE - Name of the file that contains the Tcl library, such
+# as libtcl7.8.so or libtcl7.8.a.
+# TCL_LIB_SUFFIX -Specifies everything that comes after the "libtcl"
+# in the shared library name, using the $VERSION variable
+# to put the version in the right place. This is used
+# by platforms that need non-standard library names.
+# Examples: ${VERSION}.so.1.1 on NetBSD, since it needs
+# to have a version after the .so, and ${VERSION}.a
+# on AIX, since the Tcl shared library needs to have
+# a .a extension whereas shared objects for loadable
+# extensions have a .so extension. Defaults to
+# ${VERSION}${SHLIB_SUFFIX}.
+#--------------------------------------------------------------------
+
+# Step 1: set the variable "system" to hold the name and version number
+# for the system. This can usually be done via the "uname" command, but
+# there are a few systems, like Next, where this doesn't work.
+
+AC_MSG_CHECKING([system version (for dynamic loading)])
+if test -f /usr/lib/NextStep/software_version; then
+ system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+else
+ system=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ AC_MSG_RESULT([unknown (can't find uname command)])
+ system=unknown
+ else
+ # Special check for weird MP-RAS system (uname returns weird
+ # results, and the version is kept in special file).
+
+ if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+ system=MP-RAS-`awk '{print $3}' /etc/.relid'`
+ fi
+ if test "`uname -s`" = "AIX" ; then
+ system=AIX-`uname -v`.`uname -r`
+ fi
+ AC_MSG_RESULT($system)
+ fi
+fi
+
+# Step 2: check for existence of -ldl library. This is needed because
+# Linux can use either -ldl or -ldld for dynamic loading.
+
+AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
+
+# Step 3: set configuration options based on system name and version.
+
+fullSrcDir=`cd $srcdir; pwd`
+TCL_SHARED_LIB_SUFFIX=""
+TCL_UNSHARED_LIB_SUFFIX=""
+TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`'
+ECHO_VERSION='`echo ${VERSION}`'
+TCL_LIB_VERSIONS_OK=ok
+case $system in
+ AIX-4.[[2-9]])
+ SHLIB_CFLAGS=""
+ SHLIB_LD="$fullSrcDir/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ AIX=yes
+ TCL_SHARED_LIB_SUFFIX='${VERSION}.a'
+ ;;
+ AIX-*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="$fullSrcDir/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o tclLoadAix.o"
+ DL_LIBS="-lld"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ TCL_SHARED_LIB_SUFFIX='${VERSION}.a'
+ ;;
+ BSD/OS-2.1*|BSD/OS-3*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="shlicc -r"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ dgux*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
+ # CYGNUS LOCAL: Handle gcc and versions of HP-UX that can't
+ # do dynamic linking.
+ AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ if test "$GCC" = yes; then
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="$CC -shared -fPIC"
+ else
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+ fi
+
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".sl"
+ DL_OBJS="tclLoadShl.o"
+ DL_LIBS="-ldld"
+
+ # The GNU linker requires the -export-dynamic
+ # option to make all symbols visible in the dynamic symbol
+ # table. Note that the HP linker will give errors
+ # -export-dynamic, but will still exit successfully.
+ # Adding a -L option will make it fail.
+ hold_ldflags=$LDFLAGS
+ AC_MSG_CHECKING(for the ld -export-dynamic flag)
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic -L`pwd`"
+ AC_TRY_LINK(, [int i;], found=yes, found=no)
+ LDFLAGS=$hold_ldflags
+ AC_MSG_RESULT($found)
+ if test $found = yes; then
+ LD_FLAGS="-Wl,-export-dynamic"
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ else
+ LD_FLAGS="-Wl,-E"
+ LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ fi
+ fi
+ # END CYGNUS LOCAL
+ ;;
+ IRIX-4.*)
+ SHLIB_CFLAGS="-G 0"
+ SHLIB_SUFFIX=".a"
+ SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
+ SHLIB_LD_LIBS='${LIBS}'
+ DL_OBJS="tclLoadAout.o"
+ DL_LIBS=""
+ LD_FLAGS="-Wl,-D,08000000"
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ TCL_SHARED_LIB_SUFFIX='${VERSION}.a'
+ ;;
+ IRIX-5.*|IRIX-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ ;;
+ IRIX64-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared -rpath /usr/local/lib"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ ;;
+ Linux*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ if test "$have_dl" = yes; then
+ SHLIB_LD="${CC} -shared"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS="-rdynamic"
+ LD_SEARCH_FLAGS=""
+ else
+ AC_CHECK_HEADER(dld.h, [
+ SHLIB_LD="ld -shared"
+ DL_OBJS="tclLoadDld.o"
+ DL_LIBS="-ldld"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""])
+ fi
+ ;;
+ MP-RAS-02*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ MP-RAS-*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS="-Wl,-Bexport"
+ LD_SEARCH_FLAGS=""
+ ;;
+ NetBSD-*|FreeBSD-*|OpenBSD-*)
+ # Not available on all versions: check for include file.
+ AC_CHECK_HEADER(dlfcn.h, [
+ SHLIB_CFLAGS="-fpic"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ TCL_SHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.so.1.0'
+ ], [
+ SHLIB_CFLAGS=""
+ SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".a"
+ DL_OBJS="tclLoadAout.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ TCL_SHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.a'
+ ])
+
+ # FreeBSD doesn't handle version numbers with dots.
+
+ TCL_UNSHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.a'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ NEXTSTEP-*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="cc -nostdlib -r"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadNext.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ OSF1-1.0|OSF1-1.1|OSF1-1.2)
+ # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
+ SHLIB_CFLAGS=""
+ # Hack: make package name same as library name
+ SHLIB_LD='ld -R -export $@:'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadOSF.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ OSF1-1.*)
+ # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
+ SHLIB_CFLAGS="-fpic"
+ SHLIB_LD="ld -shared"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ OSF1-V*)
+ # Digital OSF/1
+ SHLIB_CFLAGS=""
+ SHLIB_LD='ld -shared -expect_unresolved "*"'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ ;;
+ RISCos-*)
+ SHLIB_CFLAGS="-G 0"
+ SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".a"
+ DL_OBJS="tclLoadAout.o"
+ DL_LIBS=""
+ LD_FLAGS="-Wl,-D,08000000"
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ ;;
+ SCO_SV-3.2*)
+ # Note, dlopen is available only on SCO 3.2.5 and greater. However,
+ # this test works, since "uname -s" was non-standard in 3.2.4 and
+ # below.
+ SHLIB_CFLAGS="-Kpic -belf"
+ SHLIB_LD="ld -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS=""
+ LD_FLAGS="-belf -Wl,-Bexport"
+ LD_SEARCH_FLAGS=""
+ ;;
+ SINIX*5.4*)
+ SHLIB_CFLAGS="-K PIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SunOS-4*)
+ # CYGNUS LOCAL: gcc uses a different option than native cc.
+ if test "$GCC" = yes; then
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="$CC -shared -fPIC"
+ else
+ SHLIB_CFLAGS="-PIC"
+ SHLIB_LD="ld"
+ fi
+ # END CYGNUS LOCAL
+
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+
+ # SunOS can't handle version numbers with dots in them in library
+ # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it
+ # requires an extra version number at the end of .so file names.
+ # So, the library has to have a name like libtcl75.so.1.0
+
+ TCL_SHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.so.1.0'
+ TCL_UNSHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.a'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ SunOS-5*)
+ # CYGNUS LOCAL: gcc uses a different option than native cc.
+ if test "$GCC" = yes; then
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="$CC -shared -fPIC"
+ else
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ fi
+ # END CYGNUS LOCAL
+
+ # Note: need the LIBS below, otherwise Tk won't find Tcl's
+ # symbols when dynamically loaded into tclsh.
+
+ SHLIB_LD_LIBS='${LIBS}'
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ # CYGNUS LOCAL: The GNU linker requires the -export-dynamic
+ # option to make all symbols visible in the dynamic symbol
+ # table.
+ hold_ldflags=$LDFLAGS
+ AC_MSG_CHECKING(for the ld -export-dynamic flag)
+ LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
+ AC_TRY_LINK(, [int i;], found=yes, found=no)
+ LDFLAGS=$hold_ldflags
+ AC_MSG_RESULT($found)
+ if test $found = yes; then
+ LD_FLAGS="-Wl,-export-dynamic"
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ else
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ fi
+ # END CYGNUS LOCAL
+ ;;
+ ULTRIX-4.*)
+ SHLIB_CFLAGS="-G 0"
+ SHLIB_SUFFIX=".a"
+ SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
+ SHLIB_LD_LIBS='${LIBS}'
+ DL_OBJS="tclLoadAout.o"
+ DL_LIBS=""
+ # CYGNUS LOCAL: The GNU linker doesn't accept `-D 08000000'. It
+ # doesn't appear to be needed, either.
+ hold_ldflags="$LDFLAGS"
+ AC_MSG_CHECKING(whether ld accepts -D 08000000)
+ LD_FLAGS="-Wl,-D,08000000"
+ LDFLAGS="${LDFLAGS} -Wl,-D,08000000"
+ AC_TRY_LINK(, [int i;], found=yes, found=no)
+ LDFLAGS=$hold_ldflags
+ AC_MSG_RESULT($found)
+ if test $found = yes; then
+ LD_FLAGS="-Wl,-D,08000000"
+ else
+ LD_FLAGS=""
+ fi
+ # END CYGNUS LOCAL
+ LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ ;;
+ UNIX_SV* | UnixWare-5*)
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD="cc -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ DL_OBJS="tclLoadDl.o"
+ DL_LIBS="-ldl"
+ # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+ # that don't grok the -Bexport option. Test that it does.
+ hold_ldflags=$LDFLAGS
+ AC_MSG_CHECKING(for ld accepts -Bexport flag)
+ LDFLAGS="${LDFLAGS} -Wl,-Bexport"
+ AC_TRY_LINK(, [int i;], found=yes, found=no)
+ LDFLAGS=$hold_ldflags
+ AC_MSG_RESULT($found)
+ if test $found = yes; then
+ LD_FLAGS="-Wl,-Bexport"
+ else
+ LD_FLAGS=""
+ fi
+ LD_SEARCH_FLAGS=""
+ ;;
+esac
+
+# Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic
+# Loading for Tcl -- What Became of It?". Proc. 2nd Tcl/Tk Workshop,
+# New Orleans, LA, Computerized Processes Unlimited, 1994), then we need
+# to determine which of several header files defines the a.out file
+# format (a.out.h, sys/exec.h, or sys/exec_aout.h). At present, we
+# support only a file format that is more or less version-7-compatible.
+# In particular,
+# - a.out files must begin with `struct exec'.
+# - the N_TXTOFF on the `struct exec' must compute the seek address
+# of the text segment
+# - The `struct exec' must contain a_magic, a_text, a_data, a_bss
+# and a_entry fields.
+# The following compilation should succeed if and only if either sys/exec.h
+# or a.out.h is usable for the purpose.
+#
+# Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the
+# `struct exec' includes a second header that contains information that
+# duplicates the v7 fields that are needed.
+
+if test "x$DL_OBJS" = "xtclLoadAout.o" ; then
+ AC_MSG_CHECKING(sys/exec.h)
+ AC_TRY_COMPILE([#include <sys/exec.h>],[
+ struct exec foo;
+ unsigned long seek;
+ int flag;
+#if defined(__mips) || defined(mips)
+ seek = N_TXTOFF (foo.ex_f, foo.ex_o);
+#else
+ seek = N_TXTOFF (foo);
+#endif
+ flag = (foo.a_magic == OMAGIC);
+ return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
+], tcl_ok=usable, tcl_ok=unusable)
+ AC_MSG_RESULT($tcl_ok)
+ if test $tcl_ok = usable; then
+ AC_DEFINE(USE_SYS_EXEC_H)
+ else
+ AC_MSG_CHECKING(a.out.h)
+ AC_TRY_COMPILE([#include <a.out.h>],[
+ struct exec foo;
+ unsigned long seek;
+ int flag;
+#if defined(__mips) || defined(mips)
+ seek = N_TXTOFF (foo.ex_f, foo.ex_o);
+#else
+ seek = N_TXTOFF (foo);
+#endif
+ flag = (foo.a_magic == OMAGIC);
+ return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
+ ], tcl_ok=usable, tcl_ok=unusable)
+ AC_MSG_RESULT($tcl_ok)
+ if test $tcl_ok = usable; then
+ AC_DEFINE(USE_A_OUT_H)
+ else
+ AC_MSG_CHECKING(sys/exec_aout.h)
+ AC_TRY_COMPILE([#include <sys/exec_aout.h>],[
+ struct exec foo;
+ unsigned long seek;
+ int flag;
+#if defined(__mips) || defined(mips)
+ seek = N_TXTOFF (foo.ex_f, foo.ex_o);
+#else
+ seek = N_TXTOFF (foo);
+#endif
+ flag = (foo.a_midmag == OMAGIC);
+ return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
+ ], tcl_ok=usable, tcl_ok=unusable)
+ AC_MSG_RESULT($tcl_ok)
+ if test $tcl_ok = usable; then
+ AC_DEFINE(USE_SYS_EXEC_AOUT_H)
+ else
+ DL_OBJS=""
+ fi
+ fi
+ fi
+fi
+
+# Step 5: disable dynamic loading if requested via a command-line switch.
+
+AC_ARG_ENABLE(load, [ --disable-load disallow dynamic loading and "load" command],
+ [tcl_ok=$enableval], [tcl_ok=yes])
+if test "$tcl_ok" = "no"; then
+ DL_OBJS=""
+fi
+
+if test "x$DL_OBJS" != "x" ; then
+ BUILD_DLTEST="\$(DLTEST_TARGETS)"
+else
+ echo "Can't figure out how to do dynamic loading or shared libraries"
+ echo "on this system."
+ SHLIB_CFLAGS=""
+ SHLIB_LD=""
+ SHLIB_SUFFIX=""
+ DL_OBJS="tclLoadNone.o"
+ DL_LIBS=""
+ LD_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ BUILD_DLTEST=""
+fi
+
+# If we're running gcc, then change the C flags for compiling shared
+# libraries to the right flags for gcc, instead of those for the
+# standard manufacturer compiler.
+
+if test "$DL_OBJS" != "tclLoadNone.o" ; then
+ if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then
+ case $system in
+ AIX-*)
+ ;;
+ BSD/OS*)
+ ;;
+ IRIX*)
+ ;;
+ NetBSD-*|FreeBSD-*|OpenBSD-*)
+ ;;
+ RISCos-*)
+ ;;
+ ULTRIX-4.*)
+ ;;
+ *)
+ SHLIB_CFLAGS="-fPIC"
+ ;;
+ esac
+ fi
+fi
+
+#--------------------------------------------------------------------
+# The statements below check for systems where POSIX-style
+# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+# On these systems (mostly older ones), use the old BSD-style
+# FIONBIO approach instead.
+#--------------------------------------------------------------------
+
+AC_CHECK_HEADERS(sys/ioctl.h)
+AC_CHECK_HEADERS(sys/filio.h)
+AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+if test -f /usr/lib/NextStep/software_version; then
+ system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
+else
+ system=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ system=unknown
+ else
+ # Special check for weird MP-RAS system (uname returns weird
+ # results, and the version is kept in special file).
+
+ if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
+ system=MP-RAS-`awk '{print $3}' /etc/.relid'`
+ fi
+ if test "`uname -s`" = "AIX" ; then
+ system=AIX-`uname -v`.`uname -r`
+ fi
+ fi
+fi
+case $system in
+ # There used to be code here to use FIONBIO under AIX. However, it
+ # was reported that FIONBIO doesn't work under AIX 3.2.5. Since
+ # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
+ # code (JO, 5/31/97).
+
+ OSF*)
+ AC_DEFINE(USE_FIONBIO)
+ AC_MSG_RESULT(FIONBIO)
+ ;;
+ SunOS-4*)
+ AC_DEFINE(USE_FIONBIO)
+ AC_MSG_RESULT(FIONBIO)
+ ;;
+ ULTRIX-4.*)
+ AC_DEFINE(USE_FIONBIO)
+ AC_MSG_RESULT(FIONBIO)
+ ;;
+ *)
+ AC_MSG_RESULT(O_NONBLOCK)
+ ;;
+esac
+
+#--------------------------------------------------------------------
+# The statements below define a collection of symbols related to
+# building libtcl as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+realRanlib=$RANLIB
+if test "$TCL_SHARED_LIB_SUFFIX" = "" ; then
+ TCL_SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'
+fi
+if test "$TCL_UNSHARED_LIB_SUFFIX" = "" ; then
+ TCL_UNSHARED_LIB_SUFFIX='${VERSION}.a'
+fi
+AC_ARG_ENABLE(shared,
+ [ --enable-shared build libtcl as a shared library],
+ [tcl_ok=$enableval], [tcl_ok=no])
+# CYGNUS LOCAL: need extra variables for this information.
+TCL_SHARED_LIB_FILE=dummy1
+TCL_UNSHARED_LIB_FILE=dummy2
+# END CYGNUS LOCAL
+if test "$tcl_ok" = "yes" -a "${SHLIB_SUFFIX}" != "" ; then
+ TCL_SHARED_BUILD=1
+ TCL_SHLIB_CFLAGS="${SHLIB_CFLAGS}"
+ TCL_LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS}"
+ eval "TCL_LIB_FILE=libtcl${TCL_SHARED_LIB_SUFFIX}"
+ TCL_SHARED_LIB_FILE="$TCL_LIB_FILE"
+ if test "x$DL_OBJS" = "xtclLoadAout.o"; then
+ MAKE_LIB="ar cr \${TCL_LIB_FILE} \${OBJS}"
+ else
+ MAKE_LIB="\${SHLIB_LD} -o \${TCL_LIB_FILE} \${OBJS} ${SHLIB_LD_LIBS}"
+ RANLIB=":"
+ fi
+else
+ TCL_SHARED_BUILD=0
+ case $system in
+ BSD/OS*)
+ ;;
+
+ AIX-*)
+ ;;
+
+ *)
+ SHLIB_LD_LIBS=""
+ ;;
+ esac
+ TCL_SHLIB_CFLAGS=""
+ TCL_LD_SEARCH_FLAGS=""
+ eval "TCL_LIB_FILE=libtcl${TCL_UNSHARED_LIB_SUFFIX}"
+ TCL_UNSHARED_LIB_FILE="$TCL_LIB_FILE"
+ MAKE_LIB="$AR cr ${TCL_LIB_FILE} \${OBJS}"
+fi
+
+# Note: in the following variable, it's important to use the absolute
+# path name of the Tcl directory rather than "..": this is because
+# AIX remembers this path and will attempt to use it at run-time to look
+# up the Tcl library.
+
+if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+ TCL_BUILD_LIB_SPEC="-L`pwd` -ltcl${VERSION}"
+ TCL_LIB_SPEC="-L${exec_prefix}/lib -ltcl${VERSION}"
+else
+ TCL_BUILD_LIB_SPEC="-L`pwd` -ltcl`echo ${VERSION} | tr -d .`"
+ TCL_LIB_SPEC="-L${exec_prefix}/lib -ltcl`echo ${VERSION} | tr -d .`"
+fi
+
+TCL_LIB_FULL_PATH="`pwd`/${TCL_LIB_FILE}"
+
+#--------------------------------------------------------------------
+# The statements below define the symbol TCL_PACKAGE_PATH, which
+# gives a list of directories that may contain packages. The list
+# consists of one directory for machine-dependent binaries and
+# another for platform-independent scripts.
+#--------------------------------------------------------------------
+
+if test "$prefix" != "$exec_prefix"; then
+ TCL_PACKAGE_PATH="${exec_prefix}/lib ${prefix}/lib"
+else
+ TCL_PACKAGE_PATH="${prefix}/lib"
+fi
+
+AC_SUBST(BUILD_DLTEST)
+AC_SUBST(DL_LIBS)
+AC_SUBST(DL_OBJS)
+AC_SUBST(LD_FLAGS)
+AC_SUBST(MAKE_LIB)
+AC_SUBST(MATH_LIBS)
+AC_SUBST(SHLIB_CFLAGS)
+AC_SUBST(SHLIB_LD)
+AC_SUBST(SHLIB_LD_LIBS)
+AC_SUBST(SHLIB_SUFFIX)
+AC_SUBST(TCL_BUILD_LIB_SPEC)
+AC_SUBST(TCL_LD_SEARCH_FLAGS)
+AC_SUBST(TCL_LIB_FILE)
+AC_SUBST(TCL_LIB_FULL_PATH)
+AC_SUBST(TCL_LIB_FLAG)
+AC_SUBST(TCL_LIB_SPEC)
+AC_SUBST(TCL_LIB_VERSIONS_OK)
+AC_SUBST(TCL_MAJOR_VERSION)
+AC_SUBST(TCL_MINOR_VERSION)
+AC_SUBST(TCL_PACKAGE_PATH)
+AC_SUBST(TCL_PATCH_LEVEL)
+AC_SUBST(TCL_SHARED_LIB_SUFFIX)
+AC_SUBST(TCL_SHARED_BUILD)
+AC_SUBST(TCL_SHLIB_CFLAGS)
+AC_SUBST(TCL_SRC_DIR)
+AC_SUBST(TCL_UNSHARED_LIB_SUFFIX)
+AC_SUBST(TCL_VERSION)
+# CYGNUS LOCAL
+AC_SUBST(TCL_SHARED_LIB_FILE)
+AC_SUBST(TCL_UNSHARED_LIB_FILE)
+# END CYGNUS LOCAL
+
+AC_OUTPUT(Makefile tclConfig.sh)
diff --git a/tcl/cygwin/tclConfig.sh.in b/tcl/cygwin/tclConfig.sh.in
new file mode 100644
index 00000000000..c005c2e9995
--- /dev/null
+++ b/tcl/cygwin/tclConfig.sh.in
@@ -0,0 +1,133 @@
+# tclConfig.sh --
+#
+# This shell script (for sh) is generated automatically by Tcl's
+# configure script. It will create shell variables for most of
+# the configuration options discovered by the configure script.
+# This script is intended to be included by the configure scripts
+# for Tcl extensions so that they don't have to figure this all
+# out for themselves.
+#
+# The information in this file is specific to a single platform.
+#
+# RCS: @(#) $Id$
+
+# Tcl's version number.
+TCL_VERSION='@TCL_VERSION@'
+TCL_MAJOR_VERSION='@TCL_MAJOR_VERSION@'
+TCL_MINOR_VERSION='@TCL_MINOR_VERSION@'
+TCL_PATCH_LEVEL='@TCL_PATCH_LEVEL@'
+
+# C compiler to use for compilation.
+TCL_CC='@CC@'
+
+# -D flags for use with the C compiler.
+TCL_DEFS='@DEFS@'
+
+# If TCL was built with debugging symbols, generated libraries contain
+# this string at the end of the library name (before the extension).
+TCL_DBGX=@TCL_DBGX@
+
+# Default flags used in an optimized and debuggable build, respectively.
+TCL_CFLAGS_DEBUG='@CFLAGS_DEBUG@'
+TCL_CFLAGS_OPTIMIZE='@CFLAGS_OPTIMIZE@'
+
+# Flag, 1: we built a shared lib, 0 we didn't
+TCL_SHARED_BUILD=@TCL_SHARED_BUILD@
+
+# The name of the Tcl library (may be either a .a file or a shared library):
+TCL_LIB_FILE='@TCL_LIB_FILE@'
+
+# The fullpath of the Tcl library (used for dependency checking)
+TCL_LIB_FULL_PATH='@TCL_LIB_FULL_PATH@'
+
+# Additional libraries to use when linking Tcl.
+TCL_LIBS='@DL_LIBS@ @LIBS@ @MATH_LIBS@'
+
+# Top-level directory in which Tcl's platform-independent files are
+# installed.
+TCL_PREFIX='@prefix@'
+
+# Top-level directory in which Tcl's platform-specific files (e.g.
+# executables) are installed.
+TCL_EXEC_PREFIX='@exec_prefix@'
+
+# Flags to pass to cc when compiling the components of a shared library:
+TCL_SHLIB_CFLAGS='@SHLIB_CFLAGS@'
+
+# Extra flags to pass to cc:
+TCL_EXTRA_CFLAGS='@EXTRA_CFLAGS@'
+
+# Base command to use for combining object files into a shared library:
+TCL_SHLIB_LD='@SHLIB_LD@'
+
+# Either '$LIBS' (if dependent libraries should be included when linking
+# shared libraries) or an empty string. See Tcl's configure.in for more
+# explanation.
+TCL_SHLIB_LD_LIBS='@SHLIB_LD_LIBS@'
+
+# Suffix to use for the name of a shared library.
+TCL_SHLIB_SUFFIX='@SHLIB_SUFFIX@'
+
+# Library file(s) to include in tclsh and other base applications
+# in order to provide facilities needed by DLOBJ above.
+TCL_DL_LIBS='@DL_LIBS@'
+
+# Flags to pass to the compiler when linking object files into
+# an executable tclsh or tcltest binary.
+TCL_LD_FLAGS='@LD_FLAGS@'
+
+# Flags to pass to ld, such as "-R /usr/local/tcl/lib", that tell the
+# run-time dynamic linker where to look for shared libraries such as
+# libtcl.so. Used when linking applications. Only works if there
+# is a variable "LIB_RUNTIME_DIR" defined in the Makefile.
+TCL_LD_SEARCH_FLAGS='@TCL_LD_SEARCH_FLAGS@'
+
+# Additional object files linked with Tcl to provide compatibility
+# with standard facilities from ANSI C or POSIX.
+TCL_COMPAT_OBJS='@LIBOBJS@'
+
+# Name of the ranlib program to use.
+TCL_RANLIB='@RANLIB@'
+
+# -l flag to pass to the linker to pick up the Tcl library
+TCL_LIB_FLAG='@TCL_LIB_FLAG@'
+
+# String to pass to linker to pick up the Tcl library from its
+# build directory.
+TCL_BUILD_LIB_SPEC='@TCL_BUILD_LIB_SPEC@'
+
+# String to pass to linker to pick up the Tcl library from its
+# installed directory.
+TCL_LIB_SPEC='@TCL_LIB_SPEC@'
+
+# Indicates whether a version numbers should be used in -l switches
+# ("ok" means it's safe to use switches like -ltcl7.5; "nodots" means
+# use switches like -ltcl75). SunOS and FreeBSD require "nodots", for
+# example.
+TCL_LIB_VERSIONS_OK='@TCL_LIB_VERSIONS_OK@'
+
+# String that can be evaluated to generate the part of a shared library
+# name that comes after the "libxxx" (includes version number, if any,
+# extension, and anything else needed). May depend on the variables
+# VERSION and SHLIB_SUFFIX. On most UNIX systems this is
+# ${VERSION}${SHLIB_SUFFIX}.
+TCL_SHARED_LIB_SUFFIX='@TCL_SHARED_LIB_SUFFIX@'
+
+# String that can be evaluated to generate the part of an unshared library
+# name that comes after the "libxxx" (includes version number, if any,
+# extension, and anything else needed). May depend on the variable
+# VERSION. On most UNIX systems this is ${VERSION}.a.
+TCL_UNSHARED_LIB_SUFFIX='@TCL_UNSHARED_LIB_SUFFIX@'
+
+# Location of the top-level source directory from which Tcl was built.
+# This is the directory that contains a README file as well as
+# subdirectories such as generic, unix, etc. If Tcl was compiled in a
+# different place than the directory containing the source files, this
+# points to the location of the sources, not the location where Tcl was
+# compiled.
+TCL_SRC_DIR='@TCL_SRC_DIR@'
+
+# List of standard directories in which to look for packages during
+# "package require" commands. Contains the "prefix" directory plus also
+# the "exec_prefix" directory, if it is different.
+TCL_PACKAGE_PATH='@TCL_PACKAGE_PATH@'
diff --git a/tcl/doc/EvalObj.3 b/tcl/doc/EvalObj.3
new file mode 100644
index 00000000000..f7cdaae28b0
--- /dev/null
+++ b/tcl/doc/EvalObj.3
@@ -0,0 +1,91 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: @(#) $Id$
+'\"
+.so man.macros
+.TH Tcl_EvalObj 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_EvalObj, Tcl_GlobalEvalObj \- execute Tcl commands
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_EvalObj\fR(\fIinterp, objPtr\fR)
+.sp
+int
+\fBTcl_GlobalEvalObj\fR(\fIinterp, objPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp **termPtr;
+.AP Tcl_Interp *interp in
+Interpreter in which to execute the command.
+The command's result will be stored in the interpreter's result object
+and can be retrieved using \fBTcl_GetObjResult\fR.
+.AP Tcl_Obj *objPtr in
+A Tcl object containing a command string
+(or sequence of commands in a string) to execute.
+.BE
+
+.SH DESCRIPTION
+.PP
+These two procedures execute Tcl commands.
+\fBTcl_EvalObj\fR is the core procedure
+and is used by \fBTcl_GlobalEvalObj\fR.
+It executes the commands in the script held by \fIobjPtr\fR
+until either an error occurs or it reaches the end of the script.
+If this is the first time \fIobjPtr\fR has been executed,
+its commands are compiled into bytecode instructions
+that are then executed if there are no compilation errors.
+.PP
+The return value from \fBTcl_EvalObj\fR is one of the Tcl return codes
+\fBTCL_OK\fR, \fBTCL_ERROR\fR, \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or
+\fBTCL_CONTINUE\fR,
+and a result object containing additional information
+(a result value or error message)
+that can be retrieved using \fBTcl_GetObjResult\fR.
+If an error occurs during compilation, this return information
+describes the error.
+Otherwise, this return information corresponds to the last command
+executed from \fIobjPtr\fR.
+.PP
+\fBTcl_GlobalEvalObj\fR is similar to \fBTcl_EvalObj\fR except that it
+processes the command at global level.
+This means that the variable context for the command consists of
+global variables only (it ignores any Tcl procedure that is active).
+This produces an effect similar to the Tcl command ``\fBuplevel 0\fR''.
+.PP
+During the processing of a Tcl command it is legal to make nested
+calls to evaluate other commands (this is how procedures and
+some control structures are implemented).
+If a code other than \fBTCL_OK\fR is returned
+from a nested \fBTcl_EvalObj\fR invocation,
+then the caller should normally return immediately,
+passing that same return code back to its caller,
+and so on until the top-level application is reached.
+A few commands, like \fBfor\fR, will check for certain
+return codes, like \fBTCL_BREAK\fR and \fBTCL_CONTINUE\fR, and process them
+specially without returning.
+.PP
+\fBTcl_EvalObj\fR keeps track of how many nested \fBTcl_EvalObj\fR
+invocations are in progress for \fIinterp\fR.
+If a code of \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR is
+about to be returned from the topmost \fBTcl_EvalObj\fR
+invocation for \fIinterp\fR,
+it converts the return code to \fBTCL_ERROR\fR
+and sets the interpreter's result object
+to point to an error message indicating that
+the \fBreturn\fR, \fBbreak\fR, or \fBcontinue\fR command was
+invoked in an inappropriate place.
+This means that top-level applications should never see a return code
+from \fBTcl_EvalObj\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR.
+
+.SH "SEE ALSO"
+Tcl_GetObjResult, Tcl_SetObjResult
+
+.SH KEYWORDS
+command, execute, file, global, object, object result, variable
diff --git a/tcl/doc/ObjSetVar.3 b/tcl/doc/ObjSetVar.3
new file mode 100644
index 00000000000..71e947fe3e5
--- /dev/null
+++ b/tcl/doc/ObjSetVar.3
@@ -0,0 +1,162 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" RCS: @(#) $Id$
+'\"
+.so man.macros
+.TH Tcl_ObjSetVar2 3 8.0 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_ObjSetVar2, Tcl_ObjGetVar2 \- manipulate Tcl variables
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_ObjSetVar2\fR(\fIinterp, part1Ptr, part2Ptr, newValuePtr, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ObjGetVar2\fR(\fIinterp, part1Ptr, part2Ptr, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *newValuePtr
+.AP Tcl_Interp *interp in
+Interpreter containing variable.
+.AP Tcl_Obj *part1Ptr in
+Points to a Tcl object containing the variable's name.
+The name may include a series of \fB::\fR namespace qualifiers
+to specify a variable in a particular namespace.
+May refer to a scalar variable or an element of an array variable.
+.AP Tcl_Obj *part2Ptr in
+If non-NULL, points to an object containing the name of an element
+within an array and \fIpart1Ptr\fR must refer to an array variable.
+.AP Tcl_Obj *newValuePtr in
+Points to a Tcl object containing the new value for the variable.
+.AP int flags in
+OR-ed combination of bits providing additional information for
+operation. See below for valid values.
+.BE
+
+.SH DESCRIPTION
+.PP
+These two procedures may be used to read and modify
+Tcl variables from C code.
+\fBTcl_ObjSetVar2\fR will create a new variable or modify an existing one.
+It sets the specified variable to
+the object referenced by \fInewValuePtr\fR
+and returns a pointer to the object which is the variable's new value.
+The returned object may not be the same one
+referenced by \fInewValuePtr\fR;
+this might happen because variable traces may modify the variable's value.
+The reference count for the variable's old value is decremented
+and the reference count for its new value is incremented.
+If the new value for the variable
+is not the same one referenced by \fInewValuePtr\fR
+(perhaps as a result of a variable trace),
+then \fInewValuePtr\fR's reference count is left unchanged.
+The reference count for the returned object is not incremented
+to reflect the returned reference.
+If the caller needs to keep a reference to the object,
+say in a data structure,
+it must increment its reference count using \fBTcl_IncrRefCount\fR.
+If an error occurs in setting the variable
+(e.g. an array variable is referenced
+without giving an index into the array),
+then NULL is returned.
+.PP
+The variable name specified to \fBTcl_ObjSetVar2\fR consists of two parts.
+\fIpart1Ptr\fR contains the name of a scalar or array variable.
+If \fIpart2Ptr\fR is NULL, the variable must be a scalar.
+If \fIpart2Ptr\fR is not NULL,
+it contains the name of an element in the array named by \fIpart2Ptr\fR.
+As a special case, if the flag TCL_PARSE_PART1 is specified,
+\fIpart1Ptr\fR may contain both an array and an element name:
+if the name contains an open parenthesis and ends with a
+close parenthesis, then the value between the parentheses is
+treated as an element name (which can have any string value) and
+the characters before the first open
+parenthesis are treated as the name of an array variable.
+If the flag TCL_PARSE_PART1 is given,
+\fIpart2Ptr\fR should be NULL since the array and element names
+are taken from \fIpart2Ptr\fR.
+.PP
+The \fIflags\fR argument may be used to specify any of several
+options to the procedures.
+It consists of an OR-ed combination of any of the following
+bits:
+.TP
+\fBTCL_GLOBAL_ONLY\fR
+Under normal circumstances the procedures look up variables as follows:
+If a procedure call is active in \fIinterp\fR,
+a variable is looked up at the current level of procedure call.
+Otherwise, a variable is looked up first in the current namespace,
+then in the global namespace.
+However, if this bit is set in \fIflags\fR then the variable
+is looked up only in the global namespace
+even if there is a procedure call active.
+If both \fBTCL_GLOBAL_ONLY\fR and \fBTCL_NAMESPACE_ONLY\fR are given,
+\fBTCL_GLOBAL_ONLY\fR is ignored.
+.TP
+\fBTCL_NAMESPACE_ONLY\fR
+Under normal circumstances the procedures look up variables as follows:
+If a procedure call is active in \fIinterp\fR,
+a variable is looked up at the current level of procedure call.
+Otherwise, a variable is looked up first in the current namespace,
+then in the global namespace.
+However, if this bit is set in \fIflags\fR then the variable
+is looked up only in the current namespace
+even if there is a procedure call active.
+.TP
+\fBTCL_LEAVE_ERR_MSG\fR
+If an error is returned and this bit is set in \fIflags\fR, then
+an error message will be left in the interpreter's result,
+where it can be retrieved with \fBTcl_GetObjResult\fR
+or \fBTcl_GetStringResult\fR.
+If this flag bit isn't set then no error message is left
+and the interpreter's result will not be modified.
+.TP
+\fBTCL_APPEND_VALUE\fR
+If this bit is set then \fInewValuePtr\fR is appended to the current
+value, instead of replacing it.
+If the variable is currently undefined, then this bit is ignored.
+.TP
+\fBTCL_LIST_ELEMENT\fR
+If this bit is set, then \fInewValuePtr\fR is converted to a valid
+Tcl list element before setting (or appending to) the variable.
+A separator space is appended before the new list element unless
+the list element is going to be the first element in a list or
+sublist (i.e. the variable's current value is empty, or contains
+the single character ``{'', or ends in `` }'').
+.TP
+\fBTCL_PARSE_PART1\fR
+If this bit is set,
+then \fBTcl_ObjGetVar2\fR and \fBTcl_ObjSetVar2\fR
+will parse \fIpart1Ptr\fR
+to obtain both an array name and an element name.
+If the name in \fIpart1Ptr\fR contains an open parenthesis
+and ends with a close parenthesis,
+the name is treated as the name of an element of an array;
+otherwise, the name in \fIpart1Ptr\fR
+is interpreted as the name of a scalar variable.
+When this bit is set,
+\fIpart2Ptr\fR is ignored.
+.PP
+\fBTcl_ObjGetVar2\fR returns the value of the specified variable.
+Its arguments are treated the same way as those for \fBTcl_ObjSetVar2\fR.
+It returns a pointer to the object which is the variable's value.
+The reference count for the returned object is not incremented.
+If the caller needs to keep a reference to the object,
+say in a data structure,
+it must increment the reference count using \fBTcl_IncrRefCount\fR.
+If an error occurs in setting the variable
+(e.g. an array variable is referenced
+without giving an index into the array),
+then NULL is returned.
+
+.SH "SEE ALSO"
+Tcl_GetObjResult, Tcl_GetStringResult, Tcl_GetVar, Tcl_GetVar2, Tcl_SetVar, Tcl_SetVar2, Tcl_TraceVar, Tcl_UnsetVar, Tcl_UnsetVar2
+
+.SH KEYWORDS
+array, interpreter, object, scalar, set, unset, variable
diff --git a/tcl/generic/panic.c b/tcl/generic/panic.c
new file mode 100644
index 00000000000..99cf39b8ccc
--- /dev/null
+++ b/tcl/generic/panic.c
@@ -0,0 +1,99 @@
+/*
+ * panic.c --
+ *
+ * Source code for the "panic" library procedure for Tcl;
+ * individual applications will probably override this with
+ * an application-specific panic procedure.
+ *
+ * Copyright (c) 1988-1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id$
+ */
+
+#include <stdio.h>
+#ifdef NO_STDLIB_H
+# include "../compat/stdlib.h"
+#else
+# include <stdlib.h>
+#endif
+
+#define panic panicDummy
+#include "tcl.h"
+#undef panic
+
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLEXPORT
+
+EXTERN void panic _ANSI_ARGS_((char *format, char *arg1,
+ char *arg2, char *arg3, char *arg4, char *arg5,
+ char *arg6, char *arg7, char *arg8));
+
+/*
+ * The panicProc variable contains a pointer to an application
+ * specific panic procedure.
+ */
+
+void (*panicProc) _ANSI_ARGS_(TCL_VARARGS(char *,format)) = NULL;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetPanicProc --
+ *
+ * Replace the default panic behavior with the specified functiion.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Sets the panicProc variable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetPanicProc(proc)
+ void (*proc) _ANSI_ARGS_(TCL_VARARGS(char *,format));
+{
+ panicProc = proc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * panic --
+ *
+ * Print an error message and kill the process.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The process dies, entering the debugger if possible.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ /* VARARGS ARGSUSED */
+void
+panic(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+ char *format; /* Format string, suitable for passing to
+ * fprintf. */
+ char *arg1, *arg2, *arg3; /* Additional arguments (variable in number)
+ * to pass to fprintf. */
+ char *arg4, *arg5, *arg6, *arg7, *arg8;
+{
+ if (panicProc != NULL) {
+ (void) (*panicProc)(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+ } else {
+ (void) fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5, arg6,
+ arg7, arg8);
+ (void) fprintf(stderr, "\n");
+ (void) fflush(stderr);
+ abort();
+ }
+}
diff --git a/tcl/generic/regexp.c b/tcl/generic/regexp.c
new file mode 100644
index 00000000000..ca429c87186
--- /dev/null
+++ b/tcl/generic/regexp.c
@@ -0,0 +1,1355 @@
+/*
+ * TclRegComp and TclRegExec -- TclRegSub is elsewhere
+ *
+ * Copyright (c) 1986 by University of Toronto.
+ * Written by Henry Spencer. Not derived from licensed software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose on any computer system, and to redistribute it freely,
+ * subject to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of
+ * this software, no matter how awful, even if they arise
+ * from defects in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either
+ * by explicit claim or by omission.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not
+ * be misrepresented as being the original software.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions. Serious changes in
+ * regular-expression syntax might require a total rethink.
+ *
+ * *** NOTE: this code has been altered slightly for use in Tcl: ***
+ * *** 1. Use ckalloc and ckfree instead of malloc and free. ***
+ * *** 2. Add extra argument to regexp to specify the real ***
+ * *** start of the string separately from the start of the ***
+ * *** current search. This is needed to search for multiple ***
+ * *** matches within a string. ***
+ * *** 3. Names have been changed, e.g. from regcomp to ***
+ * *** TclRegComp, to avoid clashes with other ***
+ * *** regexp implementations used by applications. ***
+ * *** 4. Added errMsg declaration and TclRegError procedure ***
+ * *** 5. Various lint-like things, such as casting arguments ***
+ * *** in procedure calls. ***
+ *
+ * *** NOTE: This code has been altered for use in MT-Sturdy Tcl ***
+ * *** 1. All use of static variables has been changed to access ***
+ * *** fields of a structure. ***
+ * *** 2. This in addition to changes to TclRegError makes the ***
+ * *** code multi-thread safe. ***
+ *
+ * RCS: @(#) $Id$
+ */
+
+#include "tclInt.h"
+#include "tclPort.h"
+
+/*
+ * The variable below is set to NULL before invoking regexp functions
+ * and checked after those functions. If an error occurred then TclRegError
+ * will set the variable to point to a (static) error message. This
+ * mechanism unfortunately does not support multi-threading, but the
+ * procedures TclRegError and TclGetRegError can be modified to use
+ * thread-specific storage for the variable and thereby make the code
+ * thread-safe.
+ */
+
+static char *errMsg = NULL;
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases. They are:
+ *
+ * regstart char that must begin a match; '\0' if none obvious
+ * reganch is the match anchored (at beginning-of-line only)?
+ * regmust string (pointer into program) that match must include, or NULL
+ * regmlen length of regmust string
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot. Regmust permits fast rejection
+ * of lines that cannot possibly match. The regmust tests are costly enough
+ * that TclRegComp() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup). Regmlen is
+ * supplied because the test in TclRegExec() needs it and TclRegComp() is
+ * computing it anyway.
+ */
+
+/*
+ * Structure for regexp "program". This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology). Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand. "Next" pointers of
+ * all nodes except BRANCH implement concatenation; a "next" pointer with
+ * a BRANCH on both ends of it is connecting two alternatives. (Here we
+ * have one of the subtle syntax dependencies: an individual BRANCH (as
+ * opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence.) The operand of some types of node is
+ * a literal string; for others, it is a node leading into a sub-FSM. In
+ * particular, the operand of a BRANCH node is the first node of the branch.
+ * (NB this is *not* a tree structure: the tail of the branch connects
+ * to the thing following the set of BRANCHes.) The opcodes are:
+ */
+
+/* definition number opnd? meaning */
+#define END 0 /* no End of program. */
+#define BOL 1 /* no Match "" at beginning of line. */
+#define EOL 2 /* no Match "" at end of line. */
+#define ANY 3 /* no Match any one character. */
+#define ANYOF 4 /* str Match any character in this string. */
+#define ANYBUT 5 /* str Match any character not in this string. */
+#define BRANCH 6 /* node Match this alternative, or the next... */
+#define BACK 7 /* no Match "", "next" ptr points backward. */
+#define EXACTLY 8 /* str Match this string. */
+#define NOTHING 9 /* no Match empty string. */
+#define STAR 10 /* node Match this (simple) thing 0 or more times. */
+#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
+#define OPEN 20 /* no Mark this point in input as start of #n. */
+ /* OPEN+1 is number 1, etc. */
+#define CLOSE (OPEN+NSUBEXP) /* no Analogous to OPEN. */
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH The set of branches constituting a single choice are hooked
+ * together with their "next" pointers, since precedence prevents
+ * anything being concatenated to any individual branch. The
+ * "next" pointer of the last BRANCH in a choice points to the
+ * thing following the whole choice. This is also where the
+ * final "next" pointer of each individual branch points; each
+ * branch starts with the operand node of a BRANCH node.
+ *
+ * BACK Normal "next" pointers all implicitly point forward; BACK
+ * exists to make loop structures possible.
+ *
+ * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
+ * BRANCH structures using BACK. Simple cases (one character
+ * per match) are implemented with STAR and PLUS for speed
+ * and to minimize recursive plunges.
+ *
+ * OPEN,CLOSE ...are numbered at compile time.
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit pieces, high order first. The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node. (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+#define OP(p) (*(p))
+#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
+#define OPERAND(p) ((p) + 3)
+
+/*
+ * See regmagic.h for one further detail of program structure.
+ */
+
+
+/*
+ * Utility definitions.
+ */
+#ifndef CHARBITS
+#define UCHARAT(p) ((int)*(unsigned char *)(p))
+#else
+#define UCHARAT(p) ((int)*(p)&CHARBITS)
+#endif
+
+#define FAIL(m) { TclRegError(m); return(NULL); }
+#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
+#define META "^$.[()|?+*\\"
+
+/*
+ * Flags to be passed up and down.
+ */
+#define HASWIDTH 01 /* Known never to match null string. */
+#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
+#define SPSTART 04 /* Starts with * or +. */
+#define WORST 0 /* Worst case. */
+
+/*
+ * Global work variables for TclRegComp().
+ */
+struct regcomp_state {
+ char *regparse; /* Input-scan pointer. */
+ int regnpar; /* () count. */
+ char *regcode; /* Code-emit pointer; &regdummy = don't. */
+ long regsize; /* Code size. */
+};
+
+static char regdummy;
+
+/*
+ * The first byte of the regexp internal "program" is actually this magic
+ * number; the start node begins in the second byte.
+ */
+#define MAGIC 0234
+
+
+/*
+ * Forward declarations for TclRegComp()'s friends.
+ */
+
+static char * reg _ANSI_ARGS_((int paren, int *flagp,
+ struct regcomp_state *rcstate));
+static char * regatom _ANSI_ARGS_((int *flagp,
+ struct regcomp_state *rcstate));
+static char * regbranch _ANSI_ARGS_((int *flagp,
+ struct regcomp_state *rcstate));
+static void regc _ANSI_ARGS_((int b,
+ struct regcomp_state *rcstate));
+static void reginsert _ANSI_ARGS_((int op, char *opnd,
+ struct regcomp_state *rcstate));
+static char * regnext _ANSI_ARGS_((char *p));
+static char * regnode _ANSI_ARGS_((int op,
+ struct regcomp_state *rcstate));
+static void regoptail _ANSI_ARGS_((char *p, char *val));
+static char * regpiece _ANSI_ARGS_((int *flagp,
+ struct regcomp_state *rcstate));
+static void regtail _ANSI_ARGS_((char *p, char *val));
+
+#ifdef STRCSPN
+static int strcspn _ANSI_ARGS_((char *s1, char *s2));
+#endif
+
+/*
+ - TclRegComp - compile a regular expression into internal code
+ *
+ * We can't allocate space until we know how big the compiled form will be,
+ * but we can't compile it (and thus know how big it is) until we've got a
+ * place to put the code. So we cheat: we compile it twice, once with code
+ * generation turned off and size counting turned on, and once "for real".
+ * This also means that we don't allocate space until we are sure that the
+ * thing really will compile successfully, and we never have to move the
+ * code and thus invalidate pointers into it. (Note that it has to be in
+ * one piece because free() must be able to free it all.)
+ *
+ * Beware that the optimization-preparation code in here knows about some
+ * of the structure of the compiled regexp.
+ */
+regexp *
+TclRegComp(exp)
+char *exp;
+{
+ register regexp *r;
+ register char *scan;
+ register char *longest;
+ register int len;
+ int flags;
+ struct regcomp_state state;
+ struct regcomp_state *rcstate= &state;
+
+ if (exp == NULL)
+ FAIL("NULL argument");
+
+ /* First pass: determine size, legality. */
+ rcstate->regparse = exp;
+ rcstate->regnpar = 1;
+ rcstate->regsize = 0L;
+ rcstate->regcode = &regdummy;
+ regc(MAGIC, rcstate);
+ if (reg(0, &flags, rcstate) == NULL)
+ return(NULL);
+
+ /* Small enough for pointer-storage convention? */
+ if (rcstate->regsize >= 32767L) /* Probably could be 65535L. */
+ FAIL("regexp too big");
+
+ /* Allocate space. */
+ r = (regexp *)ckalloc(sizeof(regexp) + (unsigned)rcstate->regsize);
+ if (r == NULL)
+ FAIL("out of space");
+
+ /* Second pass: emit code. */
+ rcstate->regparse = exp;
+ rcstate->regnpar = 1;
+ rcstate->regcode = r->program;
+ regc(MAGIC, rcstate);
+ if (reg(0, &flags, rcstate) == NULL)
+ return(NULL);
+
+ /* Dig out information for optimizations. */
+ r->regstart = '\0'; /* Worst-case defaults. */
+ r->reganch = 0;
+ r->regmust = NULL;
+ r->regmlen = 0;
+ scan = r->program+1; /* First BRANCH. */
+ if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
+ scan = OPERAND(scan);
+
+ /* Starting-point info. */
+ if (OP(scan) == EXACTLY)
+ r->regstart = *OPERAND(scan);
+ else if (OP(scan) == BOL)
+ r->reganch++;
+
+ /*
+ * If there's something expensive in the r.e., find the
+ * longest literal string that must appear and make it the
+ * regmust. Resolve ties in favor of later strings, since
+ * the regstart check works with the beginning of the r.e.
+ * and avoiding duplication strengthens checking. Not a
+ * strong reason, but sufficient in the absence of others.
+ */
+ if (flags&SPSTART) {
+ longest = NULL;
+ len = 0;
+ for (; scan != NULL; scan = regnext(scan))
+ if (OP(scan) == EXACTLY && ((int) strlen(OPERAND(scan))) >= len) {
+ longest = OPERAND(scan);
+ len = strlen(OPERAND(scan));
+ }
+ r->regmust = longest;
+ r->regmlen = len;
+ }
+ }
+
+ return(r);
+}
+
+/*
+ - reg - regular expression, i.e. main body or parenthesized thing
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+static char *
+reg(paren, flagp, rcstate)
+int paren; /* Parenthesized? */
+int *flagp;
+struct regcomp_state *rcstate;
+{
+ register char *ret;
+ register char *br;
+ register char *ender;
+ register int parno = 0;
+ int flags;
+
+ *flagp = HASWIDTH; /* Tentatively. */
+
+ /* Make an OPEN node, if parenthesized. */
+ if (paren) {
+ if (rcstate->regnpar >= NSUBEXP)
+ FAIL("too many ()");
+ parno = rcstate->regnpar;
+ rcstate->regnpar++;
+ ret = regnode(OPEN+parno,rcstate);
+ } else
+ ret = NULL;
+
+ /* Pick up the branches, linking them together. */
+ br = regbranch(&flags,rcstate);
+ if (br == NULL)
+ return(NULL);
+ if (ret != NULL)
+ regtail(ret, br); /* OPEN -> first. */
+ else
+ ret = br;
+ if (!(flags&HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags&SPSTART;
+ while (*rcstate->regparse == '|') {
+ rcstate->regparse++;
+ br = regbranch(&flags,rcstate);
+ if (br == NULL)
+ return(NULL);
+ regtail(ret, br); /* BRANCH -> BRANCH. */
+ if (!(flags&HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags&SPSTART;
+ }
+
+ /* Make a closing node, and hook it on the end. */
+ ender = regnode((paren) ? CLOSE+parno : END,rcstate);
+ regtail(ret, ender);
+
+ /* Hook the tails of the branches to the closing node. */
+ for (br = ret; br != NULL; br = regnext(br))
+ regoptail(br, ender);
+
+ /* Check for proper termination. */
+ if (paren && *rcstate->regparse++ != ')') {
+ FAIL("unmatched ()");
+ } else if (!paren && *rcstate->regparse != '\0') {
+ if (*rcstate->regparse == ')') {
+ FAIL("unmatched ()");
+ } else
+ FAIL("junk on end"); /* "Can't happen". */
+ /* NOTREACHED */
+ }
+
+ return(ret);
+}
+
+/*
+ - regbranch - one alternative of an | operator
+ *
+ * Implements the concatenation operator.
+ */
+static char *
+regbranch(flagp, rcstate)
+int *flagp;
+struct regcomp_state *rcstate;
+{
+ register char *ret;
+ register char *chain;
+ register char *latest;
+ int flags;
+
+ *flagp = WORST; /* Tentatively. */
+
+ ret = regnode(BRANCH,rcstate);
+ chain = NULL;
+ while (*rcstate->regparse != '\0' && *rcstate->regparse != '|' &&
+ *rcstate->regparse != ')') {
+ latest = regpiece(&flags, rcstate);
+ if (latest == NULL)
+ return(NULL);
+ *flagp |= flags&HASWIDTH;
+ if (chain == NULL) /* First piece. */
+ *flagp |= flags&SPSTART;
+ else
+ regtail(chain, latest);
+ chain = latest;
+ }
+ if (chain == NULL) /* Loop ran zero times. */
+ (void) regnode(NOTHING,rcstate);
+
+ return(ret);
+}
+
+/*
+ - regpiece - something followed by possible [*+?]
+ *
+ * Note that the branching code sequences used for ? and the general cases
+ * of * and + are somewhat optimized: they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+static char *
+regpiece(flagp, rcstate)
+int *flagp;
+struct regcomp_state *rcstate;
+{
+ register char *ret;
+ register char op;
+ register char *next;
+ int flags;
+
+ ret = regatom(&flags,rcstate);
+ if (ret == NULL)
+ return(NULL);
+
+ op = *rcstate->regparse;
+ if (!ISMULT(op)) {
+ *flagp = flags;
+ return(ret);
+ }
+
+ if (!(flags&HASWIDTH) && op != '?')
+ FAIL("*+ operand could be empty");
+ *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
+
+ if (op == '*' && (flags&SIMPLE))
+ reginsert(STAR, ret, rcstate);
+ else if (op == '*') {
+ /* Emit x* as (x&|), where & means "self". */
+ reginsert(BRANCH, ret, rcstate); /* Either x */
+ regoptail(ret, regnode(BACK,rcstate)); /* and loop */
+ regoptail(ret, ret); /* back */
+ regtail(ret, regnode(BRANCH,rcstate)); /* or */
+ regtail(ret, regnode(NOTHING,rcstate)); /* null. */
+ } else if (op == '+' && (flags&SIMPLE))
+ reginsert(PLUS, ret, rcstate);
+ else if (op == '+') {
+ /* Emit x+ as x(&|), where & means "self". */
+ next = regnode(BRANCH,rcstate); /* Either */
+ regtail(ret, next);
+ regtail(regnode(BACK,rcstate), ret); /* loop back */
+ regtail(next, regnode(BRANCH,rcstate)); /* or */
+ regtail(ret, regnode(NOTHING,rcstate)); /* null. */
+ } else if (op == '?') {
+ /* Emit x? as (x|) */
+ reginsert(BRANCH, ret, rcstate); /* Either x */
+ regtail(ret, regnode(BRANCH,rcstate)); /* or */
+ next = regnode(NOTHING,rcstate); /* null. */
+ regtail(ret, next);
+ regoptail(ret, next);
+ }
+ rcstate->regparse++;
+ if (ISMULT(*rcstate->regparse))
+ FAIL("nested *?+");
+
+ return(ret);
+}
+
+/*
+ - regatom - the lowest level
+ *
+ * Optimization: gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run. Backslashed characters are exceptions, each becoming a
+ * separate node; the code is simpler that way and it's not worth fixing.
+ */
+static char *
+regatom(flagp, rcstate)
+int *flagp;
+struct regcomp_state *rcstate;
+{
+ register char *ret;
+ int flags;
+
+ *flagp = WORST; /* Tentatively. */
+
+ switch (*rcstate->regparse++) {
+ case '^':
+ ret = regnode(BOL,rcstate);
+ break;
+ case '$':
+ ret = regnode(EOL,rcstate);
+ break;
+ case '.':
+ ret = regnode(ANY,rcstate);
+ *flagp |= HASWIDTH|SIMPLE;
+ break;
+ case '[': {
+ register int clss;
+ register int classend;
+
+ if(rcstate->regparse[0] != '\\' &&
+ rcstate->regparse[0] != '^' &&
+ rcstate->regparse[1] == ']') {
+ ret = regnode(EXACTLY,rcstate);
+ regc(*rcstate->regparse++,rcstate);
+ regc('\0',rcstate);
+ rcstate->regparse++;
+ *flagp |= HASWIDTH|SIMPLE;
+ break;
+ }
+ if (*rcstate->regparse == '^') { /* Complement of range. */
+ ret = regnode(ANYBUT,rcstate);
+ rcstate->regparse++;
+ } else
+ ret = regnode(ANYOF,rcstate);
+ if (*rcstate->regparse == ']' || *rcstate->regparse == '-')
+ regc(*rcstate->regparse++,rcstate);
+ while (*rcstate->regparse != '\0' && *rcstate->regparse != ']') {
+ if (*rcstate->regparse == '-') {
+ rcstate->regparse++;
+ if (*rcstate->regparse == ']' || *rcstate->regparse == '\0')
+ regc('-',rcstate);
+ else {
+ clss = UCHARAT(rcstate->regparse-2)+1;
+ classend = UCHARAT(rcstate->regparse);
+ if (clss > classend+1)
+ FAIL("invalid [] range");
+ for (; clss <= classend; clss++)
+ regc((char)clss,rcstate);
+ rcstate->regparse++;
+ }
+ } else
+ regc(*rcstate->regparse++,rcstate);
+ }
+ regc('\0',rcstate);
+ if (*rcstate->regparse != ']')
+ FAIL("unmatched []");
+ rcstate->regparse++;
+ *flagp |= HASWIDTH|SIMPLE;
+ }
+ break;
+ case '(':
+ ret = reg(1, &flags, rcstate);
+ if (ret == NULL)
+ return(NULL);
+ *flagp |= flags&(HASWIDTH|SPSTART);
+ break;
+ case '\0':
+ case '|':
+ case ')':
+ FAIL("internal urp"); /* Supposed to be caught earlier. */
+ /* NOTREACHED */
+ case '?':
+ case '+':
+ case '*':
+ FAIL("?+* follows nothing");
+ /* NOTREACHED */
+ case '\\':
+ if (*rcstate->regparse == '\0')
+ FAIL("trailing \\");
+ ret = regnode(EXACTLY,rcstate);
+ regc(*rcstate->regparse++,rcstate);
+ regc('\0',rcstate);
+ *flagp |= HASWIDTH|SIMPLE;
+ break;
+ default: {
+ register int len;
+ register char ender;
+
+ rcstate->regparse--;
+ len = strcspn(rcstate->regparse, META);
+ if (len <= 0)
+ FAIL("internal disaster");
+ ender = *(rcstate->regparse+len);
+ if (len > 1 && ISMULT(ender))
+ len--; /* Back off clear of ?+* operand. */
+ *flagp |= HASWIDTH;
+ if (len == 1)
+ *flagp |= SIMPLE;
+ ret = regnode(EXACTLY,rcstate);
+ while (len > 0) {
+ regc(*rcstate->regparse++,rcstate);
+ len--;
+ }
+ regc('\0',rcstate);
+ }
+ break;
+ }
+
+ return(ret);
+}
+
+/*
+ - regnode - emit a node
+ */
+static char * /* Location. */
+regnode(op, rcstate)
+int op;
+struct regcomp_state *rcstate;
+{
+ register char *ret;
+ register char *ptr;
+
+ ret = rcstate->regcode;
+ if (ret == &regdummy) {
+ rcstate->regsize += 3;
+ return(ret);
+ }
+
+ ptr = ret;
+ *ptr++ = (char)op;
+ *ptr++ = '\0'; /* Null "next" pointer. */
+ *ptr++ = '\0';
+ rcstate->regcode = ptr;
+
+ return(ret);
+}
+
+/*
+ - regc - emit (if appropriate) a byte of code
+ */
+static void
+regc(b, rcstate)
+int b;
+struct regcomp_state *rcstate;
+{
+ if (rcstate->regcode != &regdummy)
+ *rcstate->regcode++ = (char)b;
+ else
+ rcstate->regsize++;
+}
+
+/*
+ - reginsert - insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+static void
+reginsert(op, opnd, rcstate)
+int op;
+char *opnd;
+struct regcomp_state *rcstate;
+{
+ register char *src;
+ register char *dst;
+ register char *place;
+
+ if (rcstate->regcode == &regdummy) {
+ rcstate->regsize += 3;
+ return;
+ }
+
+ src = rcstate->regcode;
+ rcstate->regcode += 3;
+ dst = rcstate->regcode;
+ while (src > opnd)
+ *--dst = *--src;
+
+ place = opnd; /* Op node, where operand used to be. */
+ *place++ = (char)op;
+ *place++ = '\0';
+ *place = '\0';
+}
+
+/*
+ - regtail - set the next-pointer at the end of a node chain
+ */
+static void
+regtail(p, val)
+char *p;
+char *val;
+{
+ register char *scan;
+ register char *temp;
+ register int offset;
+
+ if (p == &regdummy)
+ return;
+
+ /* Find last node. */
+ scan = p;
+ for (;;) {
+ temp = regnext(scan);
+ if (temp == NULL)
+ break;
+ scan = temp;
+ }
+
+ if (OP(scan) == BACK)
+ offset = scan - val;
+ else
+ offset = val - scan;
+ *(scan+1) = (char)((offset>>8)&0377);
+ *(scan+2) = (char)(offset&0377);
+}
+
+/*
+ - regoptail - regtail on operand of first argument; nop if operandless
+ */
+static void
+regoptail(p, val)
+char *p;
+char *val;
+{
+ /* "Operandless" and "op != BRANCH" are synonymous in practice. */
+ if (p == NULL || p == &regdummy || OP(p) != BRANCH)
+ return;
+ regtail(OPERAND(p), val);
+}
+
+/*
+ * TclRegExec and friends
+ */
+
+/*
+ * Global work variables for TclRegExec().
+ */
+struct regexec_state {
+ char *reginput; /* String-input pointer. */
+ char *regbol; /* Beginning of input, for ^ check. */
+ char **regstartp; /* Pointer to startp array. */
+ char **regendp; /* Ditto for endp. */
+};
+
+/*
+ * Forwards.
+ */
+static int regtry _ANSI_ARGS_((regexp *prog, char *string,
+ struct regexec_state *restate));
+static int regmatch _ANSI_ARGS_((char *prog,
+ struct regexec_state *restate));
+static int regrepeat _ANSI_ARGS_((char *p,
+ struct regexec_state *restate));
+
+#ifdef DEBUG
+int regnarrate = 0;
+void regdump _ANSI_ARGS_((regexp *r));
+static char *regprop _ANSI_ARGS_((char *op));
+#endif
+
+/*
+ - TclRegExec - match a regexp against a string
+ */
+int
+TclRegExec(prog, string, start)
+register regexp *prog;
+register char *string;
+char *start;
+{
+ register char *s;
+ struct regexec_state state;
+ struct regexec_state *restate= &state;
+
+ /* Be paranoid... */
+ if (prog == NULL || string == NULL) {
+ TclRegError("NULL parameter");
+ return(0);
+ }
+
+ /* Check validity of program. */
+ if (UCHARAT(prog->program) != MAGIC) {
+ TclRegError("corrupted program");
+ return(0);
+ }
+
+ /* If there is a "must appear" string, look for it. */
+ if (prog->regmust != NULL) {
+ s = string;
+ while ((s = strchr(s, prog->regmust[0])) != NULL) {
+ if (strncmp(s, prog->regmust, (size_t) prog->regmlen)
+ == 0)
+ break; /* Found it. */
+ s++;
+ }
+ if (s == NULL) /* Not present. */
+ return(0);
+ }
+
+ /* Mark beginning of line for ^ . */
+ restate->regbol = start;
+
+ /* Simplest case: anchored match need be tried only once. */
+ if (prog->reganch)
+ return(regtry(prog, string, restate));
+
+ /* Messy cases: unanchored match. */
+ s = string;
+ if (prog->regstart != '\0')
+ /* We know what char it must start with. */
+ while ((s = strchr(s, prog->regstart)) != NULL) {
+ if (regtry(prog, s, restate))
+ return(1);
+ s++;
+ }
+ else
+ /* We don't -- general case. */
+ do {
+ if (regtry(prog, s, restate))
+ return(1);
+ } while (*s++ != '\0');
+
+ /* Failure. */
+ return(0);
+}
+
+/*
+ - regtry - try match at specific point
+ */
+static int /* 0 failure, 1 success */
+regtry(prog, string, restate)
+regexp *prog;
+char *string;
+struct regexec_state *restate;
+{
+ register int i;
+ register char **sp;
+ register char **ep;
+
+ restate->reginput = string;
+ restate->regstartp = prog->startp;
+ restate->regendp = prog->endp;
+
+ sp = prog->startp;
+ ep = prog->endp;
+ for (i = NSUBEXP; i > 0; i--) {
+ *sp++ = NULL;
+ *ep++ = NULL;
+ }
+ if (regmatch(prog->program + 1,restate)) {
+ prog->startp[0] = string;
+ prog->endp[0] = restate->reginput;
+ return(1);
+ } else
+ return(0);
+}
+
+/*
+ - regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple: check to see whether the current
+ * node matches, call self recursively to see whether the rest matches,
+ * and then act accordingly. In practice we make some effort to avoid
+ * recursion, in particular by going through "ordinary" nodes (that don't
+ * need to know whether the rest of the match failed) by a loop instead of
+ * by recursion.
+ */
+static int /* 0 failure, 1 success */
+regmatch(prog, restate)
+char *prog;
+struct regexec_state *restate;
+{
+ register char *scan; /* Current node. */
+ char *next; /* Next node. */
+
+ scan = prog;
+#ifdef DEBUG
+ if (scan != NULL && regnarrate)
+ fprintf(stderr, "%s(\n", regprop(scan));
+#endif
+ while (scan != NULL) {
+#ifdef DEBUG
+ if (regnarrate)
+ fprintf(stderr, "%s...\n", regprop(scan));
+#endif
+ next = regnext(scan);
+
+ switch (OP(scan)) {
+ case BOL:
+ if (restate->reginput != restate->regbol) {
+ return 0;
+ }
+ break;
+ case EOL:
+ if (*restate->reginput != '\0') {
+ return 0;
+ }
+ break;
+ case ANY:
+ if (*restate->reginput == '\0') {
+ return 0;
+ }
+ restate->reginput++;
+ break;
+ case EXACTLY: {
+ register int len;
+ register char *opnd;
+
+ opnd = OPERAND(scan);
+ /* Inline the first character, for speed. */
+ if (*opnd != *restate->reginput) {
+ return 0 ;
+ }
+ len = strlen(opnd);
+ if (len > 1 && strncmp(opnd, restate->reginput, (size_t) len)
+ != 0) {
+ return 0;
+ }
+ restate->reginput += len;
+ break;
+ }
+ case ANYOF:
+ if (*restate->reginput == '\0'
+ || strchr(OPERAND(scan), *restate->reginput) == NULL) {
+ return 0;
+ }
+ restate->reginput++;
+ break;
+ case ANYBUT:
+ if (*restate->reginput == '\0'
+ || strchr(OPERAND(scan), *restate->reginput) != NULL) {
+ return 0;
+ }
+ restate->reginput++;
+ break;
+ case NOTHING:
+ break;
+ case BACK:
+ break;
+ case OPEN+1:
+ case OPEN+2:
+ case OPEN+3:
+ case OPEN+4:
+ case OPEN+5:
+ case OPEN+6:
+ case OPEN+7:
+ case OPEN+8:
+ case OPEN+9: {
+ register int no;
+ register char *save;
+
+ doOpen:
+ no = OP(scan) - OPEN;
+ save = restate->reginput;
+
+ if (regmatch(next,restate)) {
+ /*
+ * Don't set startp if some later invocation of the
+ * same parentheses already has.
+ */
+ if (restate->regstartp[no] == NULL) {
+ restate->regstartp[no] = save;
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ case CLOSE+1:
+ case CLOSE+2:
+ case CLOSE+3:
+ case CLOSE+4:
+ case CLOSE+5:
+ case CLOSE+6:
+ case CLOSE+7:
+ case CLOSE+8:
+ case CLOSE+9: {
+ register int no;
+ register char *save;
+
+ doClose:
+ no = OP(scan) - CLOSE;
+ save = restate->reginput;
+
+ if (regmatch(next,restate)) {
+ /*
+ * Don't set endp if some later
+ * invocation of the same parentheses
+ * already has.
+ */
+ if (restate->regendp[no] == NULL)
+ restate->regendp[no] = save;
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ case BRANCH: {
+ register char *save;
+
+ if (OP(next) != BRANCH) { /* No choice. */
+ next = OPERAND(scan); /* Avoid recursion. */
+ } else {
+ do {
+ save = restate->reginput;
+ if (regmatch(OPERAND(scan),restate))
+ return(1);
+ restate->reginput = save;
+ scan = regnext(scan);
+ } while (scan != NULL && OP(scan) == BRANCH);
+ return 0;
+ }
+ break;
+ }
+ case STAR:
+ case PLUS: {
+ register char nextch;
+ register int no;
+ register char *save;
+ register int min;
+
+ /*
+ * Lookahead to avoid useless match attempts
+ * when we know what character comes next.
+ */
+ nextch = '\0';
+ if (OP(next) == EXACTLY)
+ nextch = *OPERAND(next);
+ min = (OP(scan) == STAR) ? 0 : 1;
+ save = restate->reginput;
+ no = regrepeat(OPERAND(scan),restate);
+ while (no >= min) {
+ /* If it could work, try it. */
+ if (nextch == '\0' || *restate->reginput == nextch)
+ if (regmatch(next,restate))
+ return(1);
+ if (nextch != '\0' && no > (min + 1)) {
+ char tmp = *(save + no);
+ char *p;
+ *(save + no) = 0;
+ p = strrchr(save, nextch);
+ *(save + no) = tmp;
+ if (p != NULL)
+ no = p - save + 1;
+ else
+ no = 0;
+ }
+
+ /* Couldn't or didn't -- back up. */
+ no--;
+ restate->reginput = save + no;
+ }
+ return(0);
+ }
+ case END:
+ return(1); /* Success! */
+ default:
+ if (OP(scan) > OPEN && OP(scan) < OPEN+NSUBEXP) {
+ goto doOpen;
+ } else if (OP(scan) > CLOSE && OP(scan) < CLOSE+NSUBEXP) {
+ goto doClose;
+ }
+ TclRegError("memory corruption");
+ return 0;
+ }
+
+ scan = next;
+ }
+
+ /*
+ * We get here only if there's trouble -- normally "case END" is
+ * the terminating point.
+ */
+ TclRegError("corrupted pointers");
+ return(0);
+}
+
+/*
+ - regrepeat - repeatedly match something simple, report how many
+ */
+static int
+regrepeat(p, restate)
+char *p;
+struct regexec_state *restate;
+{
+ register int count = 0;
+ register char *scan;
+ register char *opnd;
+
+ scan = restate->reginput;
+ opnd = OPERAND(p);
+ switch (OP(p)) {
+ case ANY:
+ count = strlen(scan);
+ scan += count;
+ break;
+ case EXACTLY:
+ while (*opnd == *scan) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYOF:
+ while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYBUT:
+ while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
+ count++;
+ scan++;
+ }
+ break;
+ default: /* Oh dear. Called inappropriately. */
+ TclRegError("internal foulup");
+ count = 0; /* Best compromise. */
+ break;
+ }
+ restate->reginput = scan;
+
+ return(count);
+}
+
+/*
+ - regnext - dig the "next" pointer out of a node
+ */
+static char *
+regnext(p)
+register char *p;
+{
+ register int offset;
+
+ if (p == &regdummy)
+ return(NULL);
+
+ offset = NEXT(p);
+ if (offset == 0)
+ return(NULL);
+
+ if (OP(p) == BACK)
+ return(p-offset);
+ else
+ return(p+offset);
+}
+
+#ifdef DEBUG
+
+static char *regprop();
+
+/*
+ - regdump - dump a regexp onto stdout in vaguely comprehensible form
+ */
+void
+regdump(r)
+regexp *r;
+{
+ register char *s;
+ register char op = EXACTLY; /* Arbitrary non-END op. */
+ register char *next;
+
+
+ s = r->program + 1;
+ while (op != END) { /* While that wasn't END last time... */
+ op = OP(s);
+ printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
+ next = regnext(s);
+ if (next == NULL) /* Next ptr. */
+ printf("(0)");
+ else
+ printf("(%d)", (s-r->program)+(next-s));
+ s += 3;
+ if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
+ /* Literal string, where present. */
+ while (*s != '\0') {
+ putchar(*s);
+ s++;
+ }
+ s++;
+ }
+ putchar('\n');
+ }
+
+ /* Header fields of interest. */
+ if (r->regstart != '\0')
+ printf("start `%c' ", r->regstart);
+ if (r->reganch)
+ printf("anchored ");
+ if (r->regmust != NULL)
+ printf("must have \"%s\"", r->regmust);
+ printf("\n");
+}
+
+/*
+ - regprop - printable representation of opcode
+ */
+static char *
+regprop(op)
+char *op;
+{
+ register char *p;
+ static char buf[50];
+
+ (void) strcpy(buf, ":");
+
+ switch (OP(op)) {
+ case BOL:
+ p = "BOL";
+ break;
+ case EOL:
+ p = "EOL";
+ break;
+ case ANY:
+ p = "ANY";
+ break;
+ case ANYOF:
+ p = "ANYOF";
+ break;
+ case ANYBUT:
+ p = "ANYBUT";
+ break;
+ case BRANCH:
+ p = "BRANCH";
+ break;
+ case EXACTLY:
+ p = "EXACTLY";
+ break;
+ case NOTHING:
+ p = "NOTHING";
+ break;
+ case BACK:
+ p = "BACK";
+ break;
+ case END:
+ p = "END";
+ break;
+ case OPEN+1:
+ case OPEN+2:
+ case OPEN+3:
+ case OPEN+4:
+ case OPEN+5:
+ case OPEN+6:
+ case OPEN+7:
+ case OPEN+8:
+ case OPEN+9:
+ sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
+ p = NULL;
+ break;
+ case CLOSE+1:
+ case CLOSE+2:
+ case CLOSE+3:
+ case CLOSE+4:
+ case CLOSE+5:
+ case CLOSE+6:
+ case CLOSE+7:
+ case CLOSE+8:
+ case CLOSE+9:
+ sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
+ p = NULL;
+ break;
+ case STAR:
+ p = "STAR";
+ break;
+ case PLUS:
+ p = "PLUS";
+ break;
+ default:
+ if (OP(op) > OPEN && OP(op) < OPEN+NSUBEXP) {
+ sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
+ p = NULL;
+ break;
+ } else if (OP(op) > CLOSE && OP(op) < CLOSE+NSUBEXP) {
+ sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
+ p = NULL;
+ } else {
+ TclRegError("corrupted opcode");
+ }
+ break;
+ }
+ if (p != NULL)
+ (void) strcat(buf, p);
+ return(buf);
+}
+#endif
+
+/*
+ * The following is provided for those people who do not have strcspn() in
+ * their C libraries. They should get off their butts and do something
+ * about it; at least one public-domain implementation of those (highly
+ * useful) string routines has been published on Usenet.
+ */
+#ifdef STRCSPN
+/*
+ * strcspn - find length of initial segment of s1 consisting entirely
+ * of characters not from s2
+ */
+
+static int
+strcspn(s1, s2)
+char *s1;
+char *s2;
+{
+ register char *scan1;
+ register char *scan2;
+ register int count;
+
+ count = 0;
+ for (scan1 = s1; *scan1 != '\0'; scan1++) {
+ for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
+ if (*scan1 == *scan2++)
+ return(count);
+ count++;
+ }
+ return(count);
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRegError --
+ *
+ * This procedure is invoked by the regexp code when an error
+ * occurs. It saves the error message so it can be seen by the
+ * code that called Spencer's code.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The value of "string" is saved in "errMsg".
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclRegError(string)
+ char *string; /* Error message. */
+{
+ errMsg = string;
+}
+
+char *
+TclGetRegError()
+{
+ return errMsg;
+}
diff --git a/tcl/library/http2.0/http.tcl b/tcl/library/http2.0/http.tcl
new file mode 100644
index 00000000000..ccefaa8f0d2
--- /dev/null
+++ b/tcl/library/http2.0/http.tcl
@@ -0,0 +1,462 @@
+# http.tcl --
+#
+# Client-side HTTP for GET, POST, and HEAD commands.
+# These routines can be used in untrusted code that uses
+# the Safesock security policy. These procedures use a
+# callback interface to avoid using vwait, which is not
+# defined in the safe base.
+#
+# See the file "license.terms" for information on usage and
+# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id$
+
+package provide http 2.0 ;# This uses Tcl namespaces
+
+namespace eval http {
+ variable http
+
+ array set http {
+ -accept */*
+ -proxyhost {}
+ -proxyport {}
+ -useragent {Tcl http client package 2.0}
+ -proxyfilter http::ProxyRequired
+ }
+
+ variable formMap
+ set alphanumeric a-zA-Z0-9
+
+ for {set i 1} {$i <= 256} {incr i} {
+ set c [format %c $i]
+ if {![string match \[$alphanumeric\] $c]} {
+ set formMap($c) %[format %.2x $i]
+ }
+ }
+ # These are handled specially
+ array set formMap {
+ " " + \n %0d%0a
+ }
+
+ namespace export geturl config reset wait formatQuery
+ # Useful, but not exported: data size status code
+}
+
+# http::config --
+#
+# See documentaion for details.
+#
+# Arguments:
+# args Options parsed by the procedure.
+# Results:
+# TODO
+
+proc http::config {args} {
+ variable http
+ set options [lsort [array names http -*]]
+ set usage [join $options ", "]
+ if {[llength $args] == 0} {
+ set result {}
+ foreach name $options {
+ lappend result $name $http($name)
+ }
+ return $result
+ }
+ regsub -all -- - $options {} options
+ set pat ^-([join $options |])$
+ if {[llength $args] == 1} {
+ set flag [lindex $args 0]
+ if {[regexp -- $pat $flag]} {
+ return $http($flag)
+ } else {
+ return -code error "Unknown option $flag, must be: $usage"
+ }
+ } else {
+ foreach {flag value} $args {
+ if {[regexp -- $pat $flag]} {
+ set http($flag) $value
+ } else {
+ return -code error "Unknown option $flag, must be: $usage"
+ }
+ }
+ }
+}
+
+ proc http::Finish { token {errormsg ""} } {
+ variable $token
+ upvar 0 $token state
+ global errorInfo errorCode
+ if {[string length $errormsg] != 0} {
+ set state(error) [list $errormsg $errorInfo $errorCode]
+ set state(status) error
+ }
+ catch {close $state(sock)}
+ catch {after cancel $state(after)}
+ if {[info exists state(-command)]} {
+ if {[catch {eval $state(-command) {$token}} err]} {
+ if {[string length $errormsg] == 0} {
+ set state(error) [list $err $errorInfo $errorCode]
+ set state(status) error
+ }
+ }
+ unset state(-command)
+ }
+}
+
+# http::reset --
+#
+# See documentaion for details.
+#
+# Arguments:
+# token Connection token.
+# why Status info.
+# Results:
+# TODO
+
+proc http::reset { token {why reset} } {
+ variable $token
+ upvar 0 $token state
+ set state(status) $why
+ catch {fileevent $state(sock) readable {}}
+ Finish $token
+ if {[info exists state(error)]} {
+ set errorlist $state(error)
+ unset state(error)
+ eval error $errorlist
+ }
+}
+
+# http::geturl --
+#
+# Establishes a connection to a remote url via http.
+#
+# Arguments:
+# url The http URL to goget.
+# args Option value pairs. Valid options include:
+# -blocksize, -validate, -headers, -timeout
+# Results:
+# Returns a token for this connection.
+
+
+proc http::geturl { url args } {
+ variable http
+ if {![info exists http(uid)]} {
+ set http(uid) 0
+ }
+ set token [namespace current]::[incr http(uid)]
+ variable $token
+ upvar 0 $token state
+ reset $token
+ array set state {
+ -blocksize 8192
+ -validate 0
+ -headers {}
+ -timeout 0
+ state header
+ meta {}
+ currentsize 0
+ totalsize 0
+ type text/html
+ body {}
+ status ""
+ }
+ set options {-blocksize -channel -command -handler -headers \
+ -progress -query -validate -timeout}
+ set usage [join $options ", "]
+ regsub -all -- - $options {} options
+ set pat ^-([join $options |])$
+ foreach {flag value} $args {
+ if {[regexp $pat $flag]} {
+ # Validate numbers
+ if {[info exists state($flag)] && \
+ [regexp {^[0-9]+$} $state($flag)] && \
+ ![regexp {^[0-9]+$} $value]} {
+ return -code error "Bad value for $flag ($value), must be integer"
+ }
+ set state($flag) $value
+ } else {
+ return -code error "Unknown option $flag, can be: $usage"
+ }
+ }
+ if {! [regexp -nocase {^(http://)?([^/:]+)(:([0-9]+))?(/.*)?$} $url \
+ x proto host y port srvurl]} {
+ error "Unsupported URL: $url"
+ }
+ if {[string length $port] == 0} {
+ set port 80
+ }
+ if {[string length $srvurl] == 0} {
+ set srvurl /
+ }
+ if {[string length $proto] == 0} {
+ set url http://$url
+ }
+ set state(url) $url
+ if {![catch {$http(-proxyfilter) $host} proxy]} {
+ set phost [lindex $proxy 0]
+ set pport [lindex $proxy 1]
+ }
+ if {$state(-timeout) > 0} {
+ set state(after) [after $state(-timeout) [list http::reset $token timeout]]
+ }
+ if {[info exists phost] && [string length $phost]} {
+ set srvurl $url
+ set s [socket $phost $pport]
+ } else {
+ set s [socket $host $port]
+ }
+ set state(sock) $s
+
+ # Send data in cr-lf format, but accept any line terminators
+
+ fconfigure $s -translation {auto crlf} -buffersize $state(-blocksize)
+
+ # The following is disallowed in safe interpreters, but the socket
+ # is already in non-blocking mode in that case.
+
+ catch {fconfigure $s -blocking off}
+ set len 0
+ set how GET
+ if {[info exists state(-query)]} {
+ set len [string length $state(-query)]
+ if {$len > 0} {
+ set how POST
+ }
+ } elseif {$state(-validate)} {
+ set how HEAD
+ }
+ puts $s "$how $srvurl HTTP/1.0"
+ puts $s "Accept: $http(-accept)"
+ puts $s "Host: $host"
+ puts $s "User-Agent: $http(-useragent)"
+ foreach {key value} $state(-headers) {
+ regsub -all \[\n\r\] $value {} value
+ set key [string trim $key]
+ if {[string length $key]} {
+ puts $s "$key: $value"
+ }
+ }
+ if {$len > 0} {
+ puts $s "Content-Length: $len"
+ puts $s "Content-Type: application/x-www-form-urlencoded"
+ puts $s ""
+ fconfigure $s -translation {auto binary}
+ puts $s $state(-query)
+ } else {
+ puts $s ""
+ }
+ flush $s
+ fileevent $s readable [list http::Event $token]
+ if {! [info exists state(-command)]} {
+ wait $token
+ }
+ return $token
+}
+
+# Data access functions:
+# Data - the URL data
+# Status - the transaction status: ok, reset, eof, timeout
+# Code - the HTTP transaction code, e.g., 200
+# Size - the size of the URL data
+
+proc http::data {token} {
+ variable $token
+ upvar 0 $token state
+ return $state(body)
+}
+proc http::status {token} {
+ variable $token
+ upvar 0 $token state
+ return $state(status)
+}
+proc http::code {token} {
+ variable $token
+ upvar 0 $token state
+ return $state(http)
+}
+proc http::size {token} {
+ variable $token
+ upvar 0 $token state
+ return $state(currentsize)
+}
+
+ proc http::Event {token} {
+ variable $token
+ upvar 0 $token state
+ set s $state(sock)
+
+ if {[::eof $s]} {
+ Eof $token
+ return
+ }
+ if {$state(state) == "header"} {
+ set n [gets $s line]
+ if {$n == 0} {
+ set state(state) body
+ if {![regexp -nocase ^text $state(type)]} {
+ # Turn off conversions for non-text data
+ fconfigure $s -translation binary
+ if {[info exists state(-channel)]} {
+ fconfigure $state(-channel) -translation binary
+ }
+ }
+ if {[info exists state(-channel)] &&
+ ![info exists state(-handler)]} {
+ # Initiate a sequence of background fcopies
+ fileevent $s readable {}
+ CopyStart $s $token
+ }
+ } elseif {$n > 0} {
+ if {[regexp -nocase {^content-type:(.+)$} $line x type]} {
+ set state(type) [string trim $type]
+ }
+ if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
+ set state(totalsize) [string trim $length]
+ }
+ if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
+ lappend state(meta) $key $value
+ } elseif {[regexp ^HTTP $line]} {
+ set state(http) $line
+ }
+ }
+ } else {
+ if {[catch {
+ if {[info exists state(-handler)]} {
+ set n [eval $state(-handler) {$s $token}]
+ } else {
+ set block [read $s $state(-blocksize)]
+ set n [string length $block]
+ if {$n >= 0} {
+ append state(body) $block
+ }
+ }
+ if {$n >= 0} {
+ incr state(currentsize) $n
+ }
+ } err]} {
+ Finish $token $err
+ } else {
+ if {[info exists state(-progress)]} {
+ eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
+ }
+ }
+ }
+}
+ proc http::CopyStart {s token} {
+ variable $token
+ upvar 0 $token state
+ if {[catch {
+ fcopy $s $state(-channel) -size $state(-blocksize) -command \
+ [list http::CopyDone $token]
+ } err]} {
+ Finish $token $err
+ }
+}
+ proc http::CopyDone {token count {error {}}} {
+ variable $token
+ upvar 0 $token state
+ set s $state(sock)
+ incr state(currentsize) $count
+ if {[info exists state(-progress)]} {
+ eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
+ }
+ if {([string length $error] != 0)} {
+ Finish $token $error
+ } elseif {[::eof $s]} {
+ Eof $token
+ } else {
+ CopyStart $s $token
+ }
+}
+ proc http::Eof {token} {
+ variable $token
+ upvar 0 $token state
+ if {$state(state) == "header"} {
+ # Premature eof
+ set state(status) eof
+ } else {
+ set state(status) ok
+ }
+ set state(state) eof
+ Finish $token
+}
+
+# http::wait --
+#
+# See documentaion for details.
+#
+# Arguments:
+# token Connection token.
+# Results:
+# The status after the wait.
+
+proc http::wait {token} {
+ variable $token
+ upvar 0 $token state
+
+ if {![info exists state(status)] || [string length $state(status)] == 0} {
+ vwait $token\(status)
+ }
+ if {[info exists state(error)]} {
+ set errorlist $state(error)
+ unset state(error)
+ eval error $errorlist
+ }
+ return $state(status)
+}
+
+# http::formatQuery --
+#
+# See documentaion for details.
+# Call http::formatQuery with an even number of arguments, where
+# the first is a name, the second is a value, the third is another
+# name, and so on.
+#
+# Arguments:
+# args A list of name-value pairs.
+# Results:
+# TODO
+
+proc http::formatQuery {args} {
+ set result ""
+ set sep ""
+ foreach i $args {
+ append result $sep [mapReply $i]
+ if {$sep != "="} {
+ set sep =
+ } else {
+ set sep &
+ }
+ }
+ return $result
+}
+
+# do x-www-urlencoded character mapping
+# The spec says: "non-alphanumeric characters are replaced by '%HH'"
+# 1 leave alphanumerics characters alone
+# 2 Convert every other character to an array lookup
+# 3 Escape constructs that are "special" to the tcl parser
+# 4 "subst" the result, doing all the array substitutions
+
+ proc http::mapReply {string} {
+ variable formMap
+ set alphanumeric a-zA-Z0-9
+ regsub -all \[^$alphanumeric\] $string {$formMap(&)} string
+ regsub -all \n $string {\\n} string
+ regsub -all \t $string {\\t} string
+ regsub -all {[][{})\\]\)} $string {\\&} string
+ return [subst $string]
+}
+
+# Default proxy filter.
+ proc http::ProxyRequired {host} {
+ variable http
+ if {[info exists http(-proxyhost)] && [string length $http(-proxyhost)]} {
+ if {![info exists http(-proxyport)] || ![string length $http(-proxyport)]} {
+ set http(-proxyport) 8080
+ }
+ return [list $http(-proxyhost) $http(-proxyport)]
+ } else {
+ return {}
+ }
+}
diff --git a/tcl/library/http2.0/pkgIndex.tcl b/tcl/library/http2.0/pkgIndex.tcl
new file mode 100644
index 00000000000..01052f3ede8
--- /dev/null
+++ b/tcl/library/http2.0/pkgIndex.tcl
@@ -0,0 +1,11 @@
+# Tcl package index file, version 1.0
+# This file is generated by the "pkg_mkIndex" command
+# and sourced either when an application starts up or
+# by a "package unknown" script. It invokes the
+# "package ifneeded" command to set up package-related
+# information so that packages will be loaded automatically
+# in response to "package require" commands. When this
+# script is sourced, the variable $dir must contain the
+# full path name of this file's directory.
+
+package ifneeded http 2.0 [list tclPkgSetup $dir http 2.0 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait}}}]
diff --git a/tcl/library/opt0.1/optparse.tcl b/tcl/library/opt0.1/optparse.tcl
new file mode 100644
index 00000000000..5d2d33938bf
--- /dev/null
+++ b/tcl/library/opt0.1/optparse.tcl
@@ -0,0 +1,1099 @@
+# optparse.tcl --
+#
+# (Private) option parsing package
+#
+# This might be documented and exported in 8.1
+# and some function hopefully moved to the C core for
+# efficiency, if there is enough demand. (mail! ;-)
+#
+# Author: Laurent Demailly - Laurent.Demailly@sun.com - dl@mail.box.eu.org
+#
+# Credits:
+# this is a complete 'over kill' rewrite by me, from a version
+# written initially with Brent Welch, itself initially
+# based on work with Steve Uhler. Thanks them !
+#
+# RCS: @(#) $Id$
+
+package provide opt 0.3
+
+namespace eval ::tcl {
+
+ # Exported APIs
+ namespace export OptKeyRegister OptKeyDelete OptKeyError OptKeyParse \
+ OptProc OptProcArgGiven OptParse \
+ Lassign Lvarpop Lvarset Lvarincr Lfirst \
+ SetMax SetMin
+
+
+################# Example of use / 'user documentation' ###################
+
+ proc OptCreateTestProc {} {
+
+ # Defines ::tcl::OptParseTest as a test proc with parsed arguments
+ # (can't be defined before the code below is loaded (before "OptProc"))
+
+ # Every OptProc give usage information on "procname -help".
+ # Try "tcl::OptParseTest -help" and "tcl::OptParseTest -a" and
+ # then other arguments.
+ #
+ # example of 'valid' call:
+ # ::tcl::OptParseTest save -4 -pr 23 -libsok SybTcl\
+ # -nostatics false ch1
+ OptProc OptParseTest {
+ {subcommand -choice {save print} "sub command"}
+ {arg1 3 "some number"}
+ {-aflag}
+ {-intflag 7}
+ {-weirdflag "help string"}
+ {-noStatics "Not ok to load static packages"}
+ {-nestedloading1 true "OK to load into nested slaves"}
+ {-nestedloading2 -boolean true "OK to load into nested slaves"}
+ {-libsOK -choice {Tk SybTcl}
+ "List of packages that can be loaded"}
+ {-precision -int 12 "Number of digits of precision"}
+ {-intval 7 "An integer"}
+ {-scale -float 1.0 "Scale factor"}
+ {-zoom 1.0 "Zoom factor"}
+ {-arbitrary foobar "Arbitrary string"}
+ {-random -string 12 "Random string"}
+ {-listval -list {} "List value"}
+ {-blahflag -blah abc "Funny type"}
+ {arg2 -boolean "a boolean"}
+ {arg3 -choice "ch1 ch2"}
+ {?optarg? -list {} "optional argument"}
+ } {
+ foreach v [info locals] {
+ puts stderr [format "%14s : %s" $v [set $v]]
+ }
+ }
+ }
+
+################### No User serviceable part below ! ###############
+# You should really not look any further :
+# The following is private unexported undocumented unblessed... code
+# time to hit "q" ;-) !
+
+# Hmmm... ok, you really want to know ?
+
+# You've been warned... Here it is...
+
+ # Array storing the parsed descriptions
+ variable OptDesc;
+ array set OptDesc {};
+ # Next potentially free key id (numeric)
+ variable OptDescN 0;
+
+# Inside algorithm/mechanism description:
+# (not for the faint hearted ;-)
+#
+# The argument description is parsed into a "program tree"
+# It is called a "program" because it is the program used by
+# the state machine interpreter that use that program to
+# actually parse the arguments at run time.
+#
+# The general structure of a "program" is
+# notation (pseudo bnf like)
+# name :== definition defines "name" as being "definition"
+# { x y z } means list of x, y, and z
+# x* means x repeated 0 or more time
+# x+ means "x x*"
+# x? means optionally x
+# x | y means x or y
+# "cccc" means the literal string
+#
+# program :== { programCounter programStep* }
+#
+# programStep :== program | singleStep
+#
+# programCounter :== {"P" integer+ }
+#
+# singleStep :== { instruction parameters* }
+#
+# instruction :== single element list
+#
+# (the difference between singleStep and program is that \
+# llength [Lfirst $program] >= 2
+# while
+# llength [Lfirst $singleStep] == 1
+# )
+#
+# And for this application:
+#
+# singleStep :== { instruction varname {hasBeenSet currentValue} type
+# typeArgs help }
+# instruction :== "flags" | "value"
+# type :== knowType | anyword
+# knowType :== "string" | "int" | "boolean" | "boolflag" | "float"
+# | "choice"
+#
+# for type "choice" typeArgs is a list of possible choices, the first one
+# is the default value. for all other types the typeArgs is the default value
+#
+# a "boolflag" is the type for a flag whose presence or absence, without
+# additional arguments means respectively true or false (default flag type).
+#
+# programCounter is the index in the list of the currently processed
+# programStep (thus starting at 1 (0 is {"P" prgCounterValue}).
+# If it is a list it points toward each currently selected programStep.
+# (like for "flags", as they are optional, form a set and programStep).
+
+# Performance/Implementation issues
+# ---------------------------------
+# We use tcl lists instead of arrays because with tcl8.0
+# they should start to be much faster.
+# But this code use a lot of helper procs (like Lvarset)
+# which are quite slow and would be helpfully optimized
+# for instance by being written in C. Also our struture
+# is complex and there is maybe some places where the
+# string rep might be calculated at great exense. to be checked.
+
+#
+# Parse a given description and saves it here under the given key
+# generate a unused keyid if not given
+#
+proc ::tcl::OptKeyRegister {desc {key ""}} {
+ variable OptDesc;
+ variable OptDescN;
+ if {[string compare $key ""] == 0} {
+ # in case a key given to us as a parameter was a number
+ while {[info exists OptDesc($OptDescN)]} {incr OptDescN}
+ set key $OptDescN;
+ incr OptDescN;
+ }
+ # program counter
+ set program [list [list "P" 1]];
+
+ # are we processing flags (which makes a single program step)
+ set inflags 0;
+
+ set state {};
+
+ # flag used to detect that we just have a single (flags set) subprogram.
+ set empty 1;
+
+ foreach item $desc {
+ if {$state == "args"} {
+ # more items after 'args'...
+ return -code error "'args' special argument must be the last one";
+ }
+ set res [OptNormalizeOne $item];
+ set state [Lfirst $res];
+ if {$inflags} {
+ if {$state == "flags"} {
+ # add to 'subprogram'
+ lappend flagsprg $res;
+ } else {
+ # put in the flags
+ # structure for flag programs items is a list of
+ # {subprgcounter {prg flag 1} {prg flag 2} {...}}
+ lappend program $flagsprg;
+ # put the other regular stuff
+ lappend program $res;
+ set inflags 0;
+ set empty 0;
+ }
+ } else {
+ if {$state == "flags"} {
+ set inflags 1;
+ # sub program counter + first sub program
+ set flagsprg [list [list "P" 1] $res];
+ } else {
+ lappend program $res;
+ set empty 0;
+ }
+ }
+ }
+ if {$inflags} {
+ if {$empty} {
+ # We just have the subprogram, optimize and remove
+ # unneeded level:
+ set program $flagsprg;
+ } else {
+ lappend program $flagsprg;
+ }
+ }
+
+ set OptDesc($key) $program;
+
+ return $key;
+}
+
+#
+# Free the storage for that given key
+#
+proc ::tcl::OptKeyDelete {key} {
+ variable OptDesc;
+ unset OptDesc($key);
+}
+
+ # Get the parsed description stored under the given key.
+ proc OptKeyGetDesc {descKey} {
+ variable OptDesc;
+ if {![info exists OptDesc($descKey)]} {
+ return -code error "Unknown option description key \"$descKey\"";
+ }
+ set OptDesc($descKey);
+ }
+
+# Parse entry point for ppl who don't want to register with a key,
+# for instance because the description changes dynamically.
+# (otherwise one should really use OptKeyRegister once + OptKeyParse
+# as it is way faster or simply OptProc which does it all)
+# Assign a temporary key, call OptKeyParse and then free the storage
+proc ::tcl::OptParse {desc arglist} {
+ set tempkey [OptKeyRegister $desc];
+ set ret [catch {uplevel [list ::tcl::OptKeyParse $tempkey $arglist]} res];
+ OptKeyDelete $tempkey;
+ return -code $ret $res;
+}
+
+# Helper function, replacement for proc that both
+# register the description under a key which is the name of the proc
+# (and thus unique to that code)
+# and add a first line to the code to call the OptKeyParse proc
+# Stores the list of variables that have been actually given by the user
+# (the other will be sets to their default value)
+# into local variable named "Args".
+proc ::tcl::OptProc {name desc body} {
+ set namespace [uplevel namespace current];
+ if { ([string match $name "::*"])
+ || ([string compare $namespace "::"]==0)} {
+ # absolute name or global namespace, name is the key
+ set key $name;
+ } else {
+ # we are relative to some non top level namespace:
+ set key "${namespace}::${name}";
+ }
+ OptKeyRegister $desc $key;
+ uplevel [list proc $name args "set Args \[::tcl::OptKeyParse $key \$args\]\n$body"];
+ return $key;
+}
+# Check that a argument has been given
+# assumes that "OptProc" has been used as it will check in "Args" list
+proc ::tcl::OptProcArgGiven {argname} {
+ upvar Args alist;
+ expr {[lsearch $alist $argname] >=0}
+}
+
+ #######
+ # Programs/Descriptions manipulation
+
+ # Return the instruction word/list of a given step/(sub)program
+ proc OptInstr {lst} {
+ Lfirst $lst;
+ }
+ # Is a (sub) program or a plain instruction ?
+ proc OptIsPrg {lst} {
+ expr {[llength [OptInstr $lst]]>=2}
+ }
+ # Is this instruction a program counter or a real instr
+ proc OptIsCounter {item} {
+ expr {[Lfirst $item]=="P"}
+ }
+ # Current program counter (2nd word of first word)
+ proc OptGetPrgCounter {lst} {
+ Lget $lst {0 1}
+ }
+ # Current program counter (2nd word of first word)
+ proc OptSetPrgCounter {lstName newValue} {
+ upvar $lstName lst;
+ set lst [lreplace $lst 0 0 [concat "P" $newValue]];
+ }
+ # returns a list of currently selected items.
+ proc OptSelection {lst} {
+ set res {};
+ foreach idx [lrange [Lfirst $lst] 1 end] {
+ lappend res [Lget $lst $idx];
+ }
+ return $res;
+ }
+
+ # Advance to next description
+ proc OptNextDesc {descName} {
+ uplevel [list Lvarincr $descName {0 1}];
+ }
+
+ # Get the current description, eventually descend
+ proc OptCurDesc {descriptions} {
+ lindex $descriptions [OptGetPrgCounter $descriptions];
+ }
+ # get the current description, eventually descend
+ # through sub programs as needed.
+ proc OptCurDescFinal {descriptions} {
+ set item [OptCurDesc $descriptions];
+ # Descend untill we get the actual item and not a sub program
+ while {[OptIsPrg $item]} {
+ set item [OptCurDesc $item];
+ }
+ return $item;
+ }
+ # Current final instruction adress
+ proc OptCurAddr {descriptions {start {}}} {
+ set adress [OptGetPrgCounter $descriptions];
+ lappend start $adress;
+ set item [lindex $descriptions $adress];
+ if {[OptIsPrg $item]} {
+ return [OptCurAddr $item $start];
+ } else {
+ return $start;
+ }
+ }
+ # Set the value field of the current instruction
+ proc OptCurSetValue {descriptionsName value} {
+ upvar $descriptionsName descriptions
+ # get the current item full adress
+ set adress [OptCurAddr $descriptions];
+ # use the 3th field of the item (see OptValue / OptNewInst)
+ lappend adress 2
+ Lvarset descriptions $adress [list 1 $value];
+ # ^hasBeenSet flag
+ }
+
+ # empty state means done/paste the end of the program
+ proc OptState {item} {
+ Lfirst $item
+ }
+
+ # current state
+ proc OptCurState {descriptions} {
+ OptState [OptCurDesc $descriptions];
+ }
+
+ #######
+ # Arguments manipulation
+
+ # Returns the argument that has to be processed now
+ proc OptCurrentArg {lst} {
+ Lfirst $lst;
+ }
+ # Advance to next argument
+ proc OptNextArg {argsName} {
+ uplevel [list Lvarpop $argsName];
+ }
+ #######
+
+
+
+
+
+ # Loop over all descriptions, calling OptDoOne which will
+ # eventually eat all the arguments.
+ proc OptDoAll {descriptionsName argumentsName} {
+ upvar $descriptionsName descriptions
+ upvar $argumentsName arguments;
+# puts "entered DoAll";
+ # Nb: the places where "state" can be set are tricky to figure
+ # because DoOne sets the state to flagsValue and return -continue
+ # when needed...
+ set state [OptCurState $descriptions];
+ # We'll exit the loop in "OptDoOne" or when state is empty.
+ while 1 {
+ set curitem [OptCurDesc $descriptions];
+ # Do subprograms if needed, call ourselves on the sub branch
+ while {[OptIsPrg $curitem]} {
+ OptDoAll curitem arguments
+# puts "done DoAll sub";
+ # Insert back the results in current tree;
+ Lvarset1nc descriptions [OptGetPrgCounter $descriptions]\
+ $curitem;
+ OptNextDesc descriptions;
+ set curitem [OptCurDesc $descriptions];
+ set state [OptCurState $descriptions];
+ }
+# puts "state = \"$state\" - arguments=($arguments)";
+ if {[Lempty $state]} {
+ # Nothing left to do, we are done in this branch:
+ break;
+ }
+ # The following statement can make us terminate/continue
+ # as it use return -code {break, continue, return and error}
+ # codes
+ OptDoOne descriptions state arguments;
+ # If we are here, no special return code where issued,
+ # we'll step to next instruction :
+# puts "new state = \"$state\"";
+ OptNextDesc descriptions;
+ set state [OptCurState $descriptions];
+ }
+ }
+
+ # Process one step for the state machine,
+ # eventually consuming the current argument.
+ proc OptDoOne {descriptionsName stateName argumentsName} {
+ upvar $argumentsName arguments;
+ upvar $descriptionsName descriptions;
+ upvar $stateName state;
+
+ # the special state/instruction "args" eats all
+ # the remaining args (if any)
+ if {($state == "args")} {
+ if {![Lempty $arguments]} {
+ # If there is no additional arguments, leave the default value
+ # in.
+ OptCurSetValue descriptions $arguments;
+ set arguments {};
+ }
+# puts "breaking out ('args' state: consuming every reminding args)"
+ return -code break;
+ }
+
+ if {[Lempty $arguments]} {
+ if {$state == "flags"} {
+ # no argument and no flags : we're done
+# puts "returning to previous (sub)prg (no more args)";
+ return -code return;
+ } elseif {$state == "optValue"} {
+ set state next; # not used, for debug only
+ # go to next state
+ return ;
+ } else {
+ return -code error [OptMissingValue $descriptions];
+ }
+ } else {
+ set arg [OptCurrentArg $arguments];
+ }
+
+ switch $state {
+ flags {
+ # A non-dash argument terminates the options, as does --
+
+ # Still a flag ?
+ if {![OptIsFlag $arg]} {
+ # don't consume the argument, return to previous prg
+ return -code return;
+ }
+ # consume the flag
+ OptNextArg arguments;
+ if {[string compare "--" $arg] == 0} {
+ # return from 'flags' state
+ return -code return;
+ }
+
+ set hits [OptHits descriptions $arg];
+ if {$hits > 1} {
+ return -code error [OptAmbigous $descriptions $arg]
+ } elseif {$hits == 0} {
+ return -code error [OptFlagUsage $descriptions $arg]
+ }
+ set item [OptCurDesc $descriptions];
+ if {[OptNeedValue $item]} {
+ # we need a value, next state is
+ set state flagValue;
+ } else {
+ OptCurSetValue descriptions 1;
+ }
+ # continue
+ return -code continue;
+ }
+ flagValue -
+ value {
+ set item [OptCurDesc $descriptions];
+ # Test the values against their required type
+ if {[catch {OptCheckType $arg\
+ [OptType $item] [OptTypeArgs $item]} val]} {
+ return -code error [OptBadValue $item $arg $val]
+ }
+ # consume the value
+ OptNextArg arguments;
+ # set the value
+ OptCurSetValue descriptions $val;
+ # go to next state
+ if {$state == "flagValue"} {
+ set state flags
+ return -code continue;
+ } else {
+ set state next; # not used, for debug only
+ return ; # will go on next step
+ }
+ }
+ optValue {
+ set item [OptCurDesc $descriptions];
+ # Test the values against their required type
+ if {![catch {OptCheckType $arg\
+ [OptType $item] [OptTypeArgs $item]} val]} {
+ # right type, so :
+ # consume the value
+ OptNextArg arguments;
+ # set the value
+ OptCurSetValue descriptions $val;
+ }
+ # go to next state
+ set state next; # not used, for debug only
+ return ; # will go on next step
+ }
+ }
+ # If we reach this point: an unknown
+ # state as been entered !
+ return -code error "Bug! unknown state in DoOne \"$state\"\
+ (prg counter [OptGetPrgCounter $descriptions]:\
+ [OptCurDesc $descriptions])";
+ }
+
+# Parse the options given the key to previously registered description
+# and arguments list
+proc ::tcl::OptKeyParse {descKey arglist} {
+
+ set desc [OptKeyGetDesc $descKey];
+
+ # make sure -help always give usage
+ if {[string compare "-help" [string tolower $arglist]] == 0} {
+ return -code error [OptError "Usage information:" $desc 1];
+ }
+
+ OptDoAll desc arglist;
+
+ if {![Lempty $arglist]} {
+ return -code error [OptTooManyArgs $desc $arglist];
+ }
+
+ # Analyse the result
+ # Walk through the tree:
+ OptTreeVars $desc "#[expr {[info level]-1}]" ;
+}
+
+ # determine string length for nice tabulated output
+ proc OptTreeVars {desc level {vnamesLst {}}} {
+ foreach item $desc {
+ if {[OptIsCounter $item]} continue;
+ if {[OptIsPrg $item]} {
+ set vnamesLst [OptTreeVars $item $level $vnamesLst];
+ } else {
+ set vname [OptVarName $item];
+ upvar $level $vname var
+ if {[OptHasBeenSet $item]} {
+# puts "adding $vname"
+ # lets use the input name for the returned list
+ # it is more usefull, for instance you can check that
+ # no flags at all was given with expr
+ # {![string match "*-*" $Args]}
+ lappend vnamesLst [OptName $item];
+ set var [OptValue $item];
+ } else {
+ set var [OptDefaultValue $item];
+ }
+ }
+ }
+ return $vnamesLst
+ }
+
+
+# Check the type of a value
+# and emit an error if arg is not of the correct type
+# otherwise returns the canonical value of that arg (ie 0/1 for booleans)
+proc ::tcl::OptCheckType {arg type {typeArgs ""}} {
+# puts "checking '$arg' against '$type' ($typeArgs)";
+
+ # only types "any", "choice", and numbers can have leading "-"
+
+ switch -exact -- $type {
+ int {
+ if {![regexp {^(-+)?[0-9]+$} $arg]} {
+ error "not an integer"
+ }
+ return $arg;
+ }
+ float {
+ return [expr {double($arg)}]
+ }
+ script -
+ list {
+ # if llength fail : malformed list
+ if {[llength $arg]==0} {
+ if {[OptIsFlag $arg]} {
+ error "no values with leading -"
+ }
+ }
+ return $arg;
+ }
+ boolean {
+ if {![regexp -nocase {^(true|false|0|1)$} $arg]} {
+ error "non canonic boolean"
+ }
+ # convert true/false because expr/if is broken with "!,...
+ if {$arg} {
+ return 1
+ } else {
+ return 0
+ }
+ }
+ choice {
+ if {[lsearch -exact $typeArgs $arg] < 0} {
+ error "invalid choice"
+ }
+ return $arg;
+ }
+ any {
+ return $arg;
+ }
+ string -
+ default {
+ if {[OptIsFlag $arg]} {
+ error "no values with leading -"
+ }
+ return $arg
+ }
+ }
+ return neverReached;
+}
+
+ # internal utilities
+
+ # returns the number of flags matching the given arg
+ # sets the (local) prg counter to the list of matches
+ proc OptHits {descName arg} {
+ upvar $descName desc;
+ set hits 0
+ set hitems {}
+ set i 1;
+
+ set larg [string tolower $arg];
+ set len [string length $larg];
+ set last [expr {$len-1}];
+
+ foreach item [lrange $desc 1 end] {
+ set flag [OptName $item]
+ # lets try to match case insensitively
+ # (string length ought to be cheap)
+ set lflag [string tolower $flag];
+ if {$len == [string length $lflag]} {
+ if {[string compare $larg $lflag]==0} {
+ # Exact match case
+ OptSetPrgCounter desc $i;
+ return 1;
+ }
+ } else {
+ if {[string compare $larg [string range $lflag 0 $last]]==0} {
+ lappend hitems $i;
+ incr hits;
+ }
+ }
+ incr i;
+ }
+ if {$hits} {
+ OptSetPrgCounter desc $hitems;
+ }
+ return $hits
+ }
+
+ # Extract fields from the list structure:
+
+ proc OptName {item} {
+ lindex $item 1;
+ }
+ #
+ proc OptHasBeenSet {item} {
+ Lget $item {2 0};
+ }
+ #
+ proc OptValue {item} {
+ Lget $item {2 1};
+ }
+
+ proc OptIsFlag {name} {
+ string match "-*" $name;
+ }
+ proc OptIsOpt {name} {
+ string match {\?*} $name;
+ }
+ proc OptVarName {item} {
+ set name [OptName $item];
+ if {[OptIsFlag $name]} {
+ return [string range $name 1 end];
+ } elseif {[OptIsOpt $name]} {
+ return [string trim $name "?"];
+ } else {
+ return $name;
+ }
+ }
+ proc OptType {item} {
+ lindex $item 3
+ }
+ proc OptTypeArgs {item} {
+ lindex $item 4
+ }
+ proc OptHelp {item} {
+ lindex $item 5
+ }
+ proc OptNeedValue {item} {
+ string compare [OptType $item] boolflag
+ }
+ proc OptDefaultValue {item} {
+ set val [OptTypeArgs $item]
+ switch -exact -- [OptType $item] {
+ choice {return [lindex $val 0]}
+ boolean -
+ boolflag {
+ # convert back false/true to 0/1 because expr !$bool
+ # is broken..
+ if {$val} {
+ return 1
+ } else {
+ return 0
+ }
+ }
+ }
+ return $val
+ }
+
+ # Description format error helper
+ proc OptOptUsage {item {what ""}} {
+ return -code error "invalid description format$what: $item\n\
+ should be a list of {varname|-flagname ?-type? ?defaultvalue?\
+ ?helpstring?}";
+ }
+
+
+ # Generate a canonical form single instruction
+ proc OptNewInst {state varname type typeArgs help} {
+ list $state $varname [list 0 {}] $type $typeArgs $help;
+ # ^ ^
+ # | |
+ # hasBeenSet=+ +=currentValue
+ }
+
+ # Translate one item to canonical form
+ proc OptNormalizeOne {item} {
+ set lg [Lassign $item varname arg1 arg2 arg3];
+# puts "called optnormalizeone '$item' v=($varname), lg=$lg";
+ set isflag [OptIsFlag $varname];
+ set isopt [OptIsOpt $varname];
+ if {$isflag} {
+ set state "flags";
+ } elseif {$isopt} {
+ set state "optValue";
+ } elseif {[string compare $varname "args"]} {
+ set state "value";
+ } else {
+ set state "args";
+ }
+
+ # apply 'smart' 'fuzzy' logic to try to make
+ # description writer's life easy, and our's difficult :
+ # let's guess the missing arguments :-)
+
+ switch $lg {
+ 1 {
+ if {$isflag} {
+ return [OptNewInst $state $varname boolflag false ""];
+ } else {
+ return [OptNewInst $state $varname any "" ""];
+ }
+ }
+ 2 {
+ # varname default
+ # varname help
+ set type [OptGuessType $arg1]
+ if {[string compare $type "string"] == 0} {
+ if {$isflag} {
+ set type boolflag
+ set def false
+ } else {
+ set type any
+ set def ""
+ }
+ set help $arg1
+ } else {
+ set help ""
+ set def $arg1
+ }
+ return [OptNewInst $state $varname $type $def $help];
+ }
+ 3 {
+ # varname type value
+ # varname value comment
+
+ if {[regexp {^-(.+)$} $arg1 x type]} {
+ # flags/optValue as they are optional, need a "value",
+ # on the contrary, for a variable (non optional),
+ # default value is pointless, 'cept for choices :
+ if {$isflag || $isopt || ($type == "choice")} {
+ return [OptNewInst $state $varname $type $arg2 ""];
+ } else {
+ return [OptNewInst $state $varname $type "" $arg2];
+ }
+ } else {
+ return [OptNewInst $state $varname\
+ [OptGuessType $arg1] $arg1 $arg2]
+ }
+ }
+ 4 {
+ if {[regexp {^-(.+)$} $arg1 x type]} {
+ return [OptNewInst $state $varname $type $arg2 $arg3];
+ } else {
+ return -code error [OptOptUsage $item];
+ }
+ }
+ default {
+ return -code error [OptOptUsage $item];
+ }
+ }
+ }
+
+ # Auto magic lasy type determination
+ proc OptGuessType {arg} {
+ if {[regexp -nocase {^(true|false)$} $arg]} {
+ return boolean
+ }
+ if {[regexp {^(-+)?[0-9]+$} $arg]} {
+ return int
+ }
+ if {![catch {expr {double($arg)}}]} {
+ return float
+ }
+ return string
+ }
+
+ # Error messages front ends
+
+ proc OptAmbigous {desc arg} {
+ OptError "ambigous option \"$arg\", choose from:" [OptSelection $desc]
+ }
+ proc OptFlagUsage {desc arg} {
+ OptError "bad flag \"$arg\", must be one of" $desc;
+ }
+ proc OptTooManyArgs {desc arguments} {
+ OptError "too many arguments (unexpected argument(s): $arguments),\
+ usage:"\
+ $desc 1
+ }
+ proc OptParamType {item} {
+ if {[OptIsFlag $item]} {
+ return "flag";
+ } else {
+ return "parameter";
+ }
+ }
+ proc OptBadValue {item arg {err {}}} {
+# puts "bad val err = \"$err\"";
+ OptError "bad value \"$arg\" for [OptParamType $item]"\
+ [list $item]
+ }
+ proc OptMissingValue {descriptions} {
+# set item [OptCurDescFinal $descriptions];
+ set item [OptCurDesc $descriptions];
+ OptError "no value given for [OptParamType $item] \"[OptName $item]\"\
+ (use -help for full usage) :"\
+ [list $item]
+ }
+
+proc ::tcl::OptKeyError {prefix descKey {header 0}} {
+ OptError $prefix [OptKeyGetDesc $descKey] $header;
+}
+
+ # determine string length for nice tabulated output
+ proc OptLengths {desc nlName tlName dlName} {
+ upvar $nlName nl;
+ upvar $tlName tl;
+ upvar $dlName dl;
+ foreach item $desc {
+ if {[OptIsCounter $item]} continue;
+ if {[OptIsPrg $item]} {
+ OptLengths $item nl tl dl
+ } else {
+ SetMax nl [string length [OptName $item]]
+ SetMax tl [string length [OptType $item]]
+ set dv [OptTypeArgs $item];
+ if {[OptState $item] != "header"} {
+ set dv "($dv)";
+ }
+ set l [string length $dv];
+ # limit the space allocated to potentially big "choices"
+ if {([OptType $item] != "choice") || ($l<=12)} {
+ SetMax dl $l
+ } else {
+ if {![info exists dl]} {
+ set dl 0
+ }
+ }
+ }
+ }
+ }
+ # output the tree
+ proc OptTree {desc nl tl dl} {
+ set res "";
+ foreach item $desc {
+ if {[OptIsCounter $item]} continue;
+ if {[OptIsPrg $item]} {
+ append res [OptTree $item $nl $tl $dl];
+ } else {
+ set dv [OptTypeArgs $item];
+ if {[OptState $item] != "header"} {
+ set dv "($dv)";
+ }
+ append res [format "\n %-*s %-*s %-*s %s" \
+ $nl [OptName $item] $tl [OptType $item] \
+ $dl $dv [OptHelp $item]]
+ }
+ }
+ return $res;
+ }
+
+# Give nice usage string
+proc ::tcl::OptError {prefix desc {header 0}} {
+ # determine length
+ if {$header} {
+ # add faked instruction
+ set h [list [OptNewInst header Var/FlagName Type Value Help]];
+ lappend h [OptNewInst header ------------ ---- ----- ----];
+ lappend h [OptNewInst header {( -help} "" "" {gives this help )}]
+ set desc [concat $h $desc]
+ }
+ OptLengths $desc nl tl dl
+ # actually output
+ return "$prefix[OptTree $desc $nl $tl $dl]"
+}
+
+
+################ General Utility functions #######################
+
+#
+# List utility functions
+# Naming convention:
+# "Lvarxxx" take the list VARiable name as argument
+# "Lxxxx" take the list value as argument
+# (which is not costly with Tcl8 objects system
+# as it's still a reference and not a copy of the values)
+#
+
+# Is that list empty ?
+proc ::tcl::Lempty {list} {
+ expr {[llength $list]==0}
+}
+
+# Gets the value of one leaf of a lists tree
+proc ::tcl::Lget {list indexLst} {
+ if {[llength $indexLst] <= 1} {
+ return [lindex $list $indexLst];
+ }
+ Lget [lindex $list [Lfirst $indexLst]] [Lrest $indexLst];
+}
+# Sets the value of one leaf of a lists tree
+# (we use the version that does not create the elements because
+# it would be even slower... needs to be written in C !)
+# (nb: there is a non trivial recursive problem with indexes 0,
+# which appear because there is no difference between a list
+# of 1 element and 1 element alone : [list "a"] == "a" while
+# it should be {a} and [listp a] should be 0 while [listp {a b}] would be 1
+# and [listp "a b"] maybe 0. listp does not exist either...)
+proc ::tcl::Lvarset {listName indexLst newValue} {
+ upvar $listName list;
+ if {[llength $indexLst] <= 1} {
+ Lvarset1nc list $indexLst $newValue;
+ } else {
+ set idx [Lfirst $indexLst];
+ set targetList [lindex $list $idx];
+ # reduce refcount on targetList (not really usefull now,
+ # could be with optimizing compiler)
+# Lvarset1 list $idx {};
+ # recursively replace in targetList
+ Lvarset targetList [Lrest $indexLst] $newValue;
+ # put updated sub list back in the tree
+ Lvarset1nc list $idx $targetList;
+ }
+}
+# Set one cell to a value, eventually create all the needed elements
+# (on level-1 of lists)
+variable emptyList {}
+proc ::tcl::Lvarset1 {listName index newValue} {
+ upvar $listName list;
+ if {$index < 0} {return -code error "invalid negative index"}
+ set lg [llength $list];
+ if {$index >= $lg} {
+ variable emptyList;
+ for {set i $lg} {$i<$index} {incr i} {
+ lappend list $emptyList;
+ }
+ lappend list $newValue;
+ } else {
+ set list [lreplace $list $index $index $newValue];
+ }
+}
+# same as Lvarset1 but no bound checking / creation
+proc ::tcl::Lvarset1nc {listName index newValue} {
+ upvar $listName list;
+ set list [lreplace $list $index $index $newValue];
+}
+# Increments the value of one leaf of a lists tree
+# (which must exists)
+proc ::tcl::Lvarincr {listName indexLst {howMuch 1}} {
+ upvar $listName list;
+ if {[llength $indexLst] <= 1} {
+ Lvarincr1 list $indexLst $howMuch;
+ } else {
+ set idx [Lfirst $indexLst];
+ set targetList [lindex $list $idx];
+ # reduce refcount on targetList
+ Lvarset1nc list $idx {};
+ # recursively replace in targetList
+ Lvarincr targetList [Lrest $indexLst] $howMuch;
+ # put updated sub list back in the tree
+ Lvarset1nc list $idx $targetList;
+ }
+}
+# Increments the value of one cell of a list
+proc ::tcl::Lvarincr1 {listName index {howMuch 1}} {
+ upvar $listName list;
+ set newValue [expr {[lindex $list $index]+$howMuch}];
+ set list [lreplace $list $index $index $newValue];
+ return $newValue;
+}
+# Returns the first element of a list
+proc ::tcl::Lfirst {list} {
+ lindex $list 0
+}
+# Returns the rest of the list minus first element
+proc ::tcl::Lrest {list} {
+ lrange $list 1 end
+}
+# Removes the first element of a list
+proc ::tcl::Lvarpop {listName} {
+ upvar $listName list;
+ set list [lrange $list 1 end];
+}
+# Same but returns the removed element
+proc ::tcl::Lvarpop2 {listName} {
+ upvar $listName list;
+ set el [Lfirst $list];
+ set list [lrange $list 1 end];
+ return $el;
+}
+# Assign list elements to variables and return the length of the list
+proc ::tcl::Lassign {list args} {
+ # faster than direct blown foreach (which does not byte compile)
+ set i 0;
+ set lg [llength $list];
+ foreach vname $args {
+ if {$i>=$lg} break
+ uplevel [list set $vname [lindex $list $i]];
+ incr i;
+ }
+ return $lg;
+}
+
+# Misc utilities
+
+# Set the varname to value if value is greater than varname's current value
+# or if varname is undefined
+proc ::tcl::SetMax {varname value} {
+ upvar 1 $varname var
+ if {![info exists var] || $value > $var} {
+ set var $value
+ }
+}
+
+# Set the varname to value if value is smaller than varname's current value
+# or if varname is undefined
+proc ::tcl::SetMin {varname value} {
+ upvar 1 $varname var
+ if {![info exists var] || $value < $var} {
+ set var $value
+ }
+}
+
+
+ # everything loaded fine, lets create the test proc:
+ OptCreateTestProc
+ # Don't need the create temp proc anymore:
+ rename OptCreateTestProc {}
+}
diff --git a/tcl/library/opt0.1/pkgIndex.tcl b/tcl/library/opt0.1/pkgIndex.tcl
new file mode 100644
index 00000000000..7f2baaf86cf
--- /dev/null
+++ b/tcl/library/opt0.1/pkgIndex.tcl
@@ -0,0 +1,7 @@
+# Tcl package index file, version 1.0
+# This file is NOT generated by the "pkg_mkIndex" command
+# because if someone just did "package require opt", let's just load
+# the package now, so they can readily use it
+# and even "namespace import tcl::*" ...
+# (tclPkgSetup just makes things slow and do not work so well with namespaces)
+package ifneeded opt 0.3 [list source [file join $dir optparse.tcl]]
diff --git a/tcl/tests/all b/tcl/tests/all
new file mode 100644
index 00000000000..2fec4725646
--- /dev/null
+++ b/tcl/tests/all
@@ -0,0 +1,22 @@
+# This file contains a top-level script to run all of the Tcl
+# tests. Execute it by invoking "source all" when running tclTest
+# in this directory.
+#
+# RCS: @(#) $Id$
+
+if {$tcl_platform(os) == "Win32s"} {
+ set files [glob *.tes]
+} else {
+ set files [glob *.test]
+}
+
+foreach i [lsort $files] {
+ if [string match l.*.test $i] {
+ # This is an SCCS lockfile
+ continue
+ }
+ puts stdout $i
+ if [catch {source $i} msg] {
+ puts $msg
+ }
+}
diff --git a/tcl/tests/defs b/tcl/tests/defs
new file mode 100644
index 00000000000..e4a87796e38
--- /dev/null
+++ b/tcl/tests/defs
@@ -0,0 +1,460 @@
+# This file contains support code for the Tcl test suite. It is
+# normally sourced by the individual files in the test suite before
+# they run their tests. This improved approach to testing was designed
+# and initially implemented by Mary Ann May-Pumphrey of Sun Microsystems.
+#
+# Copyright (c) 1990-1994 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id$
+
+if ![info exists srcdir] {
+ set srcdir .
+}
+
+if ![info exists VERBOSE] {
+ set VERBOSE 0
+}
+if ![info exists TESTS] {
+ set TESTS {}
+}
+
+# If tests are being run as root, issue a warning message and set a
+# variable to prevent some tests from running at all.
+
+set user {}
+if {$tcl_platform(platform) == "unix"} {
+ catch {set user [exec whoami]}
+ if {$user == ""} {
+ catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
+ }
+ if {$user == ""} {set user root}
+ if {$user == "root"} {
+ puts stdout "Warning: you're executing as root. I'll have to"
+ puts stdout "skip some of the tests, since they'll fail as root."
+ set testConfig(root) 1
+ }
+}
+
+# Some of the tests don't work on some system configurations due to
+# differences in word length, file system configuration, etc. In order
+# to prevent false alarms, these tests are generally only run in the
+# master development directory for Tcl. The presence of a file
+# "doAllTests" in this directory is used to indicate that the non-portable
+# tests should be run.
+
+# If there is no "memory" command (because memory debugging isn't
+# enabled), generate a dummy command that does nothing.
+
+if {[info commands memory] == ""} {
+ proc memory args {}
+}
+
+# Check configuration information that will determine which tests
+# to run. To do this, create an array testConfig. Each element
+# has a 0 or 1 value, and the following elements are defined:
+# unixOnly - 1 means this is a UNIX platform, so it's OK
+# to run tests that only work under UNIX.
+# macOnly - 1 means this is a Mac platform, so it's OK
+# to run tests that only work on Macs.
+# pcOnly - 1 means this is a PC platform, so it's OK to
+# run tests that only work on PCs.
+# unixOrPc - 1 means this is a UNIX or PC platform.
+# macOrPc - 1 means this is a Mac or PC platform.
+# macOrUnix - 1 means this is a Mac or UNIX platform.
+# nonPortable - 1 means this the tests are being running in
+# the master Tcl/Tk development environment;
+# Some tests are inherently non-portable because
+# they depend on things like word length, file system
+# configuration, window manager, etc. These tests
+# are only run in the main Tcl development directory
+# where the configuration is well known. The presence
+# of the file "doAllTests" in this directory indicates
+# that it is safe to run non-portable tests.
+# knownBug - The test is known to fail and the bug is not yet
+# fixed. The test will be run only if the file
+# "doBuggyTests" exists (intended for Tcl dev. group
+# internal use only).
+# tempNotPc - The inverse of pcOnly. This flag is used to
+# temporarily disable a test.
+# tempNotMac - The inverse of macOnly. This flag is used to
+# temporarily disable a test.
+# nonBlockFiles - 1 means this platform supports setting files into
+# nonblocking mode.
+# asyncPipeClose- 1 means this platform supports async flush and
+# async close on a pipe.
+# unixExecs - 1 means this machine has commands such as 'cat',
+# 'echo' etc available.
+# notIfCompiled - 1 means this that it is safe to run tests that
+# might fail if the bytecode compiler is used. This
+# element is set 1 if the file "doAllTests" exists in
+# this directory. Normally, this element is 0 so that
+# tests that fail with the bytecode compiler are
+# skipped. As of 11/2/96 these are the history tests
+# since they depend on accurate source location
+# information.
+
+catch {unset testConfig}
+if {$tcl_platform(platform) == "unix"} {
+ set testConfig(unixOnly) 1
+ set testConfig(tempNotPc) 1
+ set testConfig(tempNotMac) 1
+} else {
+ set testConfig(unixOnly) 0
+}
+if {$tcl_platform(platform) == "macintosh"} {
+ set testConfig(tempNotPc) 1
+ set testConfig(macOnly) 1
+} else {
+ set testConfig(macOnly) 0
+}
+if {$tcl_platform(platform) == "windows"} {
+ set testConfig(tempNotMac) 1
+ set testConfig(pcOnly) 1
+} else {
+ set testConfig(pcOnly) 0
+}
+set testConfig(unixOrPc) [expr $testConfig(unixOnly) || $testConfig(pcOnly)]
+set testConfig(macOrPc) [expr $testConfig(macOnly) || $testConfig(pcOnly)]
+set testConfig(macOrUnix) [expr $testConfig(macOnly) || $testConfig(unixOnly)]
+set testConfig(nonPortable) [expr [file exists doAllTests] || [file exists doAllTe]]
+set testConfig(knownBug) [expr [file exists doBuggyTests] || [file exists doBuggyT]]
+set testConfig(notIfCompiled) [file exists doAllCompilerTests]
+
+set testConfig(unix) $testConfig(unixOnly)
+set testConfig(mac) $testConfig(macOnly)
+set testConfig(pc) $testConfig(pcOnly)
+
+set testConfig(nt) [expr {$tcl_platform(os) == "Windows NT"}]
+set testConfig(95) [expr {$tcl_platform(os) == "Windows 95"}]
+set testConfig(win32s) [expr {$tcl_platform(os) == "Win32s"}]
+
+# The following config switches are used to mark tests that crash on
+# certain platforms, so that they can be reactivated again when the
+# underlying problem is fixed.
+
+set testConfig(pcCrash) $testConfig(macOrUnix)
+set testConfig(macCrash) $testConfig(unixOrPc)
+set testConfig(unixCrash) $testConfig(macOrPc)
+
+if {[catch {set f [open $srcdir/defs r]}]} {
+ set testConfig(nonBlockFiles) 1
+} else {
+ if {[expr [catch {fconfigure $f -blocking off}]] == 0} {
+ set testConfig(nonBlockFiles) 1
+ } else {
+ set testConfig(nonBlockFiles) 0
+ }
+ close $f
+}
+
+trace variable testConfig r safeFetch
+
+proc safeFetch {n1 n2 op} {
+ global testConfig
+
+ if {($n2 != {}) && ([info exists testConfig($n2)] == 0)} {
+ set testConfig($n2) 0
+ }
+}
+
+# Test for SCO Unix - cannot run async flushing tests because a potential
+# problem with select is apparently interfering. (Mark Diekhans).
+
+if {$tcl_platform(platform) == "unix"} {
+ if {[catch {exec uname -X | fgrep {Release = 3.2v}}] == 0} {
+ set testConfig(asyncPipeClose) 0
+ } else {
+ set testConfig(asyncPipeClose) 1
+ }
+} else {
+ set testConfig(asyncPipeClose) 1
+}
+
+# Test to see if we have a broken version of sprintf with respect to the
+# "e" format of floating-point numbers.
+
+set testConfig(eformat) 1
+if {[string compare "[format %g 5e-5]" "5e-05"] != 0} {
+ set testConfig(eformat) 0
+ puts "(will skip tests that depend on the \"e\" format of floating-point numbers)"
+}
+# Test to see if execed commands such as cat, echo, rm and so forth are
+# present on this machine.
+
+set testConfig(unixExecs) 1
+if {$tcl_platform(platform) == "macintosh"} {
+ set testConfig(unixExecs) 0
+}
+if {($testConfig(unixExecs) == 1) && ($tcl_platform(platform) == "windows")} {
+ if {[catch {exec cat $srcdir/defs}] == 1} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && ([catch {exec echo hello}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && \
+ ([catch {exec sh -c echo hello}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && ([catch {exec wc $srcdir/defs}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {$testConfig(unixExecs) == 1} {
+ exec echo hello > removeMe
+ if {[catch {exec rm removeMe}] == 1} {
+ set testConfig(unixExecs) 0
+ }
+ }
+ if {($testConfig(unixExecs) == 1) && ([catch {exec sleep 1}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && \
+ ([catch {exec fgrep unixExecs $srcdir/defs}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && ([catch {exec ps}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && \
+ ([catch {exec echo abc > removeMe}] == 0) && \
+ ([catch {exec chmod 644 removeMe}] == 1) && \
+ ([catch {exec rm removeMe}] == 0)} {
+ set testConfig(unixExecs) 0
+ } else {
+ catch {exec rm -f removeMe}
+ }
+ if {($testConfig(unixExecs) == 1) && \
+ ([catch {exec mkdir removeMe}] == 1)} {
+ set testConfig(unixExecs) 0
+ } else {
+ catch {exec rm -r removeMe}
+ }
+ if {$testConfig(unixExecs) == 0} {
+ puts stdout "Warning: Unix-style executables are not available, so"
+ puts stdout "some tests will be skipped."
+ }
+}
+
+proc print_verbose {name description constraints script code answer} {
+ puts stdout "\n"
+ if {[string length $constraints]} {
+ puts stdout "==== $name $description\t--- ($constraints) ---"
+ } else {
+ puts stdout "==== $name $description"
+ }
+ puts stdout "==== Contents of test case:"
+ puts stdout "$script"
+ if {$code != 0} {
+ if {$code == 1} {
+ puts stdout "==== Test generated error:"
+ puts stdout $answer
+ } elseif {$code == 2} {
+ puts stdout "==== Test generated return exception; result was:"
+ puts stdout $answer
+ } elseif {$code == 3} {
+ puts stdout "==== Test generated break exception"
+ } elseif {$code == 4} {
+ puts stdout "==== Test generated continue exception"
+ } else {
+ puts stdout "==== Test generated exception $code; message was:"
+ puts stdout $answer
+ }
+ } else {
+ puts stdout "==== Result was:"
+ puts stdout "$answer"
+ }
+}
+
+# test --
+# This procedure runs a test and prints an error message if the
+# test fails. If VERBOSE has been set, it also prints a message
+# even if the test succeeds. The test will be skipped if it
+# doesn't match the TESTS variable, or if one of the elements
+# of "constraints" turns out not to be true.
+#
+# Arguments:
+# name - Name of test, in the form foo-1.2.
+# description - Short textual description of the test, to
+# help humans understand what it does.
+# constraints - A list of one or more keywords, each of
+# which must be the name of an element in
+# the array "testConfig". If any of these
+# elements is zero, the test is skipped.
+# This argument may be omitted.
+# script - Script to run to carry out the test. It must
+# return a result that can be checked for
+# correctness.
+# answer - Expected result from script.
+
+proc test {name description script answer args} {
+ global VERBOSE TESTS testConfig
+ if {[string compare $TESTS ""] != 0} then {
+ set ok 0
+ foreach test $TESTS {
+ if [string match $test $name] then {
+ set ok 1
+ break
+ }
+ }
+ if !$ok then return
+ }
+ set i [llength $args]
+ if {$i == 0} {
+ set constraints {}
+ } elseif {$i == 1} {
+ # "constraints" argument exists; shuffle arguments down, then
+ # make sure that the constraints are satisfied.
+
+ set constraints $script
+ set script $answer
+ set answer [lindex $args 0]
+ set doTest 0
+ if {[string match {*[$\[]*} $constraints] != 0} {
+ # full expression, e.g. {$foo > [info tclversion]}
+
+ catch {set doTest [uplevel #0 expr [list $constraints]]} msg
+ } elseif {[regexp {[^.a-zA-Z0-9 ]+} $constraints] != 0} {
+ # something like {a || b} should be turned into
+ # $testConfig(a) || $testConfig(b).
+
+ regsub -all {[.a-zA-Z0-9]+} $constraints {$testConfig(&)} c
+ catch {set doTest [eval expr $c]}
+ } else {
+ # just simple constraints such as {unixOnly fonts}.
+
+ set doTest 1
+ foreach constraint $constraints {
+ if {![info exists testConfig($constraint)]
+ || !$testConfig($constraint)} {
+ set doTest 0
+ break
+ }
+ }
+ }
+ if {$doTest == 0} {
+ if $VERBOSE then {
+ puts stdout "++++ $name SKIPPED: $constraints"
+ }
+ return
+ }
+ } else {
+ error "wrong # args: must be \"test name description ?constraints? script answer\""
+ }
+ memory tag $name
+ set code [catch {uplevel $script} result]
+ if {$code != 0} {
+ print_verbose $name $description $constraints $script \
+ $code $result
+ } elseif {[string compare $result $answer] == 0} then {
+ if $VERBOSE then {
+ if {$VERBOSE > 0} {
+ print_verbose $name $description $constraints $script \
+ $code $result
+ }
+ if {$VERBOSE != -2} {
+ puts stdout "++++ $name PASSED"
+ }
+ }
+ } else {
+ print_verbose $name $description $constraints $script \
+ $code $result
+ puts stdout "---- Result should have been:"
+ puts stdout "$answer"
+ puts stdout "---- $name FAILED"
+ }
+}
+
+proc dotests {file args} {
+ global TESTS
+ set savedTests $TESTS
+ set TESTS $args
+ source $file
+ set TESTS $savedTests
+}
+
+proc normalizeMsg {msg} {
+ regsub "\n$" [string tolower $msg] "" msg
+ regsub -all "\n\n" $msg "\n" msg
+ regsub -all "\n\}" $msg "\}" msg
+ return $msg
+}
+
+proc makeFile {contents name} {
+ set fd [open $name w]
+ fconfigure $fd -translation lf
+ if {[string index $contents [expr [string length $contents] - 1]] == "\n"} {
+ puts -nonewline $fd $contents
+ } else {
+ puts $fd $contents
+ }
+ close $fd
+}
+
+proc removeFile {name} {
+ file delete $name
+}
+
+proc makeDirectory {name} {
+ file mkdir $name
+}
+
+proc removeDirectory {name} {
+ file delete -force $name
+}
+
+proc viewFile {name} {
+ global tcl_platform testConfig
+ if {($tcl_platform(platform) == "macintosh") || \
+ ($testConfig(unixExecs) == 0)} {
+ set f [open $name]
+ set data [read -nonewline $f]
+ close $f
+ return $data
+ } else {
+ exec cat $name
+ }
+}
+
+# Locate tcltest executable
+
+set tcltest [info nameofexecutable]
+
+if {$tcltest == "{}"} {
+ set tcltest {}
+ puts "Unable to find tcltest executable, multiple process tests will fail."
+}
+
+if {$tcl_platform(os) != "Win32s"} {
+ # Don't even try running another copy of tcltest under win32s, or you
+ # get an error dialog about multiple instances.
+
+ catch {
+ file delete -force tmp
+ set f [open tmp w]
+ puts $f {
+ exit
+ }
+ close $f
+ set f [open "|[list $tcltest tmp]" r]
+ close $f
+ set testConfig(stdio) 1
+ }
+ catch {file delete -force tmp}
+}
+
+if {($tcl_platform(platform) == "windows") && ($testConfig(stdio) == 0)} {
+ puts "(will skip tests that redirect stdio of exec'd 32-bit applications)"
+}
+
+catch {socket} msg
+set testConfig(socket) [expr {$msg != "sockets are not available on this system"}]
+
+if {$testConfig(socket) == 0} {
+ puts "(will skip tests that use sockets)"
+}
+
+
diff --git a/tcl/tests/iOUtil.test b/tcl/tests/iOUtil.test
new file mode 100644
index 00000000000..1faff7c1e3c
--- /dev/null
+++ b/tcl/tests/iOUtil.test
@@ -0,0 +1,300 @@
+# This file (iOUtil.test) tests the hookable TclStat(), TclAccess(),
+# and Tcl_OpenFileChannel, routines in the file generic/tclIOUtils.c.
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1998 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id$
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+set unsetScript {
+ catch {unset testStat1(size)}
+ catch {unset testStat2(size)}
+ catch {unset testStat3(size)}
+}
+
+test stat-1.1 {TclStat: Check that none of the test procs are there.} {
+ catch {file stat testStat1%.fil testStat1} err1
+ catch {file stat testStat2%.fil testStat2} err2
+ catch {file stat testStat3%.fil testStat3} err3
+ list $err1 $err2 $err3
+} {{couldn't stat "testStat1%.fil": no such file or directory} {couldn't stat "testStat2%.fil": no such file or directory} {couldn't stat "testStat3%.fil": no such file or directory}}
+
+if {[info commands teststatproc] == {}} {
+ puts "This application hasn't been compiled with the \"teststatproc\""
+ puts "command, so I can't test Tcl_Stat_* etc."
+} else {
+test stat-1.2 {TclStatInsertProc: Insert the 3 test TclStat_ procedures.} {
+ catch {teststatproc insert TclpStat} err1
+ teststatproc insert TestStatProc1
+ teststatproc insert TestStatProc2
+ teststatproc insert TestStatProc3
+ set err1
+} {bad arg "insert": must be TestStatProc1, TestStatProc2, or TestStatProc3}
+
+test stat-1.3 {TclStat: Use "file stat ?" to invoke each procedure.} {
+ file stat testStat2%.fil testStat2
+ file stat testStat1%.fil testStat1
+ file stat testStat3%.fil testStat3
+
+ list $testStat2(size) $testStat1(size) $testStat3(size)
+} {2345 1234 3456}
+
+eval $unsetScript
+
+test stat-1.4 {TclStatDeleteProc: "TclpStat" function should not be deletedable.} {
+ catch {teststatproc delete TclpStat} err2
+ set err2
+} {"TclpStat": could not be deleteed}
+
+test stat-1.5 {TclStatDeleteProc: Delete the 2nd TclStat procedure.} {
+ # Delete the 2nd procedure and test that it longer exists but that
+ # the others do actually return a result.
+
+ teststatproc delete TestStatProc2
+ file stat testStat1%.fil testStat1
+ catch {file stat testStat2%.fil testStat2} err3
+ file stat testStat3%.fil testStat3
+
+ list $testStat1(size) $err3 $testStat3(size)
+} {1234 {couldn't stat "testStat2%.fil": no such file or directory} 3456}
+
+eval $unsetScript
+
+test stat-1.6 {TclStatDeleteProc: Delete the 1st TclStat procedure.} {
+ # Next delete the 1st procedure and test that only the 3rd procedure
+ # is the only one that exists.
+
+ teststatproc delete TestStatProc1
+ catch {file stat testStat1%.fil testStat1} err4
+ catch {file stat testStat2%.fil testStat2} err5
+ file stat testStat3%.fil testStat3
+
+ list $err4 $err5 $testStat3(size)
+} {{couldn't stat "testStat1%.fil": no such file or directory} {couldn't stat "testStat2%.fil": no such file or directory} 3456}
+
+eval $unsetScript
+
+test stat-1.7 {TclStatDeleteProc: Delete the 3rd procedure & verify all are gone.} {
+ # Finally delete the 3rd procedure and check that none of the
+ # procedures exist.
+
+ teststatproc delete TestStatProc3
+ catch {file stat testStat1%.fil testStat1} err6
+ catch {file stat testStat2%.fil testStat2} err7
+ catch {file stat testStat3%.fil testStat3} err8
+
+ list $err6 $err7 $err8
+} {{couldn't stat "testStat1%.fil": no such file or directory} {couldn't stat "testStat2%.fil": no such file or directory} {couldn't stat "testStat3%.fil": no such file or directory}}
+
+eval $unsetScript
+
+test stat-1.8 {TclStatDeleteProc: Verify that all procs have been deleted.} {
+ # Attempt to delete all the Stat procs. again to ensure they no longer
+ # exist and an error is returned.
+
+ catch {teststatproc delete TestStatProc1} err9
+ catch {teststatproc delete TestStatProc2} err10
+ catch {teststatproc delete TestStatProc3} err11
+
+ list $err9 $err10 $err11
+} {{"TestStatProc1": could not be deleteed} {"TestStatProc2": could not be deleteed} {"TestStatProc3": could not be deleteed}}
+}
+
+eval $unsetScript
+
+
+test access-1.1 {TclAccess: Check that none of the test procs are there.} {
+ catch {file exists testAccess1%.fil} err1
+ catch {file exists testAccess2%.fil} err2
+ catch {file exists testAccess3%.fil} err3
+ list $err1 $err2 $err3
+} {0 0 0}
+
+if {[info commands testaccessproc] == {}} {
+ puts "This application hasn't been compiled with the \"testaccessproc\""
+ puts "command, so I can't test Tcl_Access_* etc."
+} else {
+test access-1.2 {TclAccessInsertProc: Insert the 3 test TclAccess_ procedures.} {
+ catch {testaccessproc insert TclpAccess} err1
+ testaccessproc insert TestAccessProc1
+ testaccessproc insert TestAccessProc2
+ testaccessproc insert TestAccessProc3
+ set err1
+} {bad arg "insert": must be TestAccessProc1, TestAccessProc2, or TestAccessProc3}
+
+test access-1.3 {TclAccess: Use "file access ?" to invoke each procedure.} {
+ list \
+ [file exists testAccess2%.fil] \
+ [file exists testAccess1%.fil] \
+ [file exists testAccess3%.fil]
+} {1 1 1}
+
+test access-1.4 {TclAccessDeleteProc: "TclpAccess" function should not be deletedable.} {
+ catch {testaccessproc delete TclpAccess} err2
+ set err2
+} {"TclpAccess": could not be deleteed}
+
+test accesst-1.5 {TclAccessDeleteProc: Delete the 2nd TclAccess procedure.} {
+ # Delete the 2nd procedure and test that it longer exists but that
+ # the others do actually return a result.
+
+ testaccessproc delete TestAccessProc2
+ set res1 [file exists testAccess1%.fil]
+ catch {file exists testAccess2%.fil} err3
+ set res2 [file exists testAccess3%.fil]
+
+ list $res1 $err3 $res2
+} {1 0 1}
+
+test access-1.6 {TclAccessDeleteProc: Delete the 1st TclAccess procedure.} {
+ # Next delete the 1st procedure and test that only the 3rd procedure
+ # is the only one that exists.
+
+ testaccessproc delete TestAccessProc1
+ catch {file exists testAccess1%.fil} err4
+ catch {file exists testAccess2%.fil} err5
+ set res3 [file exists testAccess3%.fil]
+
+ list $err4 $err5 $res3
+} {0 0 1}
+
+test access-1.7 {TclAccessDeleteProc: Delete the 3rd procedure & verify all are gone.} {
+ # Finally delete the 3rd procedure and check that none of the
+ # procedures exist.
+
+ testaccessproc delete TestAccessProc3
+ catch {file exists testAccess1%.fil} err6
+ catch {file exists testAccess2%.fil} err7
+ catch {file exists testAccess3%.fil} err8
+
+ list $err6 $err7 $err8
+} {0 0 0}
+
+test access-1.8 {TclAccessDeleteProc: Verify that all procs have been deleted.} {
+ # Attempt to delete all the Access procs. again to ensure they no longer
+ # exist and an error is returned.
+
+ catch {testaccessproc delete TestAccessProc1} err9
+ catch {testaccessproc delete TestAccessProc2} err10
+ catch {testaccessproc delete TestAccessProc3} err11
+
+ list $err9 $err10 $err11
+} {{"TestAccessProc1": could not be deleteed} {"TestAccessProc2": could not be deleteed} {"TestAccessProc3": could not be deleteed}}
+}
+
+test openfilechannel-1.1 {TclOpenFileChannel: Check that none of the test procs are there.} {
+ catch {file exists __testOpenFileChannel1%__.fil} err1
+ catch {file exists __testOpenFileChannel2%__.fil} err2
+ catch {file exists __testOpenFileChannel3%__.fil} err3
+ catch {file exists __testOpenFileChannel1%__.fil} err4
+ catch {file exists __testOpenFileChannel2%__.fil} err5
+ catch {file exists __testOpenFileChannel3%__.fil} err6
+ list $err1 $err2 $err3 $err4 $err5 $err6
+} {0 0 0 0 0 0}
+
+if {[info commands testopenfilechannelproc] == {}} {
+ puts "This application hasn't been compiled with the \"testopenfilechannelproc\""
+ puts "command, so I can't test Tcl_OpenFileChannelInsert"
+} else {
+test openfilechannel-1.2 {TclOpenFileChannelInsertProc: Insert the 3 test TclOpenFileChannel_ procedures.} {
+ catch {testopenfilechannelproc insert TclpOpenFileChannel} err1
+ testopenfilechannelproc insert TestOpenFileChannelProc1
+ testopenfilechannelproc insert TestOpenFileChannelProc2
+ testopenfilechannelproc insert TestOpenFileChannelProc3
+ set err1
+} {bad arg "insert": must be TestOpenFileChannelProc1, TestOpenFileChannelProc2, or TestOpenFileChannelProc3}
+
+test openfilechannel-1.3 {TclOpenFileChannel: Use "file openfilechannel ?" to invoke each procedure.} {
+ close [open __testOpenFileChannel1%__.fil w]
+ close [open __testOpenFileChannel2%__.fil w]
+ close [open __testOpenFileChannel3%__.fil w]
+
+ catch {
+ close [open testOpenFileChannel1%.fil r]
+ close [open testOpenFileChannel2%.fil r]
+ close [open testOpenFileChannel3%.fil r]
+ } err
+
+ file delete __testOpenFileChannel1%__.fil
+ file delete __testOpenFileChannel2%__.fil
+ file delete __testOpenFileChannel3%__.fil
+
+ set err
+} {}
+
+test openfilechannel-1.4 {TclOpenFileChannelDeleteProc: "TclpOpenFileChannel" function should not be deletedable.} {
+ catch {testopenfilechannelproc delete TclpOpenFileChannel} err2
+ set err2
+} {"TclpOpenFileChannel": could not be deleteed}
+
+test openfilechannelt-1.5 {TclOpenFileChannelDeleteProc: Delete the 2nd TclOpenFileChannel procedure.} {
+ # Delete the 2nd procedure and test that it longer exists but that
+ # the others do actually return a result.
+
+ testopenfilechannelproc delete TestOpenFileChannelProc2
+
+ close [open __testOpenFileChannel1%__.fil w]
+ close [open __testOpenFileChannel3%__.fil w]
+
+ catch {
+ close [open testOpenFileChannel1%.fil r]
+ catch {close [open testOpenFileChannel2%.fil r]}
+ close [open testOpenFileChannel3%.fil r]
+ } err3
+
+ file delete __testOpenFileChannel1%__.fil
+ file delete __testOpenFileChannel3%__.fil
+
+ set err3
+} {}
+
+test openfilechannel-1.6 {TclOpenFileChannelDeleteProc: Delete the 1st TclOpenFileChannel procedure.} {
+ # Next delete the 1st procedure and test that only the 3rd procedure
+ # is the only one that exists.
+
+ testopenfilechannelproc delete TestOpenFileChannelProc1
+
+ close [open __testOpenFileChannel3%__.fil w]
+
+ catch {
+ catch {close [open testOpenFileChannel1%.fil r]}
+ catch {close [open testOpenFileChannel2%.fil r]}
+ close [open testOpenFileChannel3%.fil r]
+ } err4
+
+ file delete __testOpenFileChannel3%__.fil
+
+ set err4
+} {}
+
+test openfilechannel-1.7 {TclOpenFileChannelDeleteProc: Delete the 3rd procedure & verify all are gone.} {
+ # Finally delete the 3rd procedure and check that none of the
+ # procedures exist.
+
+ testopenfilechannelproc delete TestOpenFileChannelProc3
+ catch {
+ catch [open testOpenFileChannel1%.fil r]
+ catch [open testOpenFileChannel2%.fil r]
+ catch [open testOpenFileChannel3%.fil r]
+ } err5
+
+ set err5
+} {1}
+
+test openfilechannel-1.8 {TclOpenFileChannelDeleteProc: Verify that all procs have been deleted.} {
+ # Attempt to delete all the OpenFileChannel procs. again to ensure they no longer
+ # exist and an error is returned.
+
+ catch {testopenfilechannelproc delete TestOpenFileChannelProc1} err9
+ catch {testopenfilechannelproc delete TestOpenFileChannelProc2} err10
+ catch {testopenfilechannelproc delete TestOpenFileChannelProc3} err11
+
+ list $err9 $err10 $err11
+} {{"TestOpenFileChannelProc1": could not be deleteed} {"TestOpenFileChannelProc2": could not be deleteed} {"TestOpenFileChannelProc3": could not be deleteed}}
+}
diff --git a/tcl/unix/porting.notes b/tcl/unix/porting.notes
new file mode 100644
index 00000000000..3d8b70089fe
--- /dev/null
+++ b/tcl/unix/porting.notes
@@ -0,0 +1,412 @@
+This file contains a collection of notes that various people have
+provided about porting Tcl to various machines and operating systems.
+I don't have personal access to any of these machines, so I make
+no guarantees that the notes are correct, complete, or up-to-date.
+If you see the word "I" in any explanations, it refers to the person
+who contributed the information, not to me; this means that I
+probably can't answer any questions about any of this stuff. In
+some cases, a person has volunteered to act as a contact point for
+questions about porting Tcl to a particular machine; in these
+cases the person's name and e-mail address are listed. I'm
+interested in getting new porting information to add to the file;
+please mail updates to "john.ousterhout@eng.sun.com".
+
+This file reflects information provided for Tcl 7.4 and later releases (8.x).
+If there is no information for your configuration in this file, check
+the file "porting.old" too; it contains information that was
+submitted for Tcl 7.3 and earlier releases, and some of that information
+may still be valid.
+
+A new porting database has recently become available on the Web at
+the following URL:
+ http://www.sunlabs.com/cgi-bin/tcl/info.8.0
+This page provides information about the platforms on which Tcl and
+and Tk 8.0 have been compiled and what changes were needed to get Tcl
+and Tk to compile. You can also add new entries to that database
+when you install Tcl and Tk on a new platform. The Web database is
+likely to be more up-to-date than this file.
+
+sccsid = RCS: @(#) $Id$
+
+--------------------------------------------
+Solaris, various versions
+--------------------------------------------
+
+1. If typing "make test" results in an error message saying that
+there are no "*.test" files, or you get lots of globbing errors,
+it's probably because your system doesn't have cc installed and
+you used gcc. In order for this to work, you have to set your
+CC environment variable to gcc and your CPP environment variable
+to "gcc -E" before running the configure script.
+
+2. Make sure that /usr/ucb is not in your PATH or LD_LIBRARY_PATH
+environment variables; this will cause confusion between the new
+Solaris libraries and older UCB versions (Tcl will expect one version
+and get another).
+
+3. There have been several reports of problems with the "glob" command.
+So far these reports have all been for older versions of Tcl, but
+if you run into problems, edit the Makefile after "configure" is
+run and add "-DNO_DIRENT_H=1" to the definitions of DEFS. Do this
+before compiling.
+
+--------------------------------------------
+SunOS 4 and potentially other OSes
+--------------------------------------------
+
+On systems where both getcwd(3) and getwd(3) exist, check the man
+page and if getcwd, like on SunOS 4, uses popen to pwd(1)
+add -DUSEGETWD to the flags CFLAGS so getwd will be used instead.
+
+That is, change the CFLAGS = -O line so it reads
+CFLAGS = -O -DUSEGETWD
+
+--------------------------------------------
+Linux, ELF, various versions/distributions
+--------------------------------------------
+
+If ./configure --enable-shared complains it can not do a shared
+library you might have to make the following symbolic link:
+ln -s /lib/libdl.so.1 /lib/libdl.so
+then remove config.cache and re run configure.
+
+--------------------------------------------
+Pyramid DC/OSx SVr4, DC/OSx version 94c079
+--------------------------------------------
+
+Tcl seems to dump core in cmdinfo.test when compiled with the
+optimiser turned on in TclEval which calls 'free'. To get around
+this, turn the optimiser off.
+
+--------------------------------------------
+SGI machines, IRIX 5.2, 5.3, IRIX64 6.0.1
+--------------------------------------------
+
+1. If you compile with gcc-2.6.3 under some versions of IRIX (e.g.
+ 4.0.5), DBL_MAX is defined too large for gcc and Tcl complains
+ about all floating-point values being too large to represent.
+ If this happens, redefining DBL_MAX to 9.99e299.
+
+2. Add "-D_BSD_TIME" to CFLAGS in Makefile. This avoids type conflicts
+in the prototype for the gettimeofday procedure.
+
+2. If you're running under Irix 6.x and tclsh dumps core, try
+removing -O from the CFLAGS in Makefile and recompiling; compiler
+optimizations seem to cause problems on some machines.
+
+--------------------------------------------
+IBM RTs, AOS
+--------------------------------------------
+
+1. Steal fmod from 4.4BSD
+2. Add a #define to tclExpr such that:
+extern double fmod();
+is defined conditionally on ibm032
+
+--------------------------------------------
+QNX 4.22
+--------------------------------------------
+
+tclPort.h
+ - commented out 2 lines containing #include <sys/param.h>
+
+tcl.h
+ - changed #define VARARGS ()
+ - to #ifndef __QNX__
+ #define VARARGS ()
+ #else
+ #define VARARGS (void *, ...)
+ #endif
+
+--------------------------------------------
+Interactive UNIX
+--------------------------------------------
+
+Add the switch -Xp to LIBS in Makefile; otherwise strftime will not
+be found when linking.
+
+--------------------------------------------
+Motorola SVR4 V4.2 (m88k)
+--------------------------------------------
+
+For Motorola Unix R40V4.2 (m88k architechure), use /usr/ucb/cc instead of
+/usr/bin/cc. Otherwise, the compile will fail because of conflicts over
+the gettimeofday() call.
+
+Also, -DNO_DIRENT_H=1 is required for the "glob" command to work.
+
+--------------------------------------------
+NeXTSTEP 3.x
+--------------------------------------------
+
+Here's the set of changes I made to make 7.5b3 compile cleanly on
+NeXTSTEP3.x.
+
+Here are a couple lines from unix/Makefile:
+
+# Added utsname.o, which implements a uname() emulation for NeXTSTEP.
+COMPAT_OBJS = getcwd.o strtod.o tmpnam.o utsname.o
+
+TCL_NAMES=\
+ -Dstrtod=tcl_strtod -Dtmpnam=tcl_tmpnam -Dgetcwd=tcl_getcwd \
+ -Dpanic=tcl_panic -Dmatherr=tcl_matherr \
+ -Duname=tcl_uname -Dutsname=tcl_utsname
+
+# Added mode_t, pid_t, and O_NONBLOCK definitions.
+AC_FLAGS = -DNO_DIRENT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_TIME_H=1
+-DTIME_WITH_SYS_TIME=1 -DHAVE_TM_ZONE=1 -DHAVE_TM_GMTOFF=1 -DHAVE_TIMEZONE_VAR=1
+-DSTDC_HEADERS=1 -Dmode_t=int -Dpid_t=int -DO_NONBLOCK=O_NDELAY ${TCL_NAMES}
+
+
+Here are diffs for other files. utsname.[hc] are a couple files I added
+to compat/ I'm not clear whether that's where they legitimately belong
+- I considered stashing them in tclLoadNext.c instead. The tclIO.c
+change was a bug, I believe, which I reported on comp.lang.tcl and
+has apparently been noted and fixed. The objc_loadModules() change
+allows "load" to load object code containing Objective-C code in
+addition to plain C code.
+
+---
+scott hess <shess@winternet.com> (WWW to "http://www.winternet.com/~shess/")
+Work: 12550 Portland Avenue South #121, Burnsville, MN 55337 (612)895-1208
+
+
+diff -rc tcl7.5b3.orig/compat/utsname.c tcl7.5b3/compat/utsname.c
+*** tcl7.5b3.orig/compat/utsname.c Tue Apr 2 13:57:23 1996
+--- tcl7.5b3/compat/utsname.c Mon Mar 18 11:05:54 1996
+***************
+*** 0 ****
+--- 1,27 ----
++ /*
++ * utsname.c --
++ *
++ * This file is an emulation of the POSIX uname() function
++ * under NeXTSTEP 3.x.
++ *
++ */
++
+
++ #include "utsname.h"
++ #include <mach-o/arch.h>
++ #include <stdio.h>
++
+
++ int uname( struct utsname *name)
++ {
++ const NXArchInfo *arch;
++ if( gethostname( name->nodename, sizeof( name->nodename))==-1) {
++ return -1;
++ }
++ if( (arch=NXGetLocalArchInfo())==NULL) {
++ return -1;
++ }
++ strncpy( name->machine, arch->description, sizeof( name->machine));
++ strcpy( name->sysname, "NEXTSTEP");
++ strcpy( name->release, "0");
++ strcpy( name->version, "3");
++ return 0;
++ }
+diff -rc tcl7.5b3.orig/compat/utsname.h tcl7.5b3/compat/utsname.h
+*** tcl7.5b3.orig/compat/utsname.h Tue Apr 2 13:57:26 1996
+--- tcl7.5b3/compat/utsname.h Mon Mar 18 10:34:05 1996
+***************
+*** 0 ****
+--- 1,22 ----
++ /*
++ * utsname.h --
++ *
++ * This file is an emulation of the POSIX uname() function
++ * under NeXTSTEP.
++ *
++ */
++
+
++ #ifndef _UTSNAME
++ #define _UTSNAME
++
+
++ struct utsname {
++ char sysname[ 32];
++ char nodename[ 32];
++ char release[ 32];
++ char version[ 32];
++ char machine[ 32];
++ };
++
+
++ extern int uname( struct utsname *name);
++
+
++ #endif /* _UTSNAME */
+diff -rc tcl7.5b3.orig/generic/tclIO.c tcl7.5b3/generic/tclIO.c
+*** tcl7.5b3.orig/generic/tclIO.c Fri Mar 8 12:59:53 1996
+--- tcl7.5b3/generic/tclIO.c Mon Mar 18 11:38:57 1996
+***************
+*** 2542,2548 ****
+ }
+ result = GetInput(chanPtr);
+ if (result != 0) {
+! if (result == EWOULDBLOCK) {
+ chanPtr->flags |= CHANNEL_BLOCKED;
+ return copied;
+ }
+--- 2542,2548 ----
+ }
+ result = GetInput(chanPtr);
+ if (result != 0) {
+! if (result == EAGAIN) {
+ chanPtr->flags |= CHANNEL_BLOCKED;
+ return copied;
+ }
+diff -rc tcl7.5b3.orig/unix/tclLoadNext.c tcl7.5b3/unix/tclLoadNext.c
+*** tcl7.5b3.orig/unix/tclLoadNext.c Sat Feb 17 16:16:42 1996
+--- tcl7.5b3/unix/tclLoadNext.c Mon Mar 18 10:02:36 1996
+***************
+*** 55,61 ****
+ char *files[]={fileName,NULL};
+ NXStream *errorStream=NXOpenMemory(0,0,NX_READWRITE);
+
+
+! if(!rld_load(errorStream,&header,files,NULL)) {
+ NXGetMemoryBuffer(errorStream,&data,&len,&maxlen);
+ Tcl_AppendResult(interp,"couldn't load file \"",fileName,"\": ",data,NULL);
+ NXCloseMemory(errorStream,NX_FREEBUFFER);
+--- 55,61 ----
+ char *files[]={fileName,NULL};
+ NXStream *errorStream=NXOpenMemory(0,0,NX_READWRITE);
+
+
+! if(objc_loadModules(files,errorStream,NULL,&header,NULL)) {
+ NXGetMemoryBuffer(errorStream,&data,&len,&maxlen);
+ Tcl_AppendResult(interp,"couldn't load file \"",fileName,"\": ",data,NULL);
+ NXCloseMemory(errorStream,NX_FREEBUFFER);
+diff -rc tcl7.5b3.orig/unix/tclUnixFile.c tcl7.5b3/unix/tclUnixFile.c
+*** tcl7.5b3.orig/unix/tclUnixFile.c Thu Mar 7 18:16:34 1996
+--- tcl7.5b3/unix/tclUnixFile.c Mon Mar 18 11:10:03 1996
+***************
+*** 31,37 ****
+--- 31,41 ----
+
+
+ static int executableNameExitHandlerSet = 0;
+
+
++ #if NeXT
++ #define waitpid( p, s, o) wait4( p, s, o, NULL)
++ #else
+ extern pid_t waitpid _ANSI_ARGS_((pid_t pid, int *stat_loc, int options));
++ #endif
+
+
+ /*
+ * Static routines for this file:
+diff -rc tcl7.5b3.orig/unix/tclUnixInit.c tcl7.5b3/unix/tclUnixInit.c
+*** tcl7.5b3.orig/unix/tclUnixInit.c Sat Feb 17 16:16:39 1996
+--- tcl7.5b3/unix/tclUnixInit.c Mon Mar 18 11:50:28 1996
+***************
+*** 14,20 ****
+ #include "tclInt.h"
+ #include "tclPort.h"
+ #ifndef NO_UNAME
+! # include <sys/utsname.h>
+ #endif
+ #if defined(__FreeBSD__)
+ #include <floatingpoint.h>
+--- 14,24 ----
+ #include "tclInt.h"
+ #include "tclPort.h"
+ #ifndef NO_UNAME
+! # if NeXT
+! # include "../compat/utsname.h"
+! # else
+! # include <sys/utsname.h>
+! # endif
+ #endif
+ #if defined(__FreeBSD__)
+ #include <floatingpoint.h>
+diff -rc tcl7.5b3.orig/unix/tclUnixPort.h tcl7.5b3/unix/tclUnixPort.h
+*** tcl7.5b3.orig/unix/tclUnixPort.h Thu Mar 7 18:16:31 1996
+--- tcl7.5b3/unix/tclUnixPort.h Mon Mar 18 11:53:14 1996
+***************
+*** 76,82 ****
+ */
+
+
+ #include <sys/socket.h> /* struct sockaddr, SOCK_STREAM, ... */
+! #include <sys/utsname.h> /* uname system call. */
+ #include <netinet/in.h> /* struct in_addr, struct sockaddr_in */
+ #include <arpa/inet.h> /* inet_ntoa() */
+ #include <netdb.h> /* gethostbyname() */
+--- 76,88 ----
+ */
+
+
+ #include <sys/socket.h> /* struct sockaddr, SOCK_STREAM, ... */
+! #ifndef NO_UNAME
+! # if NeXT
+! # include "../compat/utsname.h"
+! # else
+! # include <sys/utsname.h> /* uname system call. */
+! # endif
+! #endif
+ #include <netinet/in.h> /* struct in_addr, struct sockaddr_in */
+ #include <arpa/inet.h> /* inet_ntoa() */
+ #include <netdb.h> /* gethostbyname() */
+
+--------------------------------------------
+SCO Unix 3.2.4 (ODT 3.0)
+--------------------------------------------
+
+The macro va_start in /usr/include/stdarg.h is incorrectly terminated by
+a semi-colon. This causes compile of generic/tclBasic.c to fail. The
+best solution is to edit the definition of va_start to remove the `;'.
+This will fix this file for anything you want to compile. If you don't have
+permission to edit /usr/include/stdarg.h in place, copy it to the tcl unix
+directory and change it there.
+
+Contact me directly if you have problems on SCO systems.
+Mark Diekhans <markd@grizzly.com>
+
+--------------------------------------------
+SCO Unix 3.2.5 (ODT 5.0)
+--------------------------------------------
+
+Expect failures from socket tests 2.9 and 3.1.
+
+Contact me directly if you have problems on SCO systems.
+Mark Diekhans <markd@grizzly.com>
+
+--------------------------------------------
+Linux 1.2.13 (gcc 2.7.0, libc.so.5.0.9)
+--------------------------------------------
+
+Symptoms:
+
+* Some extensions could not be loaded dynamically, most
+ prominently Blt 2.0
+
+ The given error message essentially said:
+ Could not resolve symbol '__eprintf'.
+
+ (This procedure is used by the macro 'assert')
+
+Cause
+
+* '__eprintf' is defined in 'libgcc.a', not 'libc.so.x.y'.
+ It is therefore impossible to load it dynamically.
+
+* Neither tcl nor tk make use of 'assert', thereby
+ preventing a static linkage.
+
+Workaround
+
+* I included <assert.h> in 'tclAppInit.c' / 'tkAppInit.c'
+ and then executed 'assert (argc)' just before the call
+ to Tcl_Main / Tk_Main.
+
+ This forced the static linkage of '__eprintf' and
+ everything went fine from then on.
+
+ (Something like 'assert (1)', 'assert (a==a)' is not
+ sufficient, it will be optimized away).
+
diff --git a/tcl/win/pkgIndex.tcl b/tcl/win/pkgIndex.tcl
new file mode 100644
index 00000000000..11865573017
--- /dev/null
+++ b/tcl/win/pkgIndex.tcl
@@ -0,0 +1,11 @@
+# Tcl package index file, version 1.0
+# This file contains package information for Windows-specific extensions.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id$
+
+package ifneeded registry 1.0 [list tclPkgSetup $dir registry 1.0 {{tclreg80.dll load registry}}]
diff --git a/tcl/win/tcl16.rc b/tcl/win/tcl16.rc
new file mode 100644
index 00000000000..a7242b727c7
--- /dev/null
+++ b/tcl/win/tcl16.rc
@@ -0,0 +1,37 @@
+// RCS: @(#) $Id$
+//
+// Version
+//
+
+#define RESOURCE_INCLUDED
+#include <tcl.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
+ PRODUCTVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
+ FILEFLAGSMASK 0x3fL
+ FILEFLAGS 0x0L
+ FILEOS 0x1L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Tcl16 DLL, 16-bit thunking module\0"
+ VALUE "OriginalFilename", "tcl16" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".dll\0"
+ VALUE "CompanyName", "Sun Microsystems, Inc\0"
+ VALUE "FileVersion", TCL_PATCH_LEVEL
+ VALUE "LegalCopyright", "Copyright \251 1995-1996\0"
+ VALUE "ProductName", "Tcl " TCL_VERSION " for Windows\0"
+ VALUE "ProductVersion", TCL_PATCH_LEVEL
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
diff --git a/tcl/win/tclWin16.c b/tcl/win/tclWin16.c
new file mode 100644
index 00000000000..d55ea808259
--- /dev/null
+++ b/tcl/win/tclWin16.c
@@ -0,0 +1,347 @@
+/*
+ * tclWin16.c --
+ *
+ * This file contains code for a 16-bit DLL to handle 32-to-16 bit
+ * thunking. This is necessary for the Win32s SynchSpawn() call.
+ *
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id$
+ */
+
+#define STRICT
+
+#include <windows.h>
+#include <toolhelp.h>
+
+#include <stdio.h>
+#include <string.h>
+
+static int WinSpawn(char *command);
+static int DosSpawn(char *command, char *fromFileName,
+ char *toFileName);
+static int WaitForExit(int inst);
+
+/*
+ * The following data is used to construct a .pif file that wraps the
+ * .bat file that runs the 16-bit application (that Jack built).
+ * The .pif file causes the .bat file to run in an iconified window.
+ * Otherwise, when we try to exec something, a DOS box pops up,
+ * obscuring everything, and then almost immediately flickers out of
+ * existence, which is rather disconcerting.
+ */
+
+static char pifData[545] = {
+'\000', '\013', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\200', '\000', '\200', '\000', '\103', '\117', '\115', '\115',
+'\101', '\116', '\104', '\056', '\103', '\117', '\115', '\000',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\020', '\000', '\000', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\177', '\001', '\000',
+'\377', '\031', '\120', '\000', '\000', '\007', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\340',
+'\040', '\115', '\111', '\103', '\122', '\117', '\123', '\117',
+'\106', '\124', '\040', '\120', '\111', '\106', '\105', '\130',
+'\000', '\207', '\001', '\000', '\000', '\161', '\001', '\127',
+'\111', '\116', '\104', '\117', '\127', '\123', '\040', '\063',
+'\070', '\066', '\040', '\063', '\056', '\060', '\000', '\005',
+'\002', '\235', '\001', '\150', '\000', '\200', '\002', '\200',
+'\000', '\144', '\000', '\062', '\000', '\000', '\004', '\000',
+'\000', '\000', '\004', '\000', '\000', '\002', '\020', '\002',
+'\000', '\037', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\057', '\143', '\040',
+'\146', '\157', '\157', '\056', '\142', '\141', '\164', '\000',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040',
+'\040', '\040', '\040', '\040', '\040', '\127', '\111', '\116',
+'\104', '\117', '\127', '\123', '\040', '\062', '\070', '\066',
+'\040', '\063', '\056', '\060', '\000', '\377', '\377', '\033',
+'\002', '\006', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000'
+};
+
+static HINSTANCE hInstance;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * LibMain --
+ *
+ * 16-bit DLL entry point.
+ *
+ * Results:
+ * Returns 1.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int CALLBACK
+LibMain(
+ HINSTANCE hinst,
+ WORD wDS,
+ WORD cbHeap,
+ LPSTR unused)
+{
+ hInstance = hinst;
+ wDS = wDS; /* lint. */
+ cbHeap = cbHeap; /* lint. */
+ unused = unused; /* lint. */
+
+ return TRUE;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UTProc --
+ *
+ * Universal Thunk dispatch routine. Executes a 16-bit DOS
+ * application or a 16-bit or 32-bit Windows application and
+ * waits for it to complete.
+ *
+ * Results:
+ * 1 if the application could be run, 0 or -1 on failure.
+ *
+ * Side effects:
+ * Executes 16-bit code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int WINAPI
+UTProc(buf, func)
+ void *buf;
+ DWORD func;
+{
+ char **args;
+
+ args = (char **) buf;
+ if (func == 0) {
+ return DosSpawn(args[0], args[1], args[2]);
+ } else {
+ return WinSpawn(args[0]);
+ }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * WinSpawn --
+ *
+ * Start a 16-bit or 32-bit Windows application with optional
+ * command line arguments and wait for it to finish. Windows
+ * applications do not handle input/output redirection.
+ *
+ * Results:
+ * The return value is 1 if the application could be run, 0 otherwise.
+ *
+ * Side effects:
+ * Whatever the application does.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+WinSpawn(command)
+ char *command; /* The command line, consisting of the name
+ * of the executable to run followed by any
+ * number of arguments to the executable. */
+{
+ return WaitForExit(WinExec(command, SW_SHOW));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DosSpawn --
+ *
+ * Start a 16-bit DOS program with optional command line arguments
+ * and wait for it to finish. Input and output can be redirected
+ * from the specified files, but there is no such thing as stderr
+ * under Win32s.
+ *
+ * This procedure to constructs a temporary .pif file that wraps a
+ * temporary .bat file that runs the 16-bit application. The .bat
+ * file is necessary to get the redirection symbols '<' and '>' to
+ * work, because WinExec() doesn't accept them. The .pif file is
+ * necessary to cause the .bat file to run in an iconified window,
+ * to avoid having a large DOS box pop up, obscuring everything, and
+ * then almost immediately flicker out of existence, which is rather
+ * disconcerting.
+ *
+ * Results:
+ * The return value is 1 if the application could be run, 0 otherwise.
+ *
+ * Side effects:
+ * Whatever the application does.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+DosSpawn(command, fromFileName, toFileName)
+ char *command; /* The name of the program, plus any
+ * arguments, to be run. */
+ char *fromFileName; /* Standard input for the program is to be
+ * redirected from this file, or NULL for no
+ * standard input. */
+ char *toFileName; /* Standard output for the program is to be
+ * redirected to this file, or NULL to
+ * discard standard output. */
+{
+ int result;
+ HFILE batFile, pifFile;
+ char batFileName[144], pifFileName[144];
+
+ GetTempFileName(0, "tcl", 0, batFileName);
+ unlink(batFileName);
+ strcpy(strrchr(batFileName, '.'), ".bat");
+ batFile = _lcreat(batFileName, 0);
+
+ GetTempFileName(0, "tcl", 0, pifFileName);
+ unlink(pifFileName);
+ strcpy(strrchr(pifFileName, '.'), ".pif");
+ pifFile = _lcreat(pifFileName, 0);
+
+ _lwrite(batFile, command, strlen(command));
+ if (fromFileName == NULL) {
+ _lwrite(batFile, " < nul", 6);
+ } else {
+ _lwrite(batFile, " < ", 3);
+ _lwrite(batFile, fromFileName, strlen(fromFileName));
+ }
+ if (toFileName == NULL) {
+ _lwrite(batFile, " > nul", 6);
+ } else {
+ _lwrite(batFile, " > ", 3);
+ _lwrite(batFile, toFileName, strlen(toFileName));
+ }
+ _lwrite(batFile, "\r\n\032", 3);
+ _lclose(batFile);
+
+ strcpy(pifData + 0x1c8, batFileName);
+ _lwrite(pifFile, pifData, sizeof(pifData));
+ _lclose(pifFile);
+
+ result = WaitForExit(WinExec(pifFileName, SW_MINIMIZE));
+
+ unlink(pifFileName);
+ unlink(batFileName);
+
+ return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * WaitForExit --
+ *
+ * Wait until the application with the given instance handle has
+ * finished. PeekMessage() is used to yield the processor;
+ * otherwise, nothing else could execute on the system.
+ *
+ * Results:
+ * The return value is 1 if the process exited successfully,
+ * or 0 otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+WaitForExit(inst)
+ int inst; /* Identifies the instance handle of the
+ * process to wait for. */
+{
+ TASKENTRY te;
+ MSG msg;
+ UINT timer;
+
+ if (inst < 32) {
+ return 0;
+ }
+
+ te.dwSize = sizeof(te);
+ te.hInst = 0;
+ TaskFirst(&te);
+ do {
+ if (te.hInst == (HINSTANCE) inst) {
+ break;
+ }
+ } while (TaskNext(&te) != FALSE);
+
+ if (te.hInst != (HINSTANCE) inst) {
+ return 0;
+ }
+
+ timer = SetTimer(NULL, 0, 0, NULL);
+ while (1) {
+ if (GetMessage(&msg, NULL, 0, 0) != 0) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ TaskFirst(&te);
+ do {
+ if (te.hInst == (HINSTANCE) inst) {
+ break;
+ }
+ } while (TaskNext(&te) != FALSE);
+
+ if (te.hInst != (HINSTANCE) inst) {
+ KillTimer(NULL, timer);
+ return 1;
+ }
+ }
+}
diff --git a/tcl/win/winDumpExts.c b/tcl/win/winDumpExts.c
new file mode 100644
index 00000000000..12267e977d4
--- /dev/null
+++ b/tcl/win/winDumpExts.c
@@ -0,0 +1,503 @@
+/*
+ * winDumpExts.c --
+ * Author: Gordon Chaffee, Scott Stanton
+ *
+ * History: The real functionality of this file was written by
+ * Matt Pietrek in 1993 in his pedump utility. I've
+ * modified it to dump the externals in a bunch of object
+ * files to create a .def file.
+ *
+ * 10/12/95 Modified by Scott Stanton to support Relocatable Object Module
+ * Format files for Borland C++ 4.5.
+ *
+ * Notes: Visual C++ puts an underscore before each exported symbol.
+ * This file removes them. I don't know if this is a problem
+ * this other compilers. If _MSC_VER is defined,
+ * the underscore is removed. If not, it isn't. To get a
+ * full dump of an object file, use the -f option. This can
+ * help determine the something that may be different with a
+ * compiler other than Visual C++.
+ *----------------------------------------------------------------------
+ *
+ * RCS: @(#) $Id$
+ */
+
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+#include <process.h>
+
+#ifdef _ALPHA_
+#define e_magic_number IMAGE_FILE_MACHINE_ALPHA
+#else
+#define e_magic_number IMAGE_FILE_MACHINE_I386
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ * GetArgcArgv --
+ *
+ * Break up a line into argc argv
+ *----------------------------------------------------------------------
+ */
+int
+GetArgcArgv(char *s, char **argv)
+{
+ int quote = 0;
+ int argc = 0;
+ char *bp;
+
+ bp = s;
+ while (1) {
+ while (isspace(*bp)) {
+ bp++;
+ }
+ if (*bp == '\n' || *bp == '\0') {
+ *bp = '\0';
+ return argc;
+ }
+ if (*bp == '\"') {
+ quote = 1;
+ bp++;
+ }
+ argv[argc++] = bp;
+
+ while (*bp != '\0') {
+ if (quote) {
+ if (*bp == '\"') {
+ quote = 0;
+ *bp = '\0';
+ bp++;
+ break;
+ }
+ bp++;
+ continue;
+ }
+ if (isspace(*bp)) {
+ *bp = '\0';
+ bp++;
+ break;
+ }
+ bp++;
+ }
+ }
+}
+
+/*
+ * The names of the first group of possible symbol table storage classes
+ */
+char * SzStorageClass1[] = {
+ "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
+ "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
+ "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
+ "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
+};
+
+/*
+ * The names of the second group of possible symbol table storage classes
+ */
+char * SzStorageClass2[] = {
+ "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
+};
+
+/*
+ *----------------------------------------------------------------------
+ * GetSZStorageClass --
+ *
+ * Given a symbol storage class value, return a descriptive
+ * ASCII string
+ *----------------------------------------------------------------------
+ */
+PSTR
+GetSZStorageClass(BYTE storageClass)
+{
+ if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
+ return SzStorageClass1[storageClass];
+ else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
+ && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
+ return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
+ else
+ return "???";
+}
+
+/*
+ *----------------------------------------------------------------------
+ * GetSectionName --
+ *
+ * Used by DumpSymbolTable, it gives meaningful names to
+ * the non-normal section number.
+ *
+ * Results:
+ * A name is returned in buffer
+ *----------------------------------------------------------------------
+ */
+void
+GetSectionName(WORD section, PSTR buffer, unsigned cbBuffer)
+{
+ char tempbuffer[10];
+
+ switch ( (SHORT)section )
+ {
+ case IMAGE_SYM_UNDEFINED: strcpy(tempbuffer, "UNDEF"); break;
+ case IMAGE_SYM_ABSOLUTE: strcpy(tempbuffer, "ABS "); break;
+ case IMAGE_SYM_DEBUG: strcpy(tempbuffer, "DEBUG"); break;
+ default: wsprintf(tempbuffer, "%-5X", section);
+ }
+
+ strncpy(buffer, tempbuffer, cbBuffer-1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ * DumpSymbolTable --
+ *
+ * Dumps a COFF symbol table from an EXE or OBJ. We only use
+ * it to dump tables from OBJs.
+ *----------------------------------------------------------------------
+ */
+void
+DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
+{
+ unsigned i;
+ PSTR stringTable;
+ char sectionName[10];
+
+ fprintf(fout, "Symbol Table - %X entries (* = auxillary symbol)\n",
+ cSymbols);
+
+ fprintf(fout,
+ "Indx Name Value Section cAux Type Storage\n"
+ "---- -------------------- -------- ---------- ----- ------- --------\n");
+
+ /*
+ * The string table apparently starts right after the symbol table
+ */
+ stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+ for ( i=0; i < cSymbols; i++ ) {
+ fprintf(fout, "%04X ", i);
+ if ( pSymbolTable->N.Name.Short != 0 )
+ fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
+ else
+ fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
+
+ fprintf(fout, " %08X", pSymbolTable->Value);
+
+ GetSectionName(pSymbolTable->SectionNumber, sectionName,
+ sizeof(sectionName));
+ fprintf(fout, " sect:%s aux:%X type:%02X st:%s\n",
+ sectionName,
+ pSymbolTable->NumberOfAuxSymbols,
+ pSymbolTable->Type,
+ GetSZStorageClass(pSymbolTable->StorageClass) );
+#if 0
+ if ( pSymbolTable->NumberOfAuxSymbols )
+ DumpAuxSymbols(pSymbolTable);
+#endif
+
+ /*
+ * Take into account any aux symbols
+ */
+ i += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable++;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ * DumpExternals --
+ *
+ * Dumps a COFF symbol table from an EXE or OBJ. We only use
+ * it to dump tables from OBJs.
+ *----------------------------------------------------------------------
+ */
+void
+DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
+{
+ unsigned i;
+ PSTR stringTable;
+ char *s, *f;
+ char symbol[1024];
+
+ /*
+ * The string table apparently starts right after the symbol table
+ */
+ stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+ for ( i=0; i < cSymbols; i++ ) {
+ if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
+ if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+ if (pSymbolTable->N.Name.Short != 0) {
+ strncpy(symbol, pSymbolTable->N.ShortName, 8);
+ symbol[8] = 0;
+ } else {
+ s = stringTable + pSymbolTable->N.Name.Long;
+ strcpy(symbol, s);
+ }
+ s = symbol;
+ f = strchr(s, '@');
+ if (f) {
+ *f = 0;
+ }
+#if defined(_MSC_VER) && defined(_X86_)
+ if (symbol[0] == '_') {
+ s = &symbol[1];
+ }
+#endif
+ if ((stricmp(s, "DllEntryPoint") != 0)
+ && (stricmp(s, "DllMain") != 0)) {
+ fprintf(fout, "\t%s\n", s);
+ }
+ }
+ }
+
+ /*
+ * Take into account any aux symbols
+ */
+ i += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable++;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ * DumpObjFile --
+ *
+ * Dump an object file--either a full listing or just the exported
+ * symbols.
+ *----------------------------------------------------------------------
+ */
+void
+DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full)
+{
+ PIMAGE_SYMBOL PCOFFSymbolTable;
+ DWORD COFFSymbolCount;
+
+ PCOFFSymbolTable = (PIMAGE_SYMBOL)
+ ((DWORD)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
+ COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
+
+ if (full) {
+ DumpSymbolTable(PCOFFSymbolTable, fout, COFFSymbolCount);
+ } else {
+ DumpExternals(PCOFFSymbolTable, fout, COFFSymbolCount);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ * SkipToNextRecord --
+ *
+ * Skip over the current ROMF record and return the type of the
+ * next record.
+ *----------------------------------------------------------------------
+ */
+
+BYTE
+SkipToNextRecord(BYTE **ppBuffer)
+{
+ int length;
+ (*ppBuffer)++; /* Skip over the type.*/
+ length = *((WORD*)(*ppBuffer))++; /* Retrieve the length. */
+ *ppBuffer += length; /* Skip over the rest. */
+ return **ppBuffer; /* Return the type. */
+}
+
+/*
+ *----------------------------------------------------------------------
+ * DumpROMFObjFile --
+ *
+ * Dump a Relocatable Object Module Format file, displaying only
+ * the exported symbols.
+ *----------------------------------------------------------------------
+ */
+void
+DumpROMFObjFile(LPVOID pBuffer, FILE *fout)
+{
+ BYTE type, length;
+ char symbol[1024], *s;
+
+ while (1) {
+ type = SkipToNextRecord(&(BYTE*)pBuffer);
+ if (type == 0x90) { /* PUBDEF */
+ if (((BYTE*)pBuffer)[4] != 0) {
+ length = ((BYTE*)pBuffer)[5];
+ strncpy(symbol, ((char*)pBuffer) + 6, length);
+ symbol[length] = '\0';
+ s = symbol;
+ if ((stricmp(s, "DllEntryPoint") != 0)
+ && (stricmp(s, "DllMain") != 0)) {
+ if (s[0] == '_') {
+ s++;
+ fprintf(fout, "\t_%s\n\t%s=_%s\n", s, s, s);
+ } else {
+ fprintf(fout, "\t%s\n", s);
+ }
+ }
+ }
+ } else if (type == 0x8B || type == 0x8A) { /* MODEND */
+ break;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ * DumpFile --
+ *
+ * Open up a file, memory map it, and call the appropriate
+ * dumping routine
+ *----------------------------------------------------------------------
+ */
+void
+DumpFile(LPSTR filename, FILE *fout, int full)
+{
+ HANDLE hFile;
+ HANDLE hFileMapping;
+ LPVOID lpFileBase;
+ PIMAGE_DOS_HEADER dosHeader;
+
+ hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ fprintf(stderr, "Couldn't open file with CreateFile()\n");
+ return;
+ }
+
+ hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (hFileMapping == 0) {
+ CloseHandle(hFile);
+ fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
+ return;
+ }
+
+ lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
+ if (lpFileBase == 0) {
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+ fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
+ return;
+ }
+
+ dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
+ if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
+#if 0
+ DumpExeFile( dosHeader );
+#else
+ fprintf(stderr, "File is an executable. I don't dump those.\n");
+ return;
+#endif
+ }
+ /* Does it look like a i386 COFF OBJ file??? */
+ else if ((dosHeader->e_magic == e_magic_number)
+ && (dosHeader->e_sp == 0)) {
+ /*
+ * The two tests above aren't what they look like. They're
+ * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
+ * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
+ */
+ DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full);
+ } else if (*((BYTE *)lpFileBase) == 0x80) {
+ /*
+ * This file looks like it might be a ROMF file.
+ */
+ DumpROMFObjFile(lpFileBase, fout);
+ } else {
+ printf("unrecognized file format\n");
+ }
+ UnmapViewOfFile(lpFileBase);
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+}
+
+void
+main(int argc, char **argv)
+{
+ char *fargv[1000];
+ char cmdline[10000];
+ int i, arg;
+ FILE *fout;
+ int pos;
+ int full = 0;
+ char *outfile = NULL;
+
+ if (argc < 3) {
+ Usage:
+ fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
+ exit(1);
+ }
+
+ arg = 1;
+ while (argv[arg][0] == '-') {
+ if (strcmp(argv[arg], "--") == 0) {
+ arg++;
+ break;
+ } else if (strcmp(argv[arg], "-f") == 0) {
+ full = 1;
+ } else if (strcmp(argv[arg], "-o") == 0) {
+ arg++;
+ if (arg == argc) {
+ goto Usage;
+ }
+ outfile = argv[arg];
+ }
+ arg++;
+ }
+ if (arg == argc) {
+ goto Usage;
+ }
+
+ if (outfile) {
+ fout = fopen(outfile, "w+");
+ if (fout == NULL) {
+ fprintf(stderr, "Unable to open \'%s\' for writing:\n",
+ argv[arg]);
+ perror("");
+ exit(1);
+ }
+ } else {
+ fout = stdout;
+ }
+
+ if (! full) {
+ char *dllname = argv[arg];
+ arg++;
+ if (arg == argc) {
+ goto Usage;
+ }
+ fprintf(fout, "LIBRARY %s\n", dllname);
+ fprintf(fout, "EXETYPE WINDOWS\n");
+ fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
+ fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
+ fprintf(fout, "EXPORTS\n");
+ }
+
+ for (; arg < argc; arg++) {
+ if (argv[arg][0] == '@') {
+ FILE *fargs = fopen(&argv[arg][1], "r");
+ if (fargs == NULL) {
+ fprintf(stderr, "Unable to open \'%s\' for reading:\n",
+ argv[arg]);
+ perror("");
+ exit(1);
+ }
+ pos = 0;
+ for (i = 0; i < arg; i++) {
+ strcpy(&cmdline[pos], argv[i]);
+ pos += strlen(&cmdline[pos]) + 1;
+ fargv[i] = argv[i];
+ }
+ fgets(&cmdline[pos], sizeof(cmdline), fargs);
+ fprintf(stderr, "%s\n", &cmdline[pos]);
+ fclose(fargs);
+ i += GetArgcArgv(&cmdline[pos], &fargv[i]);
+ argc = i;
+ argv = fargv;
+ }
+ DumpFile(argv[arg], fout, full);
+ }
+ exit(0);
+}