aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcvs2svn <cvs2svn@FreeBSD.org>1994-11-21 07:33:22 +0000
committercvs2svn <cvs2svn@FreeBSD.org>1994-11-21 07:33:22 +0000
commit01233029edba45b14c75afe36248d0df998b3cc3 (patch)
treee3246a9664c2bcea9329b550600f6612589b3cd0
parentc264e2c65c3f4fe911fa70df828625a6b19c6d84 (diff)
downloadsrc-01233029edba45b14c75afe36248d0df998b3cc3.tar.gz
src-01233029edba45b14c75afe36248d0df998b3cc3.zip
This commit was manufactured by cvs2svn to create branch 'BETA_2_0'.
Notes
Notes: svn path=/releng/BETA_2_0/; revision=4743
-rw-r--r--Makefile16
-rw-r--r--bin/ps/fmt.c5
-rw-r--r--etc/Makefile69
-rw-r--r--etc/etc.i386/MAKEDEV14
-rw-r--r--etc/inetd.conf2
-rw-r--r--etc/make.conf4
-rw-r--r--etc/rc4
-rw-r--r--games/fortune/Makefile2
-rw-r--r--gnu/gnu2bmake/gcc-2.6.1.patch577
-rwxr-xr-xgnu/gnu2bmake/gcc-2.6.1.tcl78
-rw-r--r--gnu/gnu2bmake/gnu2bmake.tcl6
-rw-r--r--gnu/include/values.h4
-rw-r--r--gnu/lib/libdialog/checklist.c35
-rw-r--r--gnu/lib/libdialog/dialog.h9
-rw-r--r--gnu/lib/libdialog/inputbox.c18
-rw-r--r--gnu/lib/libdialog/kernel.c81
-rw-r--r--gnu/lib/libdialog/lineedit.c127
-rw-r--r--gnu/lib/libdialog/menubox.c35
-rw-r--r--gnu/lib/libdialog/msgbox.c14
-rw-r--r--gnu/lib/libdialog/prgbox.c11
-rw-r--r--gnu/lib/libdialog/radiolist.c37
-rw-r--r--gnu/lib/libdialog/textbox.c13
-rw-r--r--gnu/lib/libdialog/yesno.c14
-rw-r--r--gnu/lib/libg++/Makefile15
-rw-r--r--gnu/lib/libg++/include/ACG.h12
-rw-r--r--gnu/lib/libg++/include/Complex.h27
-rw-r--r--gnu/lib/libg++/include/CursesW.h7
-rw-r--r--gnu/lib/libg++/include/DLList.h25
-rw-r--r--gnu/lib/libg++/include/Fix16.h58
-rw-r--r--gnu/lib/libg++/include/Fix24.h42
-rw-r--r--gnu/lib/libg++/include/MLCG.h2
-rw-r--r--gnu/lib/libg++/include/RNG.h2
-rw-r--r--gnu/lib/libg++/include/SLList.h21
-rw-r--r--gnu/lib/libg++/include/String.h144
-rw-r--r--gnu/lib/libg++/include/_G_config.h20
-rw-r--r--gnu/lib/libg++/include/bitprims.h2
-rw-r--r--gnu/lib/libg++/include/builtin.h15
-rw-r--r--gnu/lib/libg++/include/defines.h2
-rw-r--r--gnu/lib/libg++/include/iolibio.h10
-rw-r--r--gnu/lib/libg++/include/iomanip.h2
-rw-r--r--gnu/lib/libg++/include/iostream.h22
-rw-r--r--gnu/lib/libg++/include/libiberty.h7
-rw-r--r--gnu/lib/libg++/include/libio.h5
-rw-r--r--gnu/lib/libg++/include/libioP.h26
-rw-r--r--gnu/lib/libg++/include/regex.h272
-rw-r--r--gnu/lib/libg++/include/rx.h3255
-rw-r--r--gnu/lib/libg++/include/streambuf.h5
-rw-r--r--gnu/lib/libg++/libg++/ACG.cc27
-rw-r--r--gnu/lib/libg++/libg++/DLList.cc8
-rw-r--r--gnu/lib/libg++/libg++/Fix.cc6
-rw-r--r--gnu/lib/libg++/libg++/Fix16.cc48
-rw-r--r--gnu/lib/libg++/libg++/Fix24.cc76
-rw-r--r--gnu/lib/libg++/libg++/MLCG.cc2
-rw-r--r--gnu/lib/libg++/libg++/Regex.cc11
-rw-r--r--gnu/lib/libg++/libg++/SLList.cc6
-rw-r--r--gnu/lib/libg++/libg++/String.cc57
-rw-r--r--gnu/lib/libg++/libg++/error.cc2
-rw-r--r--gnu/lib/libg++/libg++/except.c79
-rw-r--r--gnu/lib/libg++/libg++/regex.cc2757
-rw-r--r--gnu/lib/libg++/libg++/timer.c1
-rw-r--r--gnu/lib/libg++/libio/fileops.c32
-rw-r--r--gnu/lib/libg++/libio/floatconv.c72
-rw-r--r--gnu/lib/libg++/libio/ioassign.cc55
-rw-r--r--gnu/lib/libg++/libio/iofclose.c4
-rw-r--r--gnu/lib/libg++/libio/iofgetpos.c2
-rw-r--r--gnu/lib/libg++/libio/iofread.c2
-rw-r--r--gnu/lib/libg++/libio/iofscanf.c2
-rw-r--r--gnu/lib/libg++/libio/iofsetpos.c2
-rw-r--r--gnu/lib/libg++/libio/iogetdelim.c102
-rw-r--r--gnu/lib/libg++/libio/iostream.cc17
-rw-r--r--gnu/lib/libg++/libio/ioungetc.c2
-rw-r--r--gnu/lib/libg++/libio/iovfprintf.c14
-rw-r--r--gnu/lib/libg++/libio/iovfscanf.c4
-rw-r--r--gnu/lib/libg++/libio/stdiostream.cc13
-rw-r--r--gnu/lib/libg++/libio/strstream.cc2
-rw-r--r--gnu/lib/libg++/librx/rx.c7159
-rw-r--r--gnu/usr.bin/cc/Makefile2
-rw-r--r--gnu/usr.bin/cc/Makefile.inc6
-rw-r--r--gnu/usr.bin/cc/c++/Makefile2
-rw-r--r--gnu/usr.bin/cc/cc/Makefile10
-rw-r--r--gnu/usr.bin/cc/cc/gcc.c4
-rw-r--r--gnu/usr.bin/cc/cc1/c-decl.c9
-rw-r--r--gnu/usr.bin/cc/cc_int/Makefile4
-rw-r--r--gnu/usr.bin/cc/cc_int/aux-output.c4
-rw-r--r--gnu/usr.bin/cc/cc_int/bc-emit.c2
-rw-r--r--gnu/usr.bin/cc/cc_int/c-common.c43
-rw-r--r--gnu/usr.bin/cc/cc_int/calls.c5
-rw-r--r--gnu/usr.bin/cc/cc_int/combine.c9
-rw-r--r--gnu/usr.bin/cc/cc_int/expmed.c6
-rw-r--r--gnu/usr.bin/cc/cc_int/function.c17
-rw-r--r--gnu/usr.bin/cc/cc_int/real.c8
-rw-r--r--gnu/usr.bin/cc/cc_int/reg-stack.c17
-rw-r--r--gnu/usr.bin/cc/cc_int/reload1.c8
-rw-r--r--gnu/usr.bin/cc/cc_int/version.c2
-rw-r--r--gnu/usr.bin/cc/cpp/Makefile5
-rw-r--r--gnu/usr.bin/cc/cpp/cccp.c52
-rw-r--r--gnu/usr.bin/cc/include/bc-arity.h42
-rw-r--r--gnu/usr.bin/cc/include/i386/bsd.h3
-rw-r--r--gnu/usr.bin/cc/include/obstack.h7
-rw-r--r--gnu/usr.bin/cc/libgcc/Makefile2
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/checklist4
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/infobox2
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/inputbox4
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/menubox2
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/msgbox6
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/radiolist4
-rw-r--r--gnu/usr.bin/gdb/gdb/terminal.h2
-rw-r--r--gnu/usr.bin/man/catman/Makefile27
-rw-r--r--gnu/usr.bin/man/makewhatis/Makefile19
-rw-r--r--gnu/usr.bin/perl/lib/timelocal.pl1
-rw-r--r--gnu/usr.bin/send-pr/send-pr.sh2
-rw-r--r--include/Makefile4
-rw-r--r--include/malloc.h5
-rw-r--r--lib/Makefile6
-rw-r--r--lib/libc/gen/Makefile.inc11
-rw-r--r--lib/libc/gen/config.c187
-rw-r--r--lib/libc/gen/config_open.373
-rw-r--r--lib/libc/sys/Makefile.inc2
-rw-r--r--lib/libcrypt/Makefile30
-rw-r--r--lib/libforms/Makefile13
-rw-r--r--lib/libforms/examples/Makefile7
-rw-r--r--lib/libforms/examples/example.frm6
-rw-r--r--lib/libforms/examples/tform.c18
-rw-r--r--lib/libforms/forms.c341
-rw-r--r--lib/libforms/forms.h84
-rw-r--r--lib/libforms/lex.l19
-rw-r--r--lib/libforms/yacc.y149
-rw-r--r--lib/libmytinfo/Makefile9
-rw-r--r--lib/libncurses/curses.priv.h1
-rw-r--r--lib/libncurses/lib_kernel.c42
-rw-r--r--lib/libncurses/ncurses.h2
-rw-r--r--lib/libtermcap/Makefile4
-rw-r--r--lib/libtermcap/termcap.c1
-rw-r--r--lib/msun/src/w_cabs.c7
-rw-r--r--libexec/lfs_cleanerd/Makefile2
-rw-r--r--libexec/rpc.rstatd/rstatd.c3
-rw-r--r--libexec/rpc.rusersd/rusers_proc.c6
-rw-r--r--libexec/rpc.rusersd/rusersd.c3
-rw-r--r--libexec/rpc.rwalld/rwalld.c3
-rw-r--r--release/Makefile102
-rwxr-xr-xrelease/adduser.sh183
-rwxr-xr-xrelease/bininst529
-rw-r--r--release/boot_flp.conf7
-rw-r--r--release/cpio_flp_1.conf17
-rw-r--r--release/extract.sh44
-rw-r--r--release/instdist.sh505
-rw-r--r--release/miscfuncs.sh112
-rw-r--r--release/mkchecksums.sh22
-rw-r--r--release/mkxf86extract.sh60
-rw-r--r--release/netinst.sh177
-rw-r--r--sbin/dumplfs/Makefile2
-rw-r--r--sbin/ipfw/Makefile4
-rw-r--r--sbin/ipfw/ipfirewall.4206
-rw-r--r--sbin/ipfw/ipfw.1527
-rw-r--r--sbin/ipfw/ipfw.8128
-rw-r--r--sbin/ipfw/ipfw.c1630
-rw-r--r--sbin/mount_null/Makefile2
-rw-r--r--sbin/mount_portal/Makefile2
-rw-r--r--sbin/mount_umap/Makefile2
-rw-r--r--sbin/mount_union/Makefile2
-rw-r--r--sbin/newlfs/Makefile4
-rw-r--r--sbin/newlfs/lfs.c2
-rw-r--r--sbin/slattach/slattach.c7
-rw-r--r--sbin/sysinstall/Makefile2
-rw-r--r--sbin/sysinstall/bootarea.c16
-rw-r--r--sbin/sysinstall/disk.h98
-rw-r--r--sbin/sysinstall/editor.c118
-rw-r--r--sbin/sysinstall/editor.h27
-rw-r--r--sbin/sysinstall/exec.c10
-rw-r--r--sbin/sysinstall/label.c550
-rw-r--r--sbin/sysinstall/label.h52
-rw-r--r--sbin/sysinstall/main.c25
-rw-r--r--sbin/sysinstall/mbr.c415
-rw-r--r--sbin/sysinstall/ourcurses.c159
-rw-r--r--sbin/sysinstall/stage0.c54
-rw-r--r--sbin/sysinstall/stage1.c407
-rw-r--r--sbin/sysinstall/stage2.c50
-rw-r--r--sbin/sysinstall/stage3.c8
-rw-r--r--sbin/sysinstall/stage4.c19
-rw-r--r--sbin/sysinstall/stage5.c17
-rw-r--r--sbin/sysinstall/sysinstall.c835
-rw-r--r--sbin/sysinstall/sysinstall.h28
-rw-r--r--sbin/sysinstall/utils.c67
-rw-r--r--secure/Makefile9
-rw-r--r--secure/Makefile.inc4
-rw-r--r--secure/bin/Makefile6
-rw-r--r--secure/bin/Makefile.inc5
-rw-r--r--secure/bin/ed/Makefile13
-rw-r--r--secure/lib/Makefile.inc9
-rw-r--r--secure/sbin/Makefile6
-rw-r--r--secure/sbin/Makefile.inc6
-rw-r--r--secure/sbin/init/Makefile12
-rw-r--r--secure/usr.bin/Makefile.inc3
-rw-r--r--secure/usr.bin/bdes/Makefile6
-rw-r--r--share/FAQ/CONTRIB.FreeBSD195
-rw-r--r--share/FAQ/DISKSPACE.FAQ16
-rw-r--r--share/FAQ/Diskless.FAQ130
-rw-r--r--share/FAQ/FreeBSD.FAQ18
-rw-r--r--share/FAQ/README-2.0 (renamed from README)31
-rw-r--r--share/FAQ/REGISTER.FreeBSD86
-rw-r--r--share/FAQ/RELNOTES.FreeBSD128
-rw-r--r--share/FAQ/TROUBLESHOOTING102
-rw-r--r--share/man/man4/lkm.44
-rw-r--r--share/mk/bsd.doc.mk8
-rw-r--r--share/mk/bsd.kmod.mk8
-rw-r--r--share/mk/bsd.lib.mk19
-rw-r--r--share/mk/bsd.port.mk89
-rw-r--r--share/mk/bsd.port.subdir.mk6
-rw-r--r--share/mk/bsd.prog.mk58
-rw-r--r--share/mk/bsd.subdir.mk12
-rw-r--r--share/syscons/keymaps/Makefile2
-rw-r--r--share/syscons/keymaps/danish.cp865.kbd2
-rw-r--r--share/syscons/keymaps/danish.iso.kbd2
-rw-r--r--share/syscons/keymaps/ru.koi8-r.kbd4
-rw-r--r--share/syscons/keymaps/ru.koi8-r.shift.kbd237
-rw-r--r--share/syscons/keymaps/us.iso.kbd2
-rw-r--r--sys/gnu/misc/aic7770/COPYING339
-rw-r--r--sys/gnu/misc/aic7770/COPYRIGHT16
-rw-r--r--sys/gnu/misc/aic7770/README94
-rw-r--r--sys/gnu/misc/aic7770/README-FIRST19
-rw-r--r--sys/gnu/misc/aic7770/aic7770.154
-rw-r--r--sys/gnu/misc/aic7770/aic7770.c584
-rw-r--r--sys/gnu/misc/aic7770/aic7770.seq1064
-rw-r--r--sys/gnu/misc/aic7770/aic7770_seq.h353
-rw-r--r--sys/gnu/misc/aic7xxx/COPYING339
-rw-r--r--sys/gnu/misc/aic7xxx/COPYRIGHT16
-rw-r--r--sys/gnu/misc/aic7xxx/README94
-rw-r--r--sys/gnu/misc/aic7xxx/README-FIRST19
-rw-r--r--sys/gnu/misc/aic7xxx/aic7770_seq.h353
-rw-r--r--sys/gnu/misc/aic7xxx/aic7xxx.154
-rw-r--r--sys/gnu/misc/aic7xxx/aic7xxx.c584
-rw-r--r--sys/gnu/misc/aic7xxx/aic7xxx.seq1064
-rw-r--r--sys/i386/apm/apm.c8
-rw-r--r--sys/i386/boot/biosboot/bios.S20
-rw-r--r--sys/i386/boot/biosboot/boot.c17
-rw-r--r--sys/i386/boot/netboot/Makefile8
-rw-r--r--sys/i386/boot/netboot/bootmenu.c118
-rw-r--r--sys/i386/boot/netboot/ether.c172
-rw-r--r--sys/i386/boot/netboot/ether.h79
-rw-r--r--sys/i386/boot/netboot/main.c30
-rw-r--r--sys/i386/boot/netboot/misc.c22
-rw-r--r--sys/i386/boot/netboot/netboot.h2
-rw-r--r--sys/i386/conf/GENERIC11
-rw-r--r--sys/i386/conf/GENERICAH3
-rw-r--r--sys/i386/conf/GENERICBT3
-rw-r--r--sys/i386/conf/IPFIREWALL3
-rw-r--r--sys/i386/conf/LINT4
-rw-r--r--sys/i386/conf/Makefile.i3866
-rw-r--r--sys/i386/conf/files.i3863
-rw-r--r--sys/i386/i386/autoconf.c31
-rw-r--r--sys/i386/i386/genassym.c3
-rw-r--r--sys/i386/i386/locore.s15
-rw-r--r--sys/i386/i386/userconfig.c291
-rw-r--r--sys/i386/include/bootinfo.h8
-rw-r--r--sys/i386/include/pmap.h25
-rw-r--r--sys/i386/include/soundcard.h15
-rw-r--r--sys/i386/isa/README.le4
-rw-r--r--sys/i386/isa/aha1742.c20
-rw-r--r--sys/i386/isa/aic6360.c44
-rw-r--r--sys/i386/isa/aic7770.c1731
-rw-r--r--sys/i386/isa/clock.c5
-rw-r--r--sys/i386/isa/fd.c6
-rw-r--r--sys/i386/isa/ft.c4
-rw-r--r--sys/i386/isa/if_ed.c45
-rw-r--r--sys/i386/isa/if_ep.c2125
-rw-r--r--sys/i386/isa/if_epreg.h299
-rw-r--r--sys/i386/isa/isa.h19
-rw-r--r--sys/i386/isa/kbdtables.h57
-rw-r--r--sys/i386/isa/lpt.c7
-rw-r--r--sys/i386/isa/mcd.c87
-rw-r--r--sys/i386/isa/mcdreg.h75
-rw-r--r--sys/i386/isa/readMBR.c3
-rw-r--r--sys/i386/isa/syscons.c29
-rw-r--r--sys/i386/isa/wd.c38
-rw-r--r--sys/i386/pci/if_de.c54
-rw-r--r--sys/i386/scsi/aic7xxx.c1731
-rw-r--r--sys/isofs/cd9660/cd9660_vfsops.c3
-rw-r--r--sys/kern/init_sysent.c9
-rw-r--r--sys/kern/kern_sysctl.c15
-rw-r--r--sys/kern/vfs_conf.c13
-rw-r--r--sys/miscfs/kernfs/kernfs_vnops.c17
-rw-r--r--sys/miscfs/specfs/spec_vnops.c3
-rw-r--r--sys/net/if.c4
-rw-r--r--sys/net/if.h14
-rw-r--r--sys/net/if_arp.h8
-rw-r--r--sys/net/radix.h11
-rw-r--r--sys/netinet/ip_fw.c678
-rw-r--r--sys/netinet/ip_fw.h45
-rw-r--r--sys/netinet/ip_input.c21
-rw-r--r--sys/netinet/ip_output.c18
-rw-r--r--sys/netinet/raw_ip.c19
-rw-r--r--sys/netiso/clnp_er.c5
-rw-r--r--sys/netiso/clnp_input.c5
-rw-r--r--sys/netiso/clnp_output.c5
-rw-r--r--sys/netiso/clnp_timer.c5
-rw-r--r--sys/netiso/cltp_usrreq.c3
-rw-r--r--sys/netiso/tp_cons.c5
-rw-r--r--sys/netiso/tp_inet.c5
-rw-r--r--sys/netiso/tp_pcb.c7
-rw-r--r--sys/netns/idp_usrreq.c3
-rw-r--r--sys/netns/ns.c3
-rw-r--r--sys/pci/if_de.c54
-rw-r--r--sys/scsi/cd.c7
-rw-r--r--sys/scsi/scsi_base.c8
-rw-r--r--sys/scsi/scsiconf.c16
-rw-r--r--sys/scsi/scsiconf.h4
-rw-r--r--sys/scsi/sd.c8
-rw-r--r--sys/sys/disklabel.h4
-rw-r--r--sys/sys/mbuf.h11
-rw-r--r--sys/sys/proc.h15
-rw-r--r--sys/sys/resourcevar.h14
-rw-r--r--sys/sys/syscall-hide.h2
-rw-r--r--sys/sys/sysctl.h16
-rw-r--r--sys/sys/vnode.h3
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c3
-rw-r--r--sys/ufs/lfs/lfs.h4
-rw-r--r--sys/ufs/lfs/lfs_segment.c104
-rw-r--r--sys/ufs/lfs/lfs_subr.c10
-rw-r--r--sys/ufs/lfs/lfs_syscalls.c7
-rw-r--r--sys/ufs/lfs/lfs_vfsops.c4
-rw-r--r--sys/ufs/ufs/ufs_extern.h9
-rw-r--r--sys/vm/swap_pager.c81
-rw-r--r--sys/vm/vm_fault.c28
-rw-r--r--sys/vm/vm_glue.c16
-rw-r--r--sys/vm/vm_page.h13
-rw-r--r--sys/vm/vm_pageout.c9
-rw-r--r--sys/vm/vnode_pager.c13
-rw-r--r--usr.bin/Makefile14
-rw-r--r--usr.bin/chat/Example5
-rw-r--r--usr.bin/chat/Makefile8
-rw-r--r--usr.bin/chat/README169
-rw-r--r--usr.bin/chat/chat.8251
-rw-r--r--usr.bin/chat/chat.c1166
-rwxr-xr-xusr.bin/chat/connect-ppp129
-rw-r--r--usr.bin/chat/fix-cua16
-rwxr-xr-xusr.bin/chat/ppp-off5
-rwxr-xr-xusr.bin/chat/ppp-on37
-rwxr-xr-xusr.bin/chat/unlock23
-rw-r--r--usr.bin/chpass/Makefile2
-rw-r--r--usr.bin/dig/dig.112
-rw-r--r--usr.bin/getopt/Makefile7
-rw-r--r--usr.bin/getopt/README57
-rw-r--r--usr.bin/getopt/getopt.1103
-rw-r--r--usr.bin/getopt/getopt.c30
-rw-r--r--usr.bin/ipcs/ipcs.14
-rw-r--r--usr.bin/kdump/Makefile2
-rw-r--r--usr.bin/kdump/kdump.c2
-rw-r--r--usr.bin/rup/rup.14
-rw-r--r--usr.bin/su/su.c6
-rw-r--r--usr.bin/systat/Makefile2
-rw-r--r--usr.bin/tn3270/Makefile2
-rw-r--r--usr.bin/vmstat/Makefile2
-rw-r--r--usr.sbin/Makefile17
-rw-r--r--usr.sbin/ac/ac.c4
-rw-r--r--usr.sbin/cdplay/Makefile5
-rw-r--r--usr.sbin/cdplay/cdplay.c273
-rw-r--r--usr.sbin/config/config.h3
-rw-r--r--usr.sbin/config/main.c26
-rw-r--r--usr.sbin/config/mkmakefile.c67
-rw-r--r--usr.sbin/iostat/iostat.82
-rw-r--r--usr.sbin/iostat/iostat.c2
-rw-r--r--usr.sbin/named/named.816
-rw-r--r--usr.sbin/named/tools/named.reload/named.reload.88
-rw-r--r--usr.sbin/named/tools/named.restart/named.restart.86
-rw-r--r--usr.sbin/named/xfer/Makefile2
-rw-r--r--usr.sbin/named/xfer/named-xfer.812
-rw-r--r--usr.sbin/ncrcontrol/Makefile2
-rw-r--r--usr.sbin/nslookup/nslookup.86
-rw-r--r--usr.sbin/pkg_install/add/perform.c5
-rw-r--r--usr.sbin/pkg_install/create/perform.c4
-rw-r--r--usr.sbin/pkg_install/create/pl.c18
-rw-r--r--usr.sbin/pkg_install/lib/lib.h3
-rw-r--r--usr.sbin/pkg_install/lib/str.c13
-rw-r--r--usr.sbin/pppd/Makefile14
-rw-r--r--usr.sbin/pppstats/Makefile12
-rw-r--r--usr.sbin/pppstats/pppstats.8131
-rw-r--r--usr.sbin/pppstats/pppstats.c407
-rw-r--r--usr.sbin/slstat/slstat.c18
-rw-r--r--usr.sbin/swapinfo/swapinfo.c20
-rw-r--r--usr.sbin/tcpdump/tcpdump/Makefile2
-rw-r--r--usr.sbin/tcpdump/tcpslice/Makefile2
-rwxr-xr-xusr.sbin/xntpd/scripts/monitoring/timelocal.pl1
-rw-r--r--usr.sbin/xntpd/util/tickadj.c4
383 files changed, 32394 insertions, 10070 deletions
diff --git a/Makefile b/Makefile
index 9bc06e6f6de0..0a5082dc640e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
#
-# $Id: Makefile,v 1.28 1994/11/01 19:52:38 pst Exp $
+# $Id: Makefile,v 1.29 1994/11/08 00:55:08 ache Exp $
#
# Make command line options:
# -DCLOBBER will remove /usr/include and MOST of /usr/lib
@@ -23,16 +23,17 @@
# Put initial settings here.
SUBDIR=
+# Must be first for "distribute" to work
+.if exists(release)
+SUBDIR+= release
+.endif
+
.if exists(bin)
SUBDIR+= bin
.endif
.if exists(contrib)
SUBDIR+= contrib
.endif
-.if exists(etc)
-# XXX until etc vs release conversion is done
-# SUBDIR+= etc
-.endif
.if exists(games)
SUBDIR+= games
.endif
@@ -76,6 +77,11 @@ SUBDIR+= secure
SUBDIR+= lkm
.endif
+# etc must be last for "distribute" to work
+.if exists(etc) && make(distribute)
+SUBDIR+= etc
+.endif
+
# These are last, since it is nice to at least get the base system
# rebuilt before you do them.
.if defined(MAKE_LOCAL) & exists(local) & exists(local/Makefile)
diff --git a/bin/ps/fmt.c b/bin/ps/fmt.c
index 59b99190dbf5..43d2c29215c8 100644
--- a/bin/ps/fmt.c
+++ b/bin/ps/fmt.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: fmt.c,v 1.3 1994/09/24 02:56:43 davidg Exp $
*/
#ifndef lint
@@ -38,6 +38,7 @@ static char sccsid[] = "@(#)fmt.c 8.4 (Berkeley) 4/15/94";
#endif /* not lint */
#include <sys/param.h>
+#include <sys/syslimits.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <ctype.h>
@@ -59,7 +60,7 @@ shquote(argv)
char **argv;
{
char **p, *dst, *src;
- static char buf[4096]; /* XXX */
+ static char buf[ARG_MAX]; /* XXX */
if (*argv == 0) {
buf[0] = 0;
diff --git a/etc/Makefile b/etc/Makefile
index 71699cb89e54..f462adb77dac 100644
--- a/etc/Makefile
+++ b/etc/Makefile
@@ -1,5 +1,5 @@
# from: @(#)Makefile 5.11 (Berkeley) 5/21/91
-# $Id: Makefile,v 1.90 1994/10/22 02:11:08 phk Exp $
+# $Id: Makefile,v 1.92 1994/11/14 20:56:10 phk Exp $
# disktab may be wrong -- hcx9 is a tahoe, but gets its own.
# -rw-r--r--
@@ -7,7 +7,7 @@ BINOWN= root
BINGRP= wheel
BIN1= aliases csh.cshrc csh.login csh.logout dm.conf \
ftpusers gettytab group hosts host.conf hosts.equiv hosts.lpd \
- inetd.conf login.access motd myname netstart \
+ inetd.conf login.access motd netstart \
networks phones printcap profile protocols rc rc.local remote \
security services shells \
syslog.conf ttys etc.${MACHINE}/disktab rpc make.conf \
@@ -123,7 +123,7 @@ DESCRYPT_LIB= secure/lib/libcrypt
CRYPT_SRCS= bin/ed bin/rcp
CRYPT_SRCS+= sbin/init
.if !defined(NOCRYPT)
-CRYPT_SRCS+= secure/usr.bin/bdes
+CRYPT_SRCS+= secure
.endif
CRYPT_DIRS= bin sbin usr usr/bin usr/lib
@@ -146,9 +146,11 @@ descrypt:
cd ${.CURDIR}/../$$i; \
${MAKE} cleandir obj depend all; \
done
+
+distribute:
+ cd ${.CURDIR} ; ${MAKE} distribution DESTDIR=${RELEASEDIR}/bindist
-
-distribution: distrib-dirs
+distribution:
(cd ${.CURDIR}; \
install -c -o ${BINOWN} -g ${BINGRP} -m 644 ${BIN1} ${DESTDIR}/etc; \
install -c -o ${BINOWN} -g ${BINGRP} -m 666 ${BIN2} ${DESTDIR}/etc; \
@@ -198,14 +200,9 @@ distribution: distrib-dirs
${DESTDIR}/var/crash
(cd ${.CURDIR}/etc.${MACHINE}; install -c -o ${BINOWN} -g ${BINGRP} \
-m 444 fstab.* ${DESTDIR}/etc)
-.if defined(NOCRYPT)
- (cd ${.CURDIR}; ${MAKE} scrypt)
- (cd ${.CURDIR}/..; ${MAKE} install)
-.else
- (cd ${.CURDIR}; ${MAKE} descrypt)
- (cd ${.CURDIR}/..; ${MAKE} install)
-.endif
(cd ${.CURDIR}/../usr.sbin/sendmail/src; \
+ ${MAKE} obj; \
+ ${MAKE} all; \
${MAKE} install; \
cd ../cf/cf; \
${MAKE} obj; \
@@ -215,14 +212,6 @@ distribution: distrib-dirs
(cd ${.CURDIR}/..; \
install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${FREEBSD} ${DESTDIR}/)
(cd ${.CURDIR}/../share/man; ${MAKE} makedb; )
-.if ${MACHINE} == "tahoe"
- (cd ${.CURDIR}/etc.tahoe; install -c -o ${BINOWN} -g ${BINGRP} \
- -m 444 ${WCS1} ${DESTDIR}/)
-.endif
-.if ${MACHINE} == "vax"
- (cd ${.CURDIR}/etc.vax; install -c -o ${BINOWN} -g ${BINGRP} \
- -m 444 ${PCS} ${DESTDIR}/)
-.endif
crunch:
crunchgen ${.CURDIR}/../usr.sbin/crunch/examples/kcopy.conf
@@ -408,8 +397,8 @@ bin-tarball:
${ZIPNSPLIT} ${RELEASEDIR}/tarballs/bindist/bin_tgz.)
src-clean:
+ #(cd ${DESTDIR}/usr/src; make cleandist)
find ${DESTDIR}/usr/src -name obj | xargs -n30 rm -rf
- (cd ${DESTDIR}/usr/src; make cleandist)
rm -rf ${DESTDIR}/usr/src/sys/compile/*
chown -R bin:bin ${DESTDIR}/usr/src
chmod -R og-w ${DESTDIR}/usr/src
@@ -446,25 +435,40 @@ srcinclude-tarball:
srclib-tarball:
(cd ${DESTDIR}; \
- tar --exclude usr/src/${CRYPT_LIB} --exclude CVS -cf - \
+ tar --exclude CVS -cf - \
usr/src/lib | \
${ZIPNSPLIT} ${RELEASEDIR}/tarballs/srcdist/lib.)
-srclibcrypt-tarball:
- (cd ${DESTDIR}; \
- tar --exclude CVS -cf - usr/src/${CRYPT_LIB} | \
- ${ZIPNSPLIT} ${RELEASEDIR}/tarballs/secrdist/libcrypt.)
-
srclibexec-tarball:
(cd ${DESTDIR}; \
tar --exclude CVS -cf - usr/src/libexec | \
${ZIPNSPLIT} ${RELEASEDIR}/tarballs/srcdist/libexec.)
+srcrelease-tarball:
+ (cd ${DESTDIR}; \
+ tar --exclude CVS -cf - usr/src/release | \
+ ${ZIPNSPLIT} ${RELEASEDIR}/tarballs/srcdist/release.)
+
srcsbin-tarball:
(cd ${DESTDIR}; \
tar --exclude CVS -cf - usr/src/sbin | \
${ZIPNSPLIT} ${RELEASEDIR}/tarballs/srcdist/sbin.)
+srcsecure-tarball:
+ (cd ${DESTDIR}; \
+ tar --exclude CVS -cf - usr/src/secure | \
+ ${ZIPNSPLIT} ${RELEASEDIR}/tarballs/secrdist/secure.)
+
+srcebones-tarball:
+ (cd ${DESTDIR}; \
+ tar --exclude CVS -cf - usr/src/eBones | \
+ ${ZIPNSPLIT} ${RELEASEDIR}/tarballs/secrdist/ebones.)
+
+srckerberos-tarball:
+ (cd ${DESTDIR}; \
+ tar --exclude CVS -cf - usr/src/kerberosIV | \
+ ${ZIPNSPLIT} ${RELEASEDIR}/tarballs/secrdist/kerberos.)
+
srcshare-tarball:
(cd ${DESTDIR}; \
tar --exclude CVS -cf - usr/src/share | \
@@ -472,7 +476,7 @@ srcshare-tarball:
srcsys-tarball:
(cd ${DESTDIR}; \
- tar --exclude CVS -cf - usr/src/sys | \
+ tar --exclude CVS -cf - usr/src/sys usr/src/lkm | \
${ZIPNSPLIT} ${RELEASEDIR}/tarballs/srcdist/sys.)
srcusrbin-tarball:
@@ -487,8 +491,9 @@ srcusrsbin-tarball:
src-tarball: src-clean srcbase-tarball srcbin-tarball \
srcetc-tarball srcgames-tarball srcgnu-tarball srcinclude-tarball \
- srclib-tarball srclibcrypt-tarball srclibexec-tarball srcsbin-tarball \
- srcshare-tarball srcsys-tarball srcusrbin-tarball srcusrsbin-tarball
+ srclib-tarball srcsecure-tarball srclibexec-tarball srcsbin-tarball \
+ srcshare-tarball srcsys-tarball srcusrbin-tarball srcusrsbin-tarball \
+ srcrelease-tarball srcebones-tarball srckerberos-tarball
des-tarball:
rm -rf ${RELEASEDIR}/tmpdes
@@ -502,7 +507,8 @@ des-tarball:
# This is ugly, it force installs a /usr/lib/libcrypt.a so
# that the other makes will be built with des.
#
- (cd ${.CURDIR}/../${CRYPT_LIB}; \
+ (set -x ; cd ${.CURDIR}/../${DESCRYPT_LIB}; \
+ NOCRYPT=; \
unset NOCRYPT; \
DESTDIR=; export DESTDIR; \
${MAKE} cleandir obj depend all install; \
@@ -510,6 +516,7 @@ des-tarball:
DESTDIR=${RELEASEDIR}/tmpdes; export DESTDIR; \
${MAKE} cleandir obj depend all install)
for i in ${CRYPT_SRCS}; do \
+ NOCRYPT=; \
unset NOCRYPT; \
DESTDIR=${RELEASEDIR}/tmpdes; export DESTDIR; \
NOMAN=noman; export NOMAN; \
diff --git a/etc/etc.i386/MAKEDEV b/etc/etc.i386/MAKEDEV
index 6bdf2fe74a8b..cedafb76a81c 100644
--- a/etc/etc.i386/MAKEDEV
+++ b/etc/etc.i386/MAKEDEV
@@ -71,7 +71,7 @@
# socksys iBCS2 socket system driver
# vat VAT compatibility audio driver (requires snd*)
#
-# $Id: MAKEDEV,v 1.46 1994/11/01 01:47:08 pst Exp $
+# $Id: MAKEDEV,v 1.48 1994/11/10 02:32:29 phk Exp $
#
PATH=/sbin:/bin/:/usr/bin:/usr/sbin:
@@ -395,9 +395,9 @@ cd*|mcd*)
case $unit in
0|1|2|3|4|5|6)
mknod ${name}${unit}a b $blk `expr $unit '*' 8 + 0`
- mknod ${name}${unit}d b $blk `expr $unit '*' 8 + 3`
+ mknod ${name}${unit}c b $blk `expr $unit '*' 8 + 2`
mknod r${name}${unit}a c $chr `expr $unit '*' 8 + 0`
- mknod r${name}${unit}d c $chr `expr $unit '*' 8 + 3`
+ mknod r${name}${unit}c c $chr `expr $unit '*' 8 + 2`
chgrp operator ${name}${unit}[a-h] r${name}${unit}[a-h]
chmod 640 ${name}${unit}[a-h] r${name}${unit}[a-h]
;;
@@ -595,10 +595,10 @@ vat)
;;
apm)
- rm -f apm
- mknod apm c 39 0
- chown root.wheel apm
- chmod 660 apm
+ rm -f apm0
+ mknod apm0 c 39 0
+ chown root.wheel apm0
+ chmod 660 apm0
;;
local)
diff --git a/etc/inetd.conf b/etc/inetd.conf
index 513e1e83ab27..c72dfe4ecb51 100644
--- a/etc/inetd.conf
+++ b/etc/inetd.conf
@@ -42,5 +42,5 @@ kshell stream tcp nowait root /usr/libexec/rshd rshd -k
#pcnfsd/1-2 dgram rpc/udp wait root /usr/libexec/rpc.pcnfsd rpc.pcnfsd
#
# example entry for the pop3 server
-#pop3 stream tcp nowait root /usr/local/etc/popper popper
+#pop3 stream tcp nowait root /usr/local/libexec/popper popper
#
diff --git a/etc/make.conf b/etc/make.conf
index 8623e1fc746c..0b2e713bb712 100644
--- a/etc/make.conf
+++ b/etc/make.conf
@@ -1,4 +1,4 @@
-# $Id: make.conf,v 1.12 1994/09/30 14:57:01 csgr Exp $
+# $Id: make.conf,v 1.13 1994/11/07 04:17:58 phk Exp $
#
# This file, if present, will be read by make (see /usr/share/mk/sys.mk).
# It allows you to override macro definitions to make without changing
@@ -67,7 +67,7 @@ WANT_MSUN= yes
# (static) one. This makes the compilers run slower (10-15%), but saves
# quite some diskspace.
#
-#SHARED_LIBCC_INT= faster_cc
+#SHARED_LIBCC_INT= smaller_cc
#
#
# Kerberos IV
diff --git a/etc/rc b/etc/rc
index ffd79d75e54f..b57cdccabdb3 100644
--- a/etc/rc
+++ b/etc/rc
@@ -1,5 +1,5 @@
#!/bin/sh
-# $Id: rc,v 1.38 1994/11/02 09:41:35 ache Exp $
+# $Id: rc,v 1.39 1994/11/07 04:02:26 phk Exp $
# From: @(#)rc 5.27 (Berkeley) 6/5/91
# System startup script run by init on autoboot
@@ -193,7 +193,7 @@ fi
# $rwhod is imported from /etc/netstart;
# if $rwhod is set to something other than NO, rwhod is run.
-if [ ${rwhod-NO} != "NO" ]; then
+if [ X"${rwhod}" != X"NO" ]; then
echo -n ' rwhod'; rwhod
fi
diff --git a/games/fortune/Makefile b/games/fortune/Makefile
index c736e356ff84..70778cf00022 100644
--- a/games/fortune/Makefile
+++ b/games/fortune/Makefile
@@ -6,7 +6,7 @@ SUBDIR= fortune
SUBDIR+=datfiles
.endif
-.ifmake !(install)
+.if !make(install) && !make(distribute)
SUBDIR+=strfile
.else
SUBDIR+=datfiles
diff --git a/gnu/gnu2bmake/gcc-2.6.1.patch b/gnu/gnu2bmake/gcc-2.6.1.patch
index 2260b4160378..fb17501992c0 100644
--- a/gnu/gnu2bmake/gcc-2.6.1.patch
+++ b/gnu/gnu2bmake/gcc-2.6.1.patch
@@ -1,178 +1,407 @@
-diff -u -r /freebsd/gcc-2.6.1/cccp.c ./cccp.c
---- /freebsd/gcc-2.6.1/cccp.c Tue Oct 25 15:37:44 1994
-+++ ./cccp.c Wed Nov 2 17:36:25 1994
-@@ -188,7 +188,7 @@
- #ifndef VMS
- #ifndef HAVE_STRERROR
- extern int sys_nerr;
--#if defined(bsd4_4) || defined(__NetBSD__)
-+#if defined(bsd4_4) || defined(__NetBSD__) || defined(__FreeBSD__)
- extern const char *const sys_errlist[];
- #else
- extern char *sys_errlist[];
+# this patch is good for 2.6.1 and 2.6.2
+
+diff -r -c ../../scratch/gcc-2.6.1/cccp.1 ./cccp.1
+*** ../../scratch/gcc-2.6.1/cccp.1 Tue May 31 16:29:50 1994
+--- ./cccp.1 Mon Nov 14 19:42:44 1994
+***************
+*** 1,13 ****
+ .\" Copyright (c) 1991, 1992, 1993 Free Software Foundation \-*-Text-*-
+ .\" See section COPYING for conditions for redistribution
+! .TH cpp 1 "30apr1993" "GNU Tools" "GNU Tools"
+ .SH NAME
+! cccp, cpp \- The GNU C-Compatible Compiler Preprocessor.
+ .SH SYNOPSIS
+ .hy 0
+ .na
+ .TP
+! .B cccp
+ .RB "[\|" \-$ "\|]"
+ .RB "[\|" \-A \c
+ .I predicate\c
+--- 1,13 ----
+ .\" Copyright (c) 1991, 1992, 1993 Free Software Foundation \-*-Text-*-
+ .\" See section COPYING for conditions for redistribution
+! .TH cpp 1 "30, April 1993" "FreeBSD" "GNU Tools"
+ .SH NAME
+! cpp \- Compiler Preprocessor.
+ .SH SYNOPSIS
+ .hy 0
+ .na
+ .TP
+! .B cpp
+ .RB "[\|" \-$ "\|]"
+ .RB "[\|" \-A \c
+ .I predicate\c
+***************
+*** 142,154 ****
+ Most often when you use the C preprocessor you will not have to invoke it
+ explicitly: the C compiler will do so automatically. However, the
+ preprocessor is sometimes useful individually.
+-
+- When you call the preprocessor individually, either name
+- (\c
+- .B cpp\c
+- \& or \c
+- .B cccp\c
+- \&) will do\(em\&they are completely synonymous.
+
+ The C preprocessor expects two file names as arguments, \c
+ .I infile\c
+--- 142,147 ----
+Only in .: cccp.1.orig
+diff -r -c ../../scratch/gcc-2.6.1/cccp.c ./cccp.c
+*** ../../scratch/gcc-2.6.1/cccp.c Tue Oct 25 15:37:44 1994
+--- ./cccp.c Mon Nov 14 19:40:30 1994
+***************
+*** 188,194 ****
+ #ifndef VMS
+ #ifndef HAVE_STRERROR
+ extern int sys_nerr;
+! #if defined(bsd4_4) || defined(__NetBSD__)
+ extern const char *const sys_errlist[];
+ #else
+ extern char *sys_errlist[];
+--- 188,194 ----
+ #ifndef VMS
+ #ifndef HAVE_STRERROR
+ extern int sys_nerr;
+! #if defined(bsd4_4) || defined(__NetBSD__) || defined(__FreeBSD__)
+ extern const char *const sys_errlist[];
+ #else
+ extern char *sys_errlist[];
Only in .: cccp.c.orig
-Only in .: cccp.o
-Only in .: cexp.o
-diff -u -r /freebsd/gcc-2.6.1/collect2.c ./collect2.c
---- /freebsd/gcc-2.6.1/collect2.c Thu Oct 20 15:05:46 1994
-+++ ./collect2.c Wed Nov 2 17:36:25 1994
-@@ -41,7 +41,7 @@
- extern int errno;
- #endif
-
--#if defined(bsd4_4) || defined(__NetBSD__)
-+#if defined(bsd4_4) || defined(__NetBSD__) || defined(__FreeBSD__)
- extern const char *const sys_errlist[];
- #else
- extern char *sys_errlist[];
-Only in .: collect2.c.orig
-diff -u -r /freebsd/gcc-2.6.1/config/i386/freebsd.h ./config/i386/freebsd.h
---- /freebsd/gcc-2.6.1/config/i386/freebsd.h Tue Oct 18 17:59:52 1994
-+++ ./config/i386/freebsd.h Wed Nov 2 17:36:37 1994
-@@ -33,11 +33,13 @@
- #undef CPP_PREDEFINES
- #define CPP_PREDEFINES "-Dunix -Di386 -D__FreeBSD__ -D__FreeBSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)"
-
-+#if 0
- #define INCLUDE_DEFAULTS { \
- { "/usr/include", 0 }, \
- { "/usr/include/g++", 1 }, \
- { 0, 0} \
- }
-+#endif
-
- /* Like the default, except no -lg. */
- #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
+Only in .: cccp.c.rej
+diff -r -c ../../scratch/gcc-2.6.1/config/i386/freebsd.h ./config/i386/freebsd.h
+*** ../../scratch/gcc-2.6.1/config/i386/freebsd.h Tue Oct 18 17:59:52 1994
+--- ./config/i386/freebsd.h Mon Nov 14 19:41:07 1994
+***************
+*** 19,27 ****
+ along with GNU CC; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+- /* This goes away when the math-emulator is fixed */
+- #define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */
+-
+ /* This is tested by i386gas.h. */
+ #define YES_UNDERSCORES
+
+--- 19,24 ----
+***************
+*** 31,37 ****
+ #include "i386/perform.h"
+
+ #undef CPP_PREDEFINES
+! #define CPP_PREDEFINES "-Dunix -Di386 -D__FreeBSD__ -D__386BSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)"
+
+ #define INCLUDE_DEFAULTS { \
+ { "/usr/include", 0 }, \
+--- 28,34 ----
+ #include "i386/perform.h"
+
+ #undef CPP_PREDEFINES
+! #define CPP_PREDEFINES "-Dunix -Di386 -D__FreeBSD__=2 -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)"
+
+ #define INCLUDE_DEFAULTS { \
+ { "/usr/include", 0 }, \
+***************
+*** 39,47 ****
+--- 36,54 ----
+ { 0, 0} \
+ }
+
++ #define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k}"
++
+ /* Like the default, except no -lg. */
+ #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
+
++ #define LINK_SPEC \
++ "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*} \
++ %{p:-Bstatic} %{pg:-Bstatic} %{Z}"
++
++ /* This goes away when the math emulator is fixed. */
++ #undef TARGET_DEFAULT
++ #define TARGET_DEFAULT (MASK_NO_FANCY_MATH_387 | 0301)
++
+ #undef SIZE_TYPE
+ #define SIZE_TYPE "unsigned int"
+
+***************
+*** 49,80 ****
+ #define PTRDIFF_TYPE "int"
+
+ #undef WCHAR_TYPE
+! #define WCHAR_TYPE "short unsigned int"
+
+! #define WCHAR_UNSIGNED 1
+
+ #undef WCHAR_TYPE_SIZE
+! #define WCHAR_TYPE_SIZE 16
+
+ #define HAVE_ATEXIT
+
+! /* Redefine this to use %eax instead of %edx. */
+ #undef FUNCTION_PROFILER
+ #define FUNCTION_PROFILER(FILE, LABELNO) \
+ { \
+ if (flag_pic) \
+! { \
+! fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%eax\n", \
+! LPREFIX, (LABELNO)); \
+! fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \
+! } \
+ else \
+! { \
+! fprintf (FILE, "\tmovl $%sP%d,%%eax\n", LPREFIX, (LABELNO)); \
+! fprintf (FILE, "\tcall mcount\n"); \
+! } \
+ }
+
+ /* There are conflicting reports about whether this system uses
+ a different assembler syntax. wilson@cygnus.com says # is right. */
+ #undef COMMENT_BEGIN
+--- 56,95 ----
+ #define PTRDIFF_TYPE "int"
+
+ #undef WCHAR_TYPE
+! #define WCHAR_TYPE "int"
+
+! #define WCHAR_UNSIGNED 0
+
+ #undef WCHAR_TYPE_SIZE
+! #define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+ #define HAVE_ATEXIT
+
+! /* Tell final.c that we don't need a label passed to mcount. */
+!
+! #define NO_PROFILE_DATA
+!
+! /* Redefine this to not pass an unused label in %edx. */
+!
+ #undef FUNCTION_PROFILER
+ #define FUNCTION_PROFILER(FILE, LABELNO) \
+ { \
+ if (flag_pic) \
+! fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \
+ else \
+! fprintf (FILE, "\tcall mcount\n"); \
+ }
+
++ #if 0 /* not ready for this; it should be decided at compile time */
++ #define FUNCTION_PROFILER_EPILOGUE(FILE) \
++ { \
++ if (flag_pic) \
++ fprintf (FILE, "\tcall *mexitcount@GOT(%%ebx)\n"); \
++ else \
++ fprintf (FILE, "\tcall mexitcount\n"); \
++ }
++ #endif
++
+ /* There are conflicting reports about whether this system uses
+ a different assembler syntax. wilson@cygnus.com says # is right. */
+ #undef COMMENT_BEGIN
+***************
+*** 218,227 ****
+ putc ('\n', FILE); \
+ } \
+ } while (0)
+-
+- #define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k}"
+- #define LINK_SPEC \
+- "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}"
+
+ /* This is defined when gcc is compiled in the BSD-directory-tree, and must
+ * make up for the gap to all the stuff done in the GNU-makefiles.
+--- 233,238 ----
Only in ./config/i386: freebsd.h.orig
-diff -u -r /freebsd/gcc-2.6.1/config/i386/x-freebsd ./config/i386/x-freebsd
---- /freebsd/gcc-2.6.1/config/i386/x-freebsd Mon Oct 31 04:52:41 1994
-+++ ./config/i386/x-freebsd Wed Nov 2 18:45:36 1994
-@@ -1,3 +1,6 @@
- # Don't run fixproto
- STMP_FIXPROTO =
--CLIB=-lgnumalloc
-+CLIB = -lgnumalloc
-+
-+# Find FreeBSD's includes before resorting to GCC's
-+LIBGCC2_INCLUDES -I/usr/include
-Only in .: config.h
-Only in .: config.status
-Only in ./cp: Makefile
-diff -u -r /freebsd/gcc-2.6.1/cp/g++.c ./cp/g++.c
---- /freebsd/gcc-2.6.1/cp/g++.c Sat Oct 29 04:17:44 1994
-+++ ./cp/g++.c Wed Nov 2 17:36:42 1994
-@@ -84,7 +84,7 @@
- #endif
-
- extern int sys_nerr;
--#if defined(bsd4_4) || defined(__NetBSD__)
-+#if defined(bsd4_4) || defined(__NetBSD__) || defined(__FreeBSD__)
- extern const char *const sys_errlist[];
- #else
- extern char *sys_errlist[];
+diff -r -c ../../scratch/gcc-2.6.1/config/i386/i386.c ./config/i386/i386.c
+*** ../../scratch/gcc-2.6.1/config/i386/i386.c Fri Oct 7 12:45:14 1994
+--- ./config/i386/i386.c Mon Nov 14 19:41:27 1994
+***************
+*** 1097,1103 ****
+ int limit;
+ rtx xops[4];
+ int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
+! || current_function_uses_const_pool);
+
+ xops[0] = stack_pointer_rtx;
+ xops[1] = frame_pointer_rtx;
+--- 1097,1104 ----
+ int limit;
+ rtx xops[4];
+ int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
+! || current_function_uses_const_pool
+! || profile_flag || profile_block_flag);
+
+ xops[0] = stack_pointer_rtx;
+ xops[1] = frame_pointer_rtx;
+***************
+*** 1158,1165 ****
+ int nregs = 0;
+ int reglimit = (frame_pointer_needed
+ ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
+! int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
+! || current_function_uses_const_pool);
+
+ #ifdef NON_SAVING_SETJMP
+ if (NON_SAVING_SETJMP && current_function_calls_setjmp)
+--- 1159,1174 ----
+ int nregs = 0;
+ int reglimit = (frame_pointer_needed
+ ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
+!
+! #ifdef FUNCTION_PROFILER_EPILOGUE
+! if (profile_flag)
+! return 0;
+! #endif
+!
+! if (flag_pic && (current_function_uses_pic_offset_table
+! || current_function_uses_const_pool
+! || profile_flag || profile_block_flag))
+! return 0;
+
+ #ifdef NON_SAVING_SETJMP
+ if (NON_SAVING_SETJMP && current_function_calls_setjmp)
+***************
+*** 1170,1177 ****
+ return 0;
+
+ for (regno = reglimit - 1; regno >= 0; regno--)
+! if ((regs_ever_live[regno] && ! call_used_regs[regno])
+! || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
+ nregs++;
+
+ return nregs == 0 || ! frame_pointer_needed;
+--- 1179,1185 ----
+ return 0;
+
+ for (regno = reglimit - 1; regno >= 0; regno--)
+! if (regs_ever_live[regno] && ! call_used_regs[regno])
+ nregs++;
+
+ return nregs == 0 || ! frame_pointer_needed;
+***************
+*** 1193,1198 ****
+--- 1201,1211 ----
+ rtx xops[3];
+ int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
+ || current_function_uses_const_pool);
++
++ #ifdef FUNCTION_PROFILER_EPILOGUE
++ if (profile_flag)
++ FUNCTION_PROFILER_EPILOGUE (file);
++ #endif
+
+ /* Compute the number of registers to pop */
+
+Only in ./config/i386: i386.c.orig
+diff -r -c ../../scratch/gcc-2.6.1/cp/g++.c ./cp/g++.c
+*** ../../scratch/gcc-2.6.1/cp/g++.c Sat Oct 29 04:17:44 1994
+--- ./cp/g++.c Mon Nov 14 19:41:16 1994
+***************
+*** 84,90 ****
+ #endif
+
+ extern int sys_nerr;
+! #if defined(bsd4_4) || defined(__NetBSD__)
+ extern const char *const sys_errlist[];
+ #else
+ extern char *sys_errlist[];
+--- 84,90 ----
+ #endif
+
+ extern int sys_nerr;
+! #if defined(bsd4_4) || defined(__NetBSD__) || defined(__FreeBSD__)
+ extern const char *const sys_errlist[];
+ #else
+ extern char *sys_errlist[];
Only in ./cp: g++.c.orig
-Only in ./cp: include
-Only in ./cp: stage1
-Only in ./cp: stage2
-Only in ./cp: stage3
-Only in ./cp: stage4
-Only in .: cpp
-Only in .: float.h-nat
-diff -u -r /freebsd/gcc-2.6.1/gcc.c ./gcc.c
---- /freebsd/gcc-2.6.1/gcc.c Thu Oct 27 15:49:58 1994
-+++ ./gcc.c Wed Nov 2 17:36:43 1994
-@@ -166,7 +166,7 @@
- #endif
-
- extern int sys_nerr;
--#if defined(bsd4_4) || defined(__NetBSD__)
-+#if defined(bsd4_4) || defined(__NetBSD__) || defined (__FreeBSD__)
- extern const char *const sys_errlist[];
- #else
- extern char *sys_errlist[];
+Only in ../../scratch/gcc-2.6.1: cpp.1
+Only in .: cpp.1.orig
+Only in .: cpp.1.rej
+Only in .: cpp.1.rej.orig
+diff -r -c ../../scratch/gcc-2.6.1/final.c ./final.c
+*** ../../scratch/gcc-2.6.1/final.c Tue Sep 20 17:05:03 1994
+--- ./final.c Mon Nov 14 19:40:32 1994
+***************
+*** 957,970 ****
+--- 957,974 ----
+ profile_function (file)
+ FILE *file;
+ {
++ #ifndef NO_PROFILE_DATA
+ int align = MIN (BIGGEST_ALIGNMENT, POINTER_SIZE);
++ #endif /* not NO_PROFILE_DATA */
+ int sval = current_function_returns_struct;
+ int cxt = current_function_needs_context;
+
++ #ifndef NO_PROFILE_DATA
+ data_section ();
+ ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
+ ASM_OUTPUT_INTERNAL_LABEL (file, "LP", profile_label_no);
+ assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
++ #endif /* not NO_PROFILE_DATA */
+
+ text_section ();
+
+Only in .: final.c.orig
+Only in .: final.c.rej
+diff -r -c ../../scratch/gcc-2.6.1/gcc.c ./gcc.c
+*** ../../scratch/gcc-2.6.1/gcc.c Thu Oct 27 15:49:58 1994
+--- ./gcc.c Mon Nov 14 19:41:18 1994
+***************
+*** 166,172 ****
+ #endif
+
+ extern int sys_nerr;
+! #if defined(bsd4_4) || defined(__NetBSD__)
+ extern const char *const sys_errlist[];
+ #else
+ extern char *sys_errlist[];
+--- 166,172 ----
+ #endif
+
+ extern int sys_nerr;
+! #if defined(bsd4_4) || defined(__NetBSD__) || defined (__FreeBSD__)
+ extern const char *const sys_errlist[];
+ #else
+ extern char *sys_errlist[];
+***************
+*** 711,716 ****
+--- 711,745 ----
+ %{!S:%{!gnatc:%{!gnats:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
+ %{c:%W{o*}%{!o*:-o %w%b.o}}\
+ %{!c:-o %d%w%u.o} %{!pipe:%g.s} %A\n}}}}}} "},
++ /***** ljo's Fortran rule *****/
++ {".f", "@f2c"},
++ {"@f2c",
++ "f2c %{checksubscripts:-C} %{I2} %{onetrip} %{honorcase:-U} %{u} %{w}\
++ %{ANSIC:-A} %{a} %{C++}\
++ %{c} %{E} %{ec} %{ext} %{f} %{72} %{g} %{h} %{i2} %{kr}\
++ %{P} %{p} %{r} %{r8} %{s} %{w8} %{z} %{N*}\
++ %i %{!pipe: -o %g.c} %{pipe:-o -}|\n",
++ "cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\
++ %{C:%{!E:%eGNU C does not support -C without using -E}}\
++ %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
++ -undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\
++ %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\
++ %{!undef:%{!ansi:%p} %P} %{trigraphs} \
++ %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
++ %{traditional-cpp:-traditional}\
++ %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\
++ %{pipe:-} %{!pipe:%g.c} %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
++ "%{!M:%{!MM:%{!E:cc1 %{!pipe:%g.i} %1 \
++ %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a}\
++ %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
++ %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
++ %{aux-info*}\
++ %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
++ %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
++ %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\
++ %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\
++ %{!pipe:%g.s} %A\n }}}}"},
++ /***** End of ljo's Fortran rule *****/
+ /* Mark end of table */
+ {0, 0}
+ };
Only in .: gcc.c.orig
-Only in .: gfloat.h
-diff -u -r /freebsd/gcc-2.6.1/ginclude/stdarg.h ./ginclude/stdarg.h
---- /freebsd/gcc-2.6.1/ginclude/stdarg.h Fri Jul 8 19:04:27 1994
-+++ ./ginclude/stdarg.h Wed Nov 2 17:36:49 1994
-@@ -136,13 +136,13 @@
- But on BSD NET2 we must not test or define or undef it.
- (Note that the comments in NET 2's ansi.h
- are incorrect for _VA_LIST_--see stdio.h!) */
--#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____FreeBSD____) || defined (__bsdi__) || defined (__FreeBSD__)
-+#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____FreeBSD____) || defined (__bsdi__)
- /* The macro _VA_LIST is used in SCO Unix 3.2. */
- #ifndef _VA_LIST
- /* The macro _VA_LIST_T_H is used in the Bull dpx2 */
- #ifndef _VA_LIST_T_H
- #define _VA_LIST_T_H
--#if !(defined (__BSD_NET2__) || defined (____FreeBSD____) || defined (__bsdi__) || defined (__FreeBSD__))
-+#if !(defined (__BSD_NET2__) || defined (____FreeBSD____) || defined (__bsdi__)
- #define _VA_LIST_
- #endif
- #define _VA_LIST
-Only in ./ginclude: stdarg.h.orig
-diff -u -r /freebsd/gcc-2.6.1/ginclude/stddef.h ./ginclude/stddef.h
---- /freebsd/gcc-2.6.1/ginclude/stddef.h Fri Oct 7 16:22:35 1994
-+++ ./ginclude/stddef.h Wed Nov 2 17:36:54 1994
-@@ -22,7 +22,7 @@
-
- /* On 4.3bsd-net2, make sure ansi.h is included, so we have
- one less case to deal with in the following. */
--#if defined (__BSD_NET2__) || defined (____FreeBSD____) || defined (__FreeBSD__)
-+#if defined (__BSD_NET2__) || defined (____FreeBSD____)
- #include <machine/ansi.h>
- #endif
-
-Only in ./ginclude: stddef.h.orig
-diff -u -r /freebsd/gcc-2.6.1/ginclude/varargs.h ./ginclude/varargs.h
---- /freebsd/gcc-2.6.1/ginclude/varargs.h Fri Jul 8 19:04:32 1994
-+++ ./ginclude/varargs.h Wed Nov 2 17:36:59 1994
-@@ -151,13 +151,13 @@
- /* Michael Eriksson <mer@sics.se> at Thu Sep 30 11:00:57 1993:
- Sequent defines _VA_LIST_ in <machine/machtypes.h> to be the type to
- use for va_list (``typedef _VA_LIST_ va_list'') */
--#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____FreeBSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__)
-+#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____FreeBSD____) || defined (__bsdi__) || defined (__sequent__)
- /* The macro _VA_LIST is used in SCO Unix 3.2. */
- #ifndef _VA_LIST
- /* The macro _VA_LIST_T_H is used in the Bull dpx2 */
- #ifndef _VA_LIST_T_H
- #define _VA_LIST_T_H
--#if !(defined (__BSD_NET2__) || defined (____FreeBSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__))
-+#if !(defined (__BSD_NET2__) || defined (____FreeBSD____) || defined (__bsdi__) || defined (__sequent__)
- #define _VA_LIST_
- #endif
- #define _VA_LIST
-Only in ./ginclude: varargs.h.orig
-Only in .: hconfig.h
-Only in .: include
-Only in .: libgcc.a
-Only in .: libgcc1.a
-Only in .: libgcc2.a
-Only in .: libgcc2.ready
-Only in .: md
-Only in .: multilib.h
-Only in .: objc-headers
-Only in .: obstack.o
-diff -u -r /freebsd/gcc-2.6.1/protoize.c ./protoize.c
---- /freebsd/gcc-2.6.1/protoize.c Tue Oct 4 20:17:40 1994
-+++ ./protoize.c Wed Nov 2 17:37:00 1994
-@@ -79,7 +79,7 @@
- #undef getopt
-
- extern int errno;
--#if defined(bsd4_4) || defined(__NetBSD__)
-+#if defined(bsd4_4) || defined(__NetBSD__) || defined (__FreeBSD__)
- extern const char *const sys_errlist[];
- #else
- extern char *sys_errlist[];
-Only in .: protoize.c.orig
-Only in .: stage1
-Only in .: stmp-fixinc
-Only in .: stmp-headers
-Only in .: stmp-int-hdrs
-Only in .: tconfig.h
-Only in .: tm.h
-Only in .: version.o
-Only in .: xlimits.h
diff --git a/gnu/gnu2bmake/gcc-2.6.1.tcl b/gnu/gnu2bmake/gcc-2.6.1.tcl
index 8b1ef7a74e48..a56c804af861 100755
--- a/gnu/gnu2bmake/gcc-2.6.1.tcl
+++ b/gnu/gnu2bmake/gcc-2.6.1.tcl
@@ -7,16 +7,17 @@
# this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
# ----------------------------------------------------------------------------
#
-# $FreeBSD$
+# $Id$
#
+# Good for 2.6.1 and 2.6.2
source gnu2bmake.tcl
#######################################################################
# Parameters to tweak
########
-set sdir /freebsd/A/gcc-2.6.1
-set ddir /freebsd/A/cc261
+set sdir /freebsd/gcc-2.6.2
+set ddir /freebsd/cc262
#######################################################################
# Do the stunt
@@ -94,21 +95,37 @@ set target [makefile_macro target $sdir]
sh "rm -rf $ddir"
sh "mkdir $ddir"
set f [open $ddir/Makefile.inc w]
-puts $f "#\n# \$FreeBSD\$\n#\n"
+puts $f "#\n# \$Id\$\n#\n"
puts $f "CFLAGS+=\t-I\${.CURDIR} -I\${.CURDIR}/../include"
puts $f "CFLAGS+=\t-Dbsd4_4"
puts $f "CFLAGS+=\t-DGCC_INCLUDE_DIR=\\\"FOO\\\""
-puts $f "CFLAGS+=\t-DGPLUSPLUS_INCLUDE_DIR=\\\"FOO\\\""
puts $f "CFLAGS+=\t-DTOOL_INCLUDE_DIR=\\\"FOO\\\""
+puts $f "CFLAGS+=\t-DGPLUSPLUS_INCLUDE_DIR=\\\"FOO\\\""
puts $f "CFLAGS+=\t-DDEFAULT_TARGET_VERSION=\\\"$version\\\""
puts $f "CFLAGS+=\t-DDEFAULT_TARGET_MACHINE=\\\"$target\\\""
puts $f "CFLAGS+=\t-DMD_EXEC_PREFIX=\\\"/usr/libexec/\\\""
puts $f "CFLAGS+=\t-DSTANDARD_STARTFILE_PREFIX=\\\"/usr/lib\\\""
+puts $f "CFLAGS+=\t-DGCC_NAME=\\\"cc\\\""
+puts $f ""
+puts $f ".if exists(\${.CURDIR}/../cc_int/obj)"
+puts $f "LIBDESTDIR=\t\${.CURDIR}/../cc_int/obj"
+puts $f ".else"
+puts $f "LIBDESTDIR=\t\${.CURDIR}/../cc_int"
+puts $f ".endif"
+puts $f ""
+
+puts $f "# XXX LDDESTDIR isn't a directory and there is no standard name for the dir"
+puts $f "LDDESTDIR=\t-L\${LIBDESTDIR}"
+puts $f ".if defined(SHARED_LIBCC_INT)"
+puts $f "LIBCC_INT=\t\${LIBDESTDIR}/libcc_int.so.262.0"
+puts $f ".else"
+puts $f "LIBCC_INT=\t\${LIBDESTDIR}/libcc_int.a"
+puts $f ".endif"
close $f
set f [open $ddir/Makefile w]
-puts $f "#\n# \$FreeBSD\$\n#\n"
-puts $f "PGMDIR=\tcc_int cpp cc1 cc cc1plus c++ libgcc"
+puts $f "#\n# \$Id\$\n#\n"
+puts $f "PGMDIR=\tcc_int cpp cc1 cc cc1plus c++ f77 libgcc"
puts $f "SUBDIR=\t\$(PGMDIR)"
puts $f "\n.include <bsd.subdir.mk>"
close $f
@@ -118,7 +135,7 @@ sh "mkdir $ddir/legal"
sh "cp $sdir/gen-*.c $sdir/md $ddir/legal"
set f [open $ddir/README w]
puts $f {
-$FreeBSD$
+$Id$
This directory contains gcc in a form that uses "bmake" makefiles.
This is not the place you want to start, if you want to hack gcc.
@@ -137,11 +154,11 @@ Thankyou.
# do ~/libgcc
sh "mkdir $ddir/libgcc"
set f [open $ddir/libgcc/Makefile w]
-puts $f "#\n# \$FreeBSD\$\n#\n"
+puts $f "#\n# \$Id\$\n#\n"
puts $f "LIB=\tgcc"
puts $f "INSTALL_PIC_ARCHIVE=\tyes"
-puts $f "SHLIB_MAJOR=\t26"
-puts $f "SHLIB_MINOR=\t1"
+puts $f "SHLIB_MAJOR=\t261"
+puts $f "SHLIB_MINOR=\t0"
puts $f ""
puts $f "LIB1OBJS=\t[add_suffix $l_libgcc1 .o]"
puts $f "LIB2OBJS=\t[add_suffix $l_libgcc2 .o]"
@@ -195,28 +212,31 @@ copy_l $sdir/config/i386 $ddir/include/i386 [add_suffix $l_include_i386 .h]
# do ~/cc_int
mk_lib $ddir cc_int [add_suffix $l_common .c] {
- "NOPROFILE=\t1"
+ "NOPROFILE=\tyes"
+ ".if defined(SHARED_LIBCC_INT)"
+ "INTERNALLIB="
+ "SHLIB_MAJOR=262"
+ "SHLIB_MINOR=0"
+ ".else"
"\ninstall:\n\t@true"
+ ".endif"
}
copy_c $sdir $ddir/cc_int $l_common
# do ~/cpp
mk_prog $ddir cpp [add_suffix $l_cpp .c] {
"BINDIR=\t/usr/libexec"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int/obj"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int"
- "LDADD+=\t-lcc_int"
+ ".PATH:\t\${.CURDIR}/../cc_int"
+ "SRCS+=\tobstack.c version.c"
}
copy_c $sdir $ddir/cpp $l_cpp
-cp $sdir/cpp.1 $ddir/cpp/cpp.1
+cp $sdir/cccp.1 $ddir/cpp/cpp.1
# do ~/c++
mk_prog $ddir c++ [add_suffix "$l_cplus $l_cplus_cp" .c] {
"BINDIR=\t/usr/bin"
+ "LINKS=\t\${BINDIR}/c++ \${BINDIR}/g++"
"NOMAN=\t1"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int/obj"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int"
- "LDADD+=\t-lcc_int"
}
copy_c $sdir $ddir/c++ $l_cplus
copy_c $sdir/cp $ddir/c++ $l_cplus_cp
@@ -224,13 +244,9 @@ copy_c $sdir/cp $ddir/c++ $l_cplus_cp
# do ~/cc
mk_prog $ddir cc [add_suffix $l_cc .c] {
"BINDIR=\t/usr/bin"
- "MLINKS+=cc.1 gcc.1"
- "MLINKS+=cc.1 c++.1"
- "MLINKS+=cc.1 g++.1"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int/obj"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int"
- "LDADD+=\t-lcc_int"
- "\nafterinstall:\n\tcd \$(DESTDIR)\$(BINDIR) ; rm gcc ; ln -s cc gcc"
+ ".PATH: \${.CURDIR}/../cc_int"
+ "SRCS+=\tobstack.c version.c"
+ "LINKS=\t\${BINDIR}/cc \${BINDIR}/gcc"
}
copy_c $sdir $ddir/cc $l_cc
cp $sdir/gcc.1 $ddir/cc/cc.1
@@ -239,9 +255,8 @@ cp $sdir/gcc.1 $ddir/cc/cc.1
mk_prog $ddir cc1 [add_suffix $l_cc1 .c] {
"BINDIR=\t/usr/libexec"
"NOMAN=\t1"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int/obj"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int"
- "LDADD+=\t-lcc_int"
+ "DPADD+=\t\${LIBCC_INT} \${LIBGNUMALLOC}"
+ "LDADD+=\t-lcc_int -lgnumalloc"
}
copy_c $sdir $ddir/cc1 $l_cc1
@@ -249,9 +264,8 @@ copy_c $sdir $ddir/cc1 $l_cc1
mk_prog $ddir cc1plus [add_suffix "$l_cc1plus_cp $l_cc1plus" .c] {
"BINDIR=\t/usr/libexec"
"NOMAN=\t1"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int/obj"
- "LDDESTDIR+=\t-L\${.CURDIR}/../cc_int"
- "LDADD+=\t-lcc_int"
+ "DPADD+=\t\${LIBCC_INT} \${LIBGNUMALLOC}"
+ "LDADD+=\t-lcc_int -lgnumalloc"
}
copy_l $sdir/cp $ddir/cc1plus $l_cc1plus_x
copy_c $sdir $ddir/cc1plus $l_cc1plus
diff --git a/gnu/gnu2bmake/gnu2bmake.tcl b/gnu/gnu2bmake/gnu2bmake.tcl
index 74221734d722..a99b1b3d134d 100644
--- a/gnu/gnu2bmake/gnu2bmake.tcl
+++ b/gnu/gnu2bmake/gnu2bmake.tcl
@@ -7,7 +7,7 @@
# this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
# ----------------------------------------------------------------------------
#
-# $FreeBSD$
+# $Id$
#
#######################################################################
# Generic procedures usable in the process of gnu-to-bmake jobs.
@@ -166,7 +166,7 @@ proc makefile_macro {macro dir {makefile Makefile}} {
proc mk_prog {ddir name list {make ""}} {
sh "mkdir $ddir/$name"
set f [open $ddir/$name/Makefile w]
- puts $f "#\n# \$FreeBSD\$\n#\n"
+ puts $f "#\n# \$Id\$\n#\n"
puts $f "PROG =\t$name"
puts $f "SRCS =\t[lsort $list]"
foreach i $make {puts $f $i}
@@ -184,7 +184,7 @@ proc mk_prog {ddir name list {make ""}} {
proc mk_lib {ddir name list {make ""}} {
sh "mkdir $ddir/$name"
set f [open $ddir/$name/Makefile w]
- puts $f "#\n# \$FreeBSD\$\n#\n"
+ puts $f "#\n# \$Id\$\n#\n"
puts $f "SRCS =\t[lsort $list]"
puts $f "LIB =\t$name"
foreach i $make {puts $f $i}
diff --git a/gnu/include/values.h b/gnu/include/values.h
index 529c5e7ae96a..91f448d1261c 100644
--- a/gnu/include/values.h
+++ b/gnu/include/values.h
@@ -1,3 +1,7 @@
+#if __GNUC__
+#warning "this file includes <values.h> which is obsoleted, use <limits.h> or <float.h> instead"
+#endif
+
/*
Copyright (C) 1988 Free Software Foundation
written by Doug Lea (dl@rocky.oswego.edu)
diff --git a/gnu/lib/libdialog/checklist.c b/gnu/lib/libdialog/checklist.c
index cc83d258b5ff..c31a9305903c 100644
--- a/gnu/lib/libdialog/checklist.c
+++ b/gnu/lib/libdialog/checklist.c
@@ -34,8 +34,8 @@ static int list_width, check_x, item_x;
*/
int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result)
{
- int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
- scroll = 0, max_choice, *status;
+ int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ l, k, scroll = 0, max_choice, *status;
WINDOW *dialog, *list;
/* Allocate space for storing item on/off status */
@@ -50,6 +50,30 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
max_choice = MIN(list_height, item_no);
+ check_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center checklist */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i*3]);
+ for (j = 0; j < item_no; j++) {
+ k = strlen(items[j*3 + 1]);
+ check_x = MAX(check_x, l + k + 6);
+ }
+ item_x = MAX(item_x, l);
+ }
+ if (height < 0)
+ height = strheight(prompt)+list_height+4+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = strwidth(title);
+ width = MAX(i,j);
+ width = MAX(width,check_x+4)+4;
+ }
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
@@ -106,13 +130,6 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in
/* draw a box around the list items */
draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
- check_x = 0;
- item_x = 0;
- /* Find length of longest item in order to center checklist */
- for (i = 0; i < item_no; i++) {
- check_x = MAX(check_x, strlen(items[i*3]) + strlen(items[i*3 + 1]) + 6);
- item_x = MAX(item_x, strlen(items[i*3]));
- }
check_x = (list_width - check_x) / 2;
item_x = check_x + item_x + 6;
diff --git a/gnu/lib/libdialog/dialog.h b/gnu/lib/libdialog/dialog.h
index f2b5d691bee6..35f6f357e5a0 100644
--- a/gnu/lib/libdialog/dialog.h
+++ b/gnu/lib/libdialog/dialog.h
@@ -79,17 +79,20 @@ extern bool use_shadow;
void draw_shadow(WINDOW *win, int y, int x, int height, int width);
#endif
void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border);
-int line_edit(WINDOW* dialog, int box_y, int box_x, int box_width, chtype attrs, int first, unsigned char *result);
+int line_edit(WINDOW* dialog, int box_y, int box_x, int flen, int box_width, chtype attrs, int first, unsigned char *result);
+int strheight(const char *p);
+int strwidth(const char *p);
void dialog_create_rc(unsigned char *filename);
int dialog_yesno(unsigned char *title, unsigned char *prompt, int height, int width);
-int dialog_prgbox(unsigned char *title, const char *line, int height, int width, int pause, int use_shell);
+int dialog_prgbox(unsigned char *title, const unsigned char *line, int height, int width, int pause, int use_shell);
int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause);
int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width);
int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result);
int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result);
-int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result);
+int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result);
int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width, unsigned char *result);
+void dialog_clear_norefresh(void);
void dialog_clear(void);
void dialog_update(void);
void init_dialog(void);
diff --git a/gnu/lib/libdialog/inputbox.c b/gnu/lib/libdialog/inputbox.c
index 197b4dfaedf7..61dd2f21248f 100644
--- a/gnu/lib/libdialog/inputbox.c
+++ b/gnu/lib/libdialog/inputbox.c
@@ -28,11 +28,23 @@
*/
int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width, unsigned char *result)
{
- int i, x, y, box_y, box_x, box_width, first,
+ int i, j, x, y, box_y, box_x, box_width, first,
key = 0, button = -1;
unsigned char instr[MAX_LEN+1];
WINDOW *dialog;
+ if (height < 0)
+ height = strheight(prompt)+2+4;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = strwidth(title);
+ width = MAX(i,j) + 4;
+ }
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
@@ -86,10 +98,12 @@ int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int
first = 1;
strcpy(instr, result);
+ wattrset(dialog, dialog_attr);
+
while (key != ESC) {
if (button == -1) { /* Input box selected */
- key = line_edit(dialog, box_y, box_x, box_width, dialog_attr, first, instr);
+ key = line_edit(dialog, box_y, box_x, -1, box_width, inputbox_attr, first, instr);
first = 0;
}
else
diff --git a/gnu/lib/libdialog/kernel.c b/gnu/lib/libdialog/kernel.c
index bdaa87f33214..309a0ba15c44 100644
--- a/gnu/lib/libdialog/kernel.c
+++ b/gnu/lib/libdialog/kernel.c
@@ -375,17 +375,30 @@ void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chty
*/
void draw_shadow(WINDOW *win, int y, int x, int height, int width)
{
- int i;
+ int i,sx,sy;
if (has_colors()) { /* Whether terminal supports color? */
+ getbegyx(win,sy,sx);
+ /* small touch */
+ wattrset(win, A_INVIS);
+ wmove(win, y + height, x + 2);
+ for (i = 0; i < width; i++)
+ waddch(win, ' ');
+ /* end touch */
wattrset(win, shadow_attr);
wmove(win, y + height, x + 2);
for (i = 0; i < width; i++)
- waddch(win, winch(win) & A_CHARTEXT);
+ waddch(win, mvwinch(newscr, sy+y+height, sx+x+2+i) & A_CHARTEXT);
for (i = y + 1; i < y + height + 1; i++) {
+ /* small touch */
+ wattrset(win, A_INVIS);
+ wmove(win, i, x + width);
+ waddstr(win, " ");
+ /* end touch */
+ wattrset(win, shadow_attr);
wmove(win, i, x + width);
- waddch(win, winch(win) & A_CHARTEXT);
- waddch(win, winch(win) & A_CHARTEXT);
+ waddch(win, mvwinch(newscr, sy+i, sx+x+width) & A_CHARTEXT);
+ waddch(win, mvwinch(newscr, sy+i, sx+x+width+1) & A_CHARTEXT);
}
wnoutrefresh(win);
}
@@ -393,11 +406,17 @@ void draw_shadow(WINDOW *win, int y, int x, int height, int width)
/* End of draw_shadow() */
#endif
-void dialog_clear(void)
+void dialog_clear_norefresh(void)
{
attr_clear(stdscr, LINES, COLS, screen_attr);
touchwin(stdscr);
- refresh();
+ wnoutrefresh(stdscr);
+}
+
+void dialog_clear(void)
+{
+ dialog_clear_norefresh();
+ doupdate();
}
void dialog_update(void)
@@ -409,3 +428,53 @@ void end_dialog(void)
{
endwin();
}
+
+int strwidth(const char *p)
+{
+ int i = 0, len, incr;
+ const char *start, *s, *s1, *s2;
+
+ for (start = s = p; ; start = (s += incr)) {
+ s1 = strchr(s, '\n');
+ s2 = strstr(s, "\\n");
+ if (s2 == NULL)
+ s = s1;
+ else if (s1 == NULL)
+ s = s2;
+ else
+ s = MIN(s1, s2);
+ if (s == NULL)
+ break;
+ incr = 1 + (s == s2);
+ len = s - start;
+ if (len > i)
+ i = len;
+ }
+ len = strlen(start);
+ if (len > i)
+ i = len;
+ return i;
+}
+
+int strheight(const char *p)
+{
+ int i = 1, incr;
+ const char *s, *s1, *s2;
+
+ for (s = p; ; s += incr) {
+ s1 = strchr(s, '\n');
+ s2 = strstr(s, "\\n");
+ if (s2 == NULL)
+ s = s1;
+ else if (s1 == NULL)
+ s = s2;
+ else
+ s = MIN(s1, s2);
+ if (s == NULL)
+ break;
+ incr = 1 + (s == s2);
+ i++;
+ }
+ return i;
+}
+
diff --git a/gnu/lib/libdialog/lineedit.c b/gnu/lib/libdialog/lineedit.c
index d6dbd579a85a..37f7ccefde48 100644
--- a/gnu/lib/libdialog/lineedit.c
+++ b/gnu/lib/libdialog/lineedit.c
@@ -26,14 +26,20 @@
/*
* Line editor
*/
-int line_edit(WINDOW* dialog, int box_y, int box_x, int box_width, chtype attr, int first, unsigned char *result)
+int line_edit(WINDOW* dialog, int box_y, int box_x, int flen, int box_width, chtype attr, int first, unsigned char *result)
{
- int i, key;
+ int i, key, len, max_len, fix_len;
+ chtype old_attr;
static int input_x, scroll;
static unsigned char instr[MAX_LEN+1];
+ unsigned char erase_char = erasechar();
+ unsigned char kill_char = killchar();
+#ifdef notyet
+ unsignec char werase_char = cur_term->Ottyb.c_cc[VWERASE];
+#endif
- wattrset(dialog, attr);
- keypad(dialog, TRUE);
+ old_attr = getattrs(dialog);
+ keypad(dialog, TRUE);
if (first) {
memset(instr, 0, sizeof(instr));
@@ -41,14 +47,22 @@ int line_edit(WINDOW* dialog, int box_y, int box_x, int box_width, chtype attr,
i = strlen(instr);
input_x = i % box_width;
scroll = i - input_x;
- wmove(dialog, box_y, box_x);
- for (i = 0; i < box_width; i++)
- waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
}
+ wmove(dialog, box_y, box_x);
+ wattrset(dialog, attr);
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = 0; i < fix_len; i++)
+ waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
+ len = strlen(instr);
+ wattrset(dialog, old_attr);
+ max_len = MIN(len-scroll,box_width);
+ for ( ; i < max_len; i++)
+ waddch(dialog, instr[scroll+i]);
wmove(dialog, box_y, box_x + input_x);
- wrefresh(dialog);
for (;;) {
+ wattrset(dialog, attr);
+ wrefresh(dialog);
key = wgetch(dialog);
switch (key) {
case TAB:
@@ -63,13 +77,20 @@ int line_edit(WINDOW* dialog, int box_y, int box_x, int box_width, chtype attr,
if (key == '\r')
key = '\n';
goto ret;
+ case '\025':
+ kill_it:
+ memset(instr, 0, sizeof(instr));
case KEY_HOME:
input_x = scroll = 0;
wmove(dialog, box_y, box_x);
- for (i = 0; i < box_width; i++)
+ fix_len = flen >= 0 ? MIN(flen,box_width) : box_width;
+ for (i = 0; i < fix_len; i++)
waddch(dialog, instr[i] ? instr[i] : ' ');
+ wattrset(dialog, old_attr);
+ max_len = MIN(len,box_width);
+ for ( ; i < max_len; i++)
+ waddch(dialog, instr[i]);
wmove(dialog, box_y, box_x);
- wrefresh(dialog);
continue;
case KEY_END:
for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
@@ -78,38 +99,51 @@ int line_edit(WINDOW* dialog, int box_y, int box_x, int box_width, chtype attr,
input_x = i % box_width;
scroll = i - input_x;
wmove(dialog, box_y, box_x);
- for (i = 0; i < box_width; i++)
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = 0; i < fix_len; i++)
waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
+ wattrset(dialog, old_attr);
+ max_len = MIN(len-scroll,box_width);
+ for ( ; i < max_len; i++)
+ waddch(dialog, instr[scroll+i]);
wmove(dialog, box_y, input_x + box_x);
- wrefresh(dialog);
continue;
case KEY_LEFT:
if (input_x || scroll) {
- wattrset(dialog, inputbox_attr);
if (!input_x) {
int oldscroll = scroll;
scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
wmove(dialog, box_y, box_x);
- for (i = 0; i < box_width; i++)
- waddch(dialog, instr[scroll+input_x+i] ? instr[scroll+input_x+i] : ' ');
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = 0; i < fix_len; i++)
+ waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
+ wattrset(dialog, old_attr);
+ max_len = MIN(len-scroll,box_width);
+ for ( ; i < max_len; i++)
+ waddch(dialog, instr[scroll+i]);
input_x = oldscroll - 1 - scroll;
}
else
input_x--;
wmove(dialog, box_y, input_x + box_x);
- wrefresh(dialog);
}
continue;
case KEY_RIGHT:
- if (scroll+input_x < MAX_LEN) {
- wattrset(dialog, inputbox_attr);
+ if ( scroll+input_x < MAX_LEN
+ && (flen < 0 || scroll+input_x < flen)
+ ) {
if (!instr[scroll+input_x])
instr[scroll+input_x] = ' ';
if (input_x == box_width-1) {
scroll++;
wmove(dialog, box_y, box_x);
- for (i = 0; i < box_width; i++)
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = 0; i < fix_len; i++)
waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
+ wattrset(dialog, old_attr);
+ max_len = MIN(len-scroll,box_width);
+ for ( ; i < max_len; i++)
+ waddch(dialog, instr[scroll+i]);
wmove(dialog, box_y, box_x + box_width - 1);
}
else {
@@ -117,62 +151,89 @@ int line_edit(WINDOW* dialog, int box_y, int box_x, int box_width, chtype attr,
waddch(dialog, instr[scroll+input_x]);
input_x++;
}
- wrefresh(dialog);
} else
- flash(); /* Alarm user about overflow */
+ beep(); /* Alarm user about overflow */
continue;
+ case '\b':
+ case '\177':
case KEY_BACKSPACE:
case KEY_DC:
+ erase_it:
if (input_x || scroll) {
i = strlen(instr);
memmove(instr+scroll+input_x-1, instr+scroll+input_x, i-scroll+input_x+1);
- wattrset(dialog, inputbox_attr);
if (!input_x) {
int oldscroll = scroll;
scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
wmove(dialog, box_y, box_x);
- for (i = 0; i < box_width; i++)
- waddch(dialog, instr[scroll+input_x+i] ? instr[scroll+input_x+i] : ' ');
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = 0; i < fix_len; i++)
+ waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
input_x = oldscroll - 1 - scroll;
}
else
input_x--;
wmove(dialog, box_y, input_x + box_x);
- for (i = input_x; i < box_width; i++)
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = input_x; i < fix_len; i++)
waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
+ wattrset(dialog, old_attr);
+ max_len = MIN(len-scroll,box_width);
+ for ( ; i < max_len; i++)
+ waddch(dialog, instr[scroll+i]);
wmove(dialog, box_y, input_x + box_x);
- wrefresh(dialog);
}
continue;
default:
+ if (CCEQ(key, erase_char))
+ goto erase_it;
+ if (CCEQ(key, kill_char))
+ goto kill_it;
if (key < 0x100 && isprint(key)) {
for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
instr[i] = '\0';
i++;
- if (i < MAX_LEN) {
+ if (i < MAX_LEN && (flen < 0 || scroll+input_x < flen)) {
+ if (flen < 0 || i < flen)
memmove(instr+scroll+input_x+1, instr+scroll+input_x, i-scroll+input_x);
- wattrset(dialog, inputbox_attr);
instr[scroll+input_x] = key;
- if (input_x == box_width-1) {
+ if (input_x == box_width-1 && (flen < 0 || i < flen)) {
scroll++;
wmove(dialog, box_y, box_x);
- for (i = 0; i < box_width-1; i++)
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = 0; i < fix_len; i++)
+ waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
+ wattrset(dialog, old_attr);
+ max_len = MIN(len-scroll,box_width);
+ for ( ; i < max_len; i++)
waddch(dialog, instr[scroll+i]);
+ wmove(dialog, box_y, input_x + box_x);
}
else {
wmove(dialog, box_y, input_x + box_x);
- for (i = input_x; i < box_width; i++)
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = input_x; i < fix_len; i++)
waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
+ wattrset(dialog, old_attr);
+ max_len = MIN(len-scroll,box_width);
+ for ( ; i < max_len; i++)
+ waddch(dialog, instr[scroll+i]);
wmove(dialog, box_y, ++input_x + box_x);
}
- wrefresh(dialog);
} else
- flash(); /* Alarm user about overflow */
+ beep(); /* Alarm user about overflow */
continue;
}
}
}
ret:
+ wattrset(dialog, old_attr);
+ wmove(dialog, box_y, box_x);
+ max_len = MIN(len-scroll,box_width);
+ for (i = 0; i < max_len; i++)
+ waddch(dialog, instr[scroll+i]);
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
strcpy(result, instr);
return key;
}
diff --git a/gnu/lib/libdialog/menubox.c b/gnu/lib/libdialog/menubox.c
index 5aa5b5b11168..ed82ae5670bc 100644
--- a/gnu/lib/libdialog/menubox.c
+++ b/gnu/lib/libdialog/menubox.c
@@ -34,12 +34,36 @@ static int menu_width, tag_x, item_x;
*/
int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result)
{
- int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
- scroll = 0, max_choice;
+ int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ l, k, scroll = 0, max_choice;
WINDOW *dialog, *menu;
max_choice = MIN(menu_height, item_no);
+ tag_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center menu */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i*2]);
+ for (j = 0; j < item_no; j++) {
+ k = strlen(items[j*2 + 1]);
+ tag_x = MAX(tag_x, l + k + 2);
+ }
+ item_x = MAX(item_x, l);
+ }
+ if (height < 0)
+ height = strheight(prompt)+menu_height+4+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = strwidth(title);
+ width = MAX(i,j);
+ width = MAX(width,tag_x+4)+4;
+ }
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
@@ -96,13 +120,6 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid
/* draw a box around the menu items */
draw_box(dialog, box_y, box_x, menu_height+2, menu_width+2, menubox_border_attr, menubox_attr);
- tag_x = 0;
- item_x = 0;
- /* Find length of longest item in order to center menu */
- for (i = 0; i < item_no; i++) {
- tag_x = MAX(tag_x, strlen(items[i*2]) + strlen(items[i*2 + 1]) + 2);
- item_x = MAX(item_x, strlen(items[i*2]));
- }
tag_x = (menu_width - tag_x) / 2;
item_x = tag_x + item_x + 2;
diff --git a/gnu/lib/libdialog/msgbox.c b/gnu/lib/libdialog/msgbox.c
index e405f3b5a26a..50f6c13b2057 100644
--- a/gnu/lib/libdialog/msgbox.c
+++ b/gnu/lib/libdialog/msgbox.c
@@ -29,9 +29,21 @@
*/
int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause)
{
- int i, x, y, key = 0;
+ int i, j, x, y, key = 0;
WINDOW *dialog;
+ if (height < 0)
+ height = strheight(prompt)+2+2*(!!pause);
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = strwidth(title);
+ width = MAX(i,j)+4;
+ }
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
diff --git a/gnu/lib/libdialog/prgbox.c b/gnu/lib/libdialog/prgbox.c
index db825890a301..53275bfd704e 100644
--- a/gnu/lib/libdialog/prgbox.c
+++ b/gnu/lib/libdialog/prgbox.c
@@ -27,13 +27,22 @@
* Display a message box. Program will pause and display an "OK" button
* if the parameter 'pause' is non-zero.
*/
-int dialog_prgbox(unsigned char *title, const char *line, int height, int width, int pause, int use_shell)
+int dialog_prgbox(unsigned char *title, const unsigned char *line, int height, int width, int pause, int use_shell)
{
int i, x, y, key = 0;
WINDOW *dialog;
FILE *f;
unsigned char *s, buf[MAX_LEN];
+ if (height < 0 || width < 0) {
+ endwin();
+ fprintf(stderr, "\nAutosizing is impossible in dialog_prgbox().\n");
+ exit(-1);
+ }
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
diff --git a/gnu/lib/libdialog/radiolist.c b/gnu/lib/libdialog/radiolist.c
index 5a2151861d87..5b8a68fff56d 100644
--- a/gnu/lib/libdialog/radiolist.c
+++ b/gnu/lib/libdialog/radiolist.c
@@ -33,10 +33,10 @@ static int list_width, check_x, item_x;
/*
* Display a dialog box with a list of options that can be turned on or off
*/
-int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result)
+int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result)
{
- int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
- scroll = 0, max_choice, *status, was_on = 0;
+ int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ l, k, scroll = 0, max_choice, *status, was_on = 0;
WINDOW *dialog, *list;
/* Allocate space for storing item on/off status */
@@ -58,6 +58,30 @@ int dialog_radiolist(char *title, char *prompt, int height, int width, int list_
}
max_choice = MIN(list_height, item_no);
+ check_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center radiolist */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i*3]);
+ for (j = 0; j < item_no; j++) {
+ k = strlen(items[j*3 + 1]);
+ check_x = MAX(check_x, l + k + 6);
+ }
+ item_x = MAX(item_x, l);
+ }
+ if (height < 0)
+ height = strheight(prompt)+list_height+4+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = strwidth(title);
+ width = MAX(i,j);
+ width = MAX(width,check_x+4)+4;
+ }
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
@@ -114,13 +138,6 @@ int dialog_radiolist(char *title, char *prompt, int height, int width, int list_
/* draw a box around the list items */
draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
- check_x = 0;
- item_x = 0;
- /* Find length of longest item in order to center radiolist */
- for (i = 0; i < item_no; i++) {
- check_x = MAX(check_x, strlen(items[i*3]) + strlen(items[i*3 + 1]) + 6);
- item_x = MAX(item_x, strlen(items[i*3]));
- }
check_x = (list_width - check_x) / 2;
item_x = check_x + item_x + 6;
diff --git a/gnu/lib/libdialog/textbox.c b/gnu/lib/libdialog/textbox.c
index 670ea49fe32c..0479723e41b6 100644
--- a/gnu/lib/libdialog/textbox.c
+++ b/gnu/lib/libdialog/textbox.c
@@ -48,6 +48,12 @@ int dialog_textbox(unsigned char *title, unsigned char *file, int height, int wi
unsigned char search_term[MAX_LEN+1], *tempptr, *found;
WINDOW *dialog, *text;
+ if (height < 0 || width < 0) {
+ endwin();
+ fprintf(stderr, "\nAutosizing is impossible in dialog_textbox().\n");
+ exit(-1);
+ }
+
search_term[0] = '\0'; /* no search term entered yet */
/* Open input file for reading */
@@ -83,6 +89,10 @@ int dialog_textbox(unsigned char *title, unsigned char *file, int height, int wi
buf[bytes_read] = '\0'; /* mark end of valid data */
page = buf; /* page is pointer to start of page to be displayed */
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
@@ -641,13 +651,14 @@ static int get_search_term(WINDOW *win, unsigned char *search_term, int height,
wattrset(win, searchbox_title_attr);
wmove(win, y, x+box_width/2-4);
waddstr(win, " Search ");
+ wattrset(win, dialog_attr);
box_width -= 2;
search_term[0] = '\0';
first = 1;
while (key != ESC) {
- key = line_edit(win, y+1, x+1, box_width, searchbox_attr, first, search_term);
+ key = line_edit(win, y+1, x+1, -1, box_width, searchbox_attr, first, search_term);
first = 0;
switch (key) {
case '\n':
diff --git a/gnu/lib/libdialog/yesno.c b/gnu/lib/libdialog/yesno.c
index 3f21b5a7d585..8d253608e6bb 100644
--- a/gnu/lib/libdialog/yesno.c
+++ b/gnu/lib/libdialog/yesno.c
@@ -28,9 +28,21 @@
*/
int dialog_yesno(unsigned char *title, unsigned char * prompt, int height, int width)
{
- int i, x, y, key = 0, button = 0;
+ int i, j, x, y, key = 0, button = 0;
WINDOW *dialog;
+ if (height < 0)
+ height = strheight(prompt)+4;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = strwidth(title);
+ width = MAX(i,j)+4;
+ }
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
diff --git a/gnu/lib/libg++/Makefile b/gnu/lib/libg++/Makefile
index 7a7888a78398..007dc4ca00ec 100644
--- a/gnu/lib/libg++/Makefile
+++ b/gnu/lib/libg++/Makefile
@@ -1,16 +1,17 @@
#
-# $Id: Makefile,v 1.4 1994/09/10 07:15:59 pst Exp $
+# $FreeBSD$
#
-SRCS= vasprintf.c strerror.c strsignal.c
-SRCS+= filedoalloc.c floatconv.c genops.c fileops.c iovfprintf.c iovfscanf.c ioignore.c iopadn.c iofgetpos.c iofread.c iofscanf.c iofsetpos.c iogetline.c ioprintf.c ioseekoff.c ioseekpos.c outfloat.c strops.c iofclose.c iopopen.c ioungetc.c builtinbuf.cc filebuf.cc fstream.cc indstream.cc isgetline.cc isgetsb.cc isscan.cc ioextend.cc iomanip.cc iostream.cc osform.cc procbuf.cc sbform.cc sbgetline.cc sbscan.cc stdiostream.cc stdstrbufs.cc stdstreams.cc stream.cc streambuf.cc strstream.cc PlotFile.cc SFile.cc parsestream.cc pfstream.cc editbuf.cc ioprims.c iostrerror.c cleanup.c
-SRCS+= AllocRing.cc Obstack.cc builtin.cc regex.cc Regex.cc String.cc Intdouble.cc Integer.cc Rational.cc Complex.cc Random.cc BitSet.cc BitString.cc LogNorm.cc SmplHist.cc SmplStat.cc Normal.cc NegExp.cc Weibull.cc Erlang.cc DiscUnif.cc Uniform.cc Poisson.cc HypGeom.cc Geom.cc Binomial.cc RNG.cc ACG.cc MLCG.cc RndInt.cc Fix.cc Fix16.cc Fix24.cc CursesW.cc GetOpt.cc new.cc chr.cc error.cc gcd.cc hash.cc lg.cc fmtq.cc ioob.cc pow.cc sqrt.cc str.cc timer.c math.cc compare.cc bitand.c bitany.c bitblt.c bitclear.c bitcopy.c bitcount.c bitinvert.c bitlcomp.c bitset1.c bitxor.c SLList.cc DLList.cc
+SRCS= strerror.c strsignal.c
+SRCS+= filedoalloc.c floatconv.c genops.c fileops.c iovfprintf.c iovfscanf.c ioignore.c iopadn.c iofgetpos.c iofread.c iofscanf.c iofsetpos.c iogetdelim.c iogetline.c ioprintf.c ioseekoff.c ioseekpos.c outfloat.c strops.c iofclose.c iopopen.c ioungetc.c builtinbuf.cc filebuf.cc fstream.cc indstream.cc ioassign.cc ioextend.cc iomanip.cc iostream.cc isgetline.cc isgetsb.cc isscan.cc osform.cc procbuf.cc sbform.cc sbgetline.cc sbscan.cc stdiostream.cc stdstrbufs.cc stdstreams.cc stream.cc streambuf.cc strstream.cc PlotFile.cc SFile.cc parsestream.cc pfstream.cc editbuf.cc ioprims.c iostrerror.c cleanup.c
+SRCS+= AllocRing.cc Obstack.cc builtin.cc Regex.cc String.cc Intdouble.cc Integer.cc Rational.cc Complex.cc Random.cc BitSet.cc BitString.cc LogNorm.cc SmplHist.cc SmplStat.cc Normal.cc NegExp.cc Weibull.cc Erlang.cc DiscUnif.cc Uniform.cc Poisson.cc HypGeom.cc Geom.cc Binomial.cc RNG.cc ACG.cc MLCG.cc RndInt.cc Fix.cc Fix16.cc Fix24.cc CursesW.cc GetOpt.cc except.c new.cc chr.cc error.cc gcd.cc hash.cc lg.cc fmtq.cc ioob.cc pow.cc sqrt.cc str.cc timer.c math.cc compare.cc bitand.c bitany.c bitblt.c bitclear.c bitcopy.c bitcount.c bitinvert.c bitlcomp.c bitset1.c bitxor.c SLList.cc DLList.cc
+SRCS+= rx.c
LIB= g++
NOMAN= noman
CFLAGS+= -nostdinc -I${.CURDIR}/include -I/usr/include
-CXXFLAGS+= -fexternal-templates -I${.CURDIR}/include
-.PATH: ${.CURDIR}/libiberty ${.CURDIR}/libio ${.CURDIR}/libg++
-LDADD+= -lcurses
+CXXFLAGS+= -I${.CURDIR}/include -I/usr/include/g++ -I/usr/include -nostdinc++
+LDADD+= -lcurses
+.PATH: ${.CURDIR}/libiberty ${.CURDIR}/libio ${.CURDIR}/libg++ ${.CURDIR}/librx
beforeinstall:
@-if [ ! -d ${DESTDIR}/usr/include/g++ ]; then mkdir ${DESTDIR}/usr/include/g++; chown ${BINOWN}.${BINGRP} ${DESTDIR}/usr/include/g++; chmod 755 ${DESTDIR}/usr/include/g++; fi
diff --git a/gnu/lib/libg++/include/ACG.h b/gnu/lib/libg++/include/ACG.h
index d7101c785adb..809380050ba9 100644
--- a/gnu/lib/libg++/include/ACG.h
+++ b/gnu/lib/libg++/include/ACG.h
@@ -42,26 +42,26 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
class ACG : public RNG {
- unsigned long initialSeed; // used to reset generator
+ _G_uint32_t initialSeed; // used to reset generator
int initialTableEntry;
- unsigned long *state;
- unsigned long *auxState;
+ _G_uint32_t *state;
+ _G_uint32_t *auxState;
short stateSize;
short auxSize;
- unsigned long lcgRecurr;
+ _G_uint32_t lcgRecurr;
short j;
short k;
protected:
public:
- ACG(unsigned long seed = 0, int size = 55);
+ ACG(_G_uint32_t seed = 0, int size = 55);
virtual ~ACG();
//
// Return a long-words word of random bits
//
- virtual unsigned long asLong();
+ virtual _G_uint32_t asLong();
virtual void reset();
};
diff --git a/gnu/lib/libg++/include/Complex.h b/gnu/lib/libg++/include/Complex.h
index 385ea606d742..9b7e378ed383 100644
--- a/gnu/lib/libg++/include/Complex.h
+++ b/gnu/lib/libg++/include/Complex.h
@@ -87,33 +87,6 @@ Complex sqrt(const Complex& x);
istream& operator >> (istream& s, Complex& x);
ostream& operator << (ostream& s, const Complex& x);
-// other functions defined as inlines
-
-int operator == (const Complex& x, const Complex& y);
-int operator == (const Complex& x, double y);
-int operator != (const Complex& x, const Complex& y);
-int operator != (const Complex& x, double y);
-
-Complex operator - (const Complex& x);
-Complex conj(const Complex& x);
-Complex operator + (const Complex& x, const Complex& y);
-Complex operator + (const Complex& x, double y);
-Complex operator + (double x, const Complex& y);
-Complex operator - (const Complex& x, const Complex& y);
-Complex operator - (const Complex& x, double y);
-Complex operator - (double x, const Complex& y);
-Complex operator * (const Complex& x, const Complex& y);
-Complex operator * (const Complex& x, double y);
-Complex operator * (double x, const Complex& y);
-
-double real(const Complex& x);
-double imag(const Complex& x);
-double abs(const Complex& x);
-double norm(const Complex& x);
-double arg(const Complex& x);
-
-Complex polar(double r, double t = 0.0);
-
// inline members
diff --git a/gnu/lib/libg++/include/CursesW.h b/gnu/lib/libg++/include/CursesW.h
index 4f367fda8d1a..1df2e8a0aa41 100644
--- a/gnu/lib/libg++/include/CursesW.h
+++ b/gnu/lib/libg++/include/CursesW.h
@@ -25,7 +25,11 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#include <_G_config.h>
#if _G_HAVE_CURSES
+// Even many system which mostly have C++-ready header files,
+// do not have C++-ready curses.h.
+extern "C" {
#include <curses.h>
+}
/* SCO 3.2v4 curses.h includes term.h, which defines lines as a macro.
Undefine it here, because CursesWindow uses lines as a method. */
@@ -148,8 +152,9 @@ inline int (winch)(WINDOW* win) { return winch(win); }
/* deal with conflicting macros in ncurses.h which is SYSV based*/
#ifdef box
-inline (box)(WINDOW* win, chtype v, chtype h) {return box(win, v, h); }
+inline _G_box(WINDOW* win, chtype v, chtype h) {return box(win, v, h); }
#undef box
+inline box(WINDOW* win, chtype v, chtype h) {return _G_box(win, v, h); }
#endif
#ifdef scroll
inline (scroll)(WINDOW* win) { return scroll(win); }
diff --git a/gnu/lib/libg++/include/DLList.h b/gnu/lib/libg++/include/DLList.h
index 0c3adc2e74f5..36f73bcb4aab 100644
--- a/gnu/lib/libg++/include/DLList.h
+++ b/gnu/lib/libg++/include/DLList.h
@@ -66,9 +66,9 @@ class BaseDLList {
int empty() const { return h == 0; }
int length() const;
void clear();
- void error(const char* msg);
- int owns(Pix p);
- int OK();
+ void error(const char* msg) const;
+ int owns(Pix p) const;
+ int OK() const;
void del(Pix& p, int dir = 1);
void del_after(Pix& p);
void del_front();
@@ -104,6 +104,13 @@ class DLList : public BaseDLList {
if (h == 0) error("rear: empty list");
return ((DLNode<T>*)h->bk)->hd;
}
+ const T& front() const {
+ if (h == 0) error("front: empty list");
+ return ((DLNode<T>*)h)->hd; }
+ const T& rear() const {
+ if (h == 0) error("rear: empty list");
+ return ((DLNode<T>*)h->bk)->hd;
+ }
T remove_front() { T dst; BaseDLList::remove_front(&dst); return dst; }
T remove_rear() { T dst; BaseDLList::remove_rear(&dst); return dst; }
@@ -111,11 +118,15 @@ class DLList : public BaseDLList {
if (p == 0) error("null Pix");
return ((DLNode<T>*)p)->hd;
}
- Pix first() { return Pix(h); }
- Pix last() { return (h == 0)? 0 : Pix(h->bk); }
- void next(Pix& p)
+ const T& operator () (Pix p) const {
+ if (p == 0) error("null Pix");
+ return ((DLNode<T>*)p)->hd;
+ }
+ Pix first() const { return Pix(h); }
+ Pix last() const { return (h == 0) ? 0 : Pix(h->bk); }
+ void next(Pix& p) const
{ p = (p == 0 || p == h->bk)? 0 : Pix(((DLNode<T>*)p)->fd); }
- void prev(Pix& p)
+ void prev(Pix& p) const
{ p = (p == 0 || p == h)? 0 : Pix(((DLNode<T>*)p)->bk); }
Pix ins_after(Pix p, const T& item)
{return BaseDLList::ins_after(p, &item); }
diff --git a/gnu/lib/libg++/include/Fix16.h b/gnu/lib/libg++/include/Fix16.h
index 36728b40ce13..e598113ede88 100644
--- a/gnu/lib/libg++/include/Fix16.h
+++ b/gnu/lib/libg++/include/Fix16.h
@@ -40,11 +40,11 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#define Fix16_min (-1.)
-#define Fix32_fs ((double)((unsigned long)(1 << 31)))
+#define Fix32_fs ((double)((_G_uint32_t)(1 << 31)))
-#define Fix32_msb ((unsigned long)(1 << 31))
-#define Fix32_m_max ((long)((1 << 31) - 1))
-#define Fix32_m_min ((long)(1 << 31))
+#define Fix32_msb ((_G_uint32_t)(1 << 31))
+#define Fix32_m_max ((_G_int32_t)((1 << 31) - 1))
+#define Fix32_m_min ((_G_int32_t)(1 << 31))
#define Fix32_mult Fix32_fs
#define Fix32_div (1./Fix32_fs)
@@ -135,12 +135,12 @@ class Fix32
{
friend class Fix16;
- long m;
+ _G_int32_t m;
- long round(double d);
- long assign(double d);
+ _G_int32_t round(double d);
+ _G_int32_t assign(double d);
- Fix32(long i);
+ Fix32(_G_int32_t i);
operator double() const;
@@ -155,8 +155,8 @@ public:
Fix32& operator = (const Fix16& f);
Fix32& operator = (double d);
- friend long& mantissa(Fix32& f);
- friend const long& mantissa(const Fix32& f);
+ friend _G_int32_t& mantissa(Fix32& f);
+ friend const _G_int32_t& mantissa(const Fix32& f);
friend double value(const Fix32& f);
Fix32 operator + () const;
@@ -188,8 +188,8 @@ public:
friend istream& operator >> (istream& s, Fix32& f);
friend ostream& operator << (ostream& s, const Fix32& f);
- void overflow(long& i) const;
- void range_error(long& i) const;
+ void overflow(_G_int32_t& i) const;
+ void range_error(_G_int32_t& i) const;
friend Fix32 operator * (const Fix32& f, int g);
friend Fix32 operator * (int g, const Fix32& f);
@@ -199,7 +199,7 @@ public:
// active error handler declarations
typedef void (*Fix16_peh)(short&);
-typedef void (*Fix32_peh)(long&);
+typedef void (*Fix32_peh)(_G_int32_t&);
extern Fix16_peh Fix16_overflow_handler;
extern Fix32_peh Fix32_overflow_handler;
@@ -231,11 +231,11 @@ extern void
Fix16_abort(short&);
extern void
- Fix32_ignore(long&),
- Fix32_overflow_saturate(long&),
- Fix32_overflow_warning_saturate(long&),
- Fix32_warning(long&),
- Fix32_abort(long&);
+ Fix32_ignore(_G_int32_t&),
+ Fix32_overflow_saturate(_G_int32_t&),
+ Fix32_overflow_warning_saturate(_G_int32_t&),
+ Fix32_warning(_G_int32_t&),
+ Fix32_abort(_G_int32_t&);
inline Fix16::~Fix16() {}
@@ -294,7 +294,7 @@ inline Fix32::Fix32()
m = 0;
}
-inline Fix32::Fix32(long i)
+inline Fix32::Fix32(_G_int32_t i)
{
m = i;
}
@@ -312,7 +312,7 @@ inline Fix32::Fix32(const Fix32& f)
inline Fix32::Fix32(const Fix16& f)
{
- m = long(f.m) << 16;
+ m = _G_int32_t(f.m) << 16;
}
inline Fix32::Fix32(double d)
@@ -340,7 +340,7 @@ inline Fix32& Fix32::operator=(const Fix32& f)
inline Fix32& Fix32::operator=(const Fix16& f)
{
- m = long(f.m) << 16;
+ m = _G_int32_t(f.m) << 16;
return *this;
}
@@ -393,7 +393,7 @@ inline Fix16 operator-(const Fix16& f, const Fix16& g)
inline Fix32 operator*(const Fix16& f, const Fix16& g)
{
- return Fix32( long( long(f.m) * long(g.m) << 1));
+ return Fix32( _G_int32_t( _G_int32_t(f.m) * _G_int32_t(g.m) << 1));
}
inline Fix16 operator<<(const Fix16& a, int b)
@@ -498,17 +498,17 @@ inline Fix16& Fix16::operator*=(int g)
inline Fix32::~Fix32() {}
-inline long Fix32::round(double d)
+inline _G_int32_t Fix32::round(double d)
{
- return long( (d >= 0)? d + 0.5 : d - 0.5);
+ return _G_int32_t( (d >= 0)? d + 0.5 : d - 0.5);
}
-inline long& mantissa(Fix32& f)
+inline _G_int32_t& mantissa(Fix32& f)
{
return f.m;
}
-inline const long& mantissa(const Fix32& f)
+inline const _G_int32_t& mantissa(const Fix32& f)
{
return f.m;
}
@@ -530,7 +530,7 @@ inline Fix32 Fix32::operator-() const
inline Fix32 operator+(const Fix32& f, const Fix32& g)
{
- long sum = f.m + g.m;
+ _G_int32_t sum = f.m + g.m;
if ( (f.m ^ sum) & (g.m ^ sum) & Fix32_msb )
f.overflow(sum);
return sum;
@@ -538,7 +538,7 @@ inline Fix32 operator+(const Fix32& f, const Fix32& g)
inline Fix32 operator-(const Fix32& f, const Fix32& g)
{
- long sum = f.m - g.m;
+ _G_int32_t sum = f.m - g.m;
if ( (f.m ^ sum) & (-g.m ^ sum) & Fix32_msb )
f.overflow(sum);
return sum;
@@ -630,7 +630,7 @@ inline ostream& operator<<(ostream& s, const Fix32& f)
inline Fix32 operator*(const Fix32& f, int g)
{
- return Fix32(long(f.m * g));
+ return Fix32(_G_int32_t(f.m * g));
}
inline Fix32 operator*(int g, const Fix32& f)
diff --git a/gnu/lib/libg++/include/Fix24.h b/gnu/lib/libg++/include/Fix24.h
index 56d11910206a..5db346e36896 100644
--- a/gnu/lib/libg++/include/Fix24.h
+++ b/gnu/lib/libg++/include/Fix24.h
@@ -29,8 +29,8 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
// extra type definitions
typedef struct {
- long u;
- unsigned long l;
+ _G_int32_t u;
+ _G_uint32_t l;
} twolongs;
// constant definitions
@@ -45,7 +45,7 @@ static const double
Fix24_max = 1. - .5/Fix24_fs,
Fix24_min = -1.;
-static const unsigned long
+static const _G_uint32_t
Fix24_msb = 0x80000000L,
Fix24_lsb = 0x00000100L,
Fix24_m_max = 0x7fffff00L,
@@ -74,9 +74,9 @@ class Fix24
{
friend class Fix48;
- long m;
+ _G_int32_t m;
- long assign(double d);
+ _G_int32_t assign(double d);
operator double() const;
Fix24(long i);
Fix24(int i);
@@ -94,8 +94,8 @@ public:
Fix24& operator=(double d);
Fix24& operator=(const Fix48& f);
- friend long& mantissa(Fix24& f);
- friend const long& mantissa(const Fix24& f);
+ friend _G_int32_t& mantissa(Fix24& f);
+ friend const _G_int32_t& mantissa(const Fix24& f);
friend double value(const Fix24& f);
Fix24 operator + () const;
@@ -129,8 +129,8 @@ public:
friend istream& operator >> (istream& s, Fix24& f);
friend ostream& operator << (ostream& s, const Fix24& f);
- void overflow(long&) const;
- void range_error(long&) const;
+ void overflow(_G_int32_t&) const;
+ void range_error(_G_int32_t&) const;
};
@@ -200,7 +200,7 @@ public:
// active error handler declarations
-typedef void (*Fix24_peh)(long&);
+typedef void (*Fix24_peh)(_G_int32_t&);
typedef void (*Fix48_peh)(twolongs&);
extern Fix24_peh Fix24_overflow_handler;
@@ -226,11 +226,11 @@ extern Fix48_peh set_Fix48_range_error_handler(Fix48_peh);
extern void set_range_error_handler(Fix24_peh, Fix48_peh);
extern void
- Fix24_ignore(long&),
- Fix24_overflow_saturate(long&),
- Fix24_overflow_warning_saturate(long&),
- Fix24_warning(long&),
- Fix24_abort(long&);
+ Fix24_ignore(_G_int32_t&),
+ Fix24_overflow_saturate(_G_int32_t&),
+ Fix24_overflow_warning_saturate(_G_int32_t&),
+ Fix24_warning(_G_int32_t&),
+ Fix24_abort(_G_int32_t&);
extern void
Fix48_ignore(twolongs&),
@@ -295,12 +295,12 @@ inline Fix24& Fix24::operator=(const Fix48& f)
return *this;
}
-inline long& mantissa(Fix24& f)
+inline _G_int32_t& mantissa(Fix24& f)
{
return f.m;
}
-inline const long& mantissa(const Fix24& f)
+inline const _G_int32_t& mantissa(const Fix24& f)
{
return f.m;
}
@@ -322,7 +322,7 @@ inline Fix24 Fix24::operator-() const
inline Fix24 operator+(const Fix24& f, const Fix24& g)
{
- long sum = f.m + g.m;
+ _G_int32_t sum = f.m + g.m;
if ( (f.m ^ sum) & (g.m ^ sum) & Fix24_msb )
f.overflow(sum);
return sum;
@@ -330,7 +330,7 @@ inline Fix24 operator+(const Fix24& f, const Fix24& g)
inline Fix24 operator-(const Fix24& f, const Fix24& g)
{
- long sum = f.m - g.m;
+ _G_int32_t sum = f.m - g.m;
if ( (f.m ^ sum) & (-g.m ^ sum) & Fix24_msb )
f.overflow(sum);
return sum;
@@ -353,7 +353,7 @@ inline Fix24 operator<<(const Fix24& a, int b)
inline Fix24 operator>>(const Fix24& a, int b)
{
- return (a.m >> b) & (long)0xffffff00;
+ return (a.m >> b) & ~0xff;
}
inline Fix24& Fix24:: operator+=(const Fix24& f)
@@ -448,7 +448,7 @@ inline Fix48:: operator double() const
* m.u is signed and m.l is unsigned.
*/
return (m.u >= 0)? Fix48_div_u * m.u + Fix48_div_l * m.l :
- (Fix48_div_u * ((unsigned long)(m.u & 0xffffff00))
+ (Fix48_div_u * ((_G_uint32_t)(m.u & 0xffffff00))
+ Fix48_div_l * m.l) - 2;
}
diff --git a/gnu/lib/libg++/include/MLCG.h b/gnu/lib/libg++/include/MLCG.h
index 8f104a1a8e39..8fa08a856fe0 100644
--- a/gnu/lib/libg++/include/MLCG.h
+++ b/gnu/lib/libg++/include/MLCG.h
@@ -41,7 +41,7 @@ public:
//
// Return a long-words word of random bits
//
- virtual unsigned long asLong();
+ virtual _G_uint32_t asLong();
virtual void reset();
_G_int32_t seed1();
void seed1(_G_int32_t);
diff --git a/gnu/lib/libg++/include/RNG.h b/gnu/lib/libg++/include/RNG.h
index 43d95b767c21..b924fb697c34 100644
--- a/gnu/lib/libg++/include/RNG.h
+++ b/gnu/lib/libg++/include/RNG.h
@@ -46,7 +46,7 @@ public:
//
// Return a long-words word of random bits
//
- virtual unsigned long asLong() = 0;
+ virtual _G_uint32_t asLong() = 0;
virtual void reset() = 0;
//
// Return random bits converted to either a float or a double
diff --git a/gnu/lib/libg++/include/SLList.h b/gnu/lib/libg++/include/SLList.h
index c613674552f3..8c133d7ebf6d 100644
--- a/gnu/lib/libg++/include/SLList.h
+++ b/gnu/lib/libg++/include/SLList.h
@@ -64,10 +64,10 @@ class BaseSLList {
void clear();
Pix prepend(BaseSLNode*);
Pix append(BaseSLNode*);
- int OK();
- void error(const char* msg);
+ int OK() const;
+ void error(const char* msg) const;
void del_after(Pix p);
- int owns(Pix p);
+ int owns(Pix p) const;
void del_front();
};
@@ -95,9 +95,12 @@ public:
T& operator () (Pix p) {
if (p == 0) error("null Pix");
return ((SLNode<T>*)(p))->hd; }
- inline Pix first() { return (last == 0)? 0 : Pix(last->tl); }
- void next(Pix& p)
- { p = (p == 0 || p == last)? 0 : Pix(((SLNode<T>*)(p))->tl); }
+ const T& operator () (Pix p) const {
+ if (p == 0) error("null Pix");
+ return ((SLNode<T>*)(p))->hd; }
+ inline Pix first() const { return (last == 0) ? 0 : Pix(last->tl); }
+ void next(Pix& p) const
+ { p = (p == 0 || p == last) ? 0 : Pix(((SLNode<T>*)(p))->tl); }
Pix ins_after(Pix p, const T& item)
{ return BaseSLList::ins_after(p, &item); }
void join(SLList<T>& a) { BaseSLList::join(a); }
@@ -108,6 +111,12 @@ public:
T& rear() {
if (last == 0) error("rear: empty list");
return ((SLNode<T>*)last)->hd; }
+ const T& front() const {
+ if (last == 0) error("front: empty list");
+ return ((SLNode<T>*)last->tl)->hd; }
+ const T& rear() const {
+ if (last == 0) error("rear: empty list");
+ return ((SLNode<T>*)last)->hd; }
int remove_front(T& x) { return BaseSLList::remove_front(&x); }
T remove_front() { T dst; BaseSLList::remove_front(&dst, 1); return dst; }
};
diff --git a/gnu/lib/libg++/include/String.h b/gnu/lib/libg++/include/String.h
index 9537ba659f6d..95b2bdf9e67d 100644
--- a/gnu/lib/libg++/include/String.h
+++ b/gnu/lib/libg++/include/String.h
@@ -39,7 +39,6 @@ struct StrRep // internal String representations
StrRep* Salloc(StrRep*, const char*, int, int);
StrRep* Scopy(StrRep*, const StrRep*);
-StrRep* Sresize(StrRep*, int);
StrRep* Scat(StrRep*, const char*, int, const char*, int);
StrRep* Scat(StrRep*, const char*, int,const char*,int, const char*,int);
StrRep* Sprepend(StrRep*, const char*, int);
@@ -155,50 +154,50 @@ public:
// procedural versions:
// concatenate first 2 args, store result in last arg
- friend void cat(const String&, const String&, String&);
- friend void cat(const String&, const SubString&, String&);
- friend void cat(const String&, const char*, String&);
- friend void cat(const String&, char, String&);
+ friend inline void cat(const String&, const String&, String&);
+ friend inline void cat(const String&, const SubString&, String&);
+ friend inline void cat(const String&, const char*, String&);
+ friend inline void cat(const String&, char, String&);
- friend void cat(const SubString&, const String&, String&);
- friend void cat(const SubString&, const SubString&, String&);
- friend void cat(const SubString&, const char*, String&);
- friend void cat(const SubString&, char, String&);
+ friend inline void cat(const SubString&, const String&, String&);
+ friend inline void cat(const SubString&, const SubString&, String&);
+ friend inline void cat(const SubString&, const char*, String&);
+ friend inline void cat(const SubString&, char, String&);
- friend void cat(const char*, const String&, String&);
- friend void cat(const char*, const SubString&, String&);
- friend void cat(const char*, const char*, String&);
- friend void cat(const char*, char, String&);
+ friend inline void cat(const char*, const String&, String&);
+ friend inline void cat(const char*, const SubString&, String&);
+ friend inline void cat(const char*, const char*, String&);
+ friend inline void cat(const char*, char, String&);
// double concatenation, by request. (yes, there are too many versions,
// but if one is supported, then the others should be too...)
// Concatenate first 3 args, store in last arg
- friend void cat(const String&,const String&, const String&,String&);
- friend void cat(const String&,const String&,const SubString&,String&);
- friend void cat(const String&,const String&, const char*, String&);
- friend void cat(const String&,const String&, char, String&);
- friend void cat(const String&,const SubString&,const String&,String&);
- friend void cat(const String&,const SubString&,const SubString&,String&);
- friend void cat(const String&,const SubString&, const char*, String&);
- friend void cat(const String&,const SubString&, char, String&);
- friend void cat(const String&,const char*, const String&, String&);
- friend void cat(const String&,const char*, const SubString&, String&);
- friend void cat(const String&,const char*, const char*, String&);
- friend void cat(const String&,const char*, char, String&);
-
- friend void cat(const char*, const String&, const String&,String&);
- friend void cat(const char*,const String&,const SubString&,String&);
- friend void cat(const char*,const String&, const char*, String&);
- friend void cat(const char*,const String&, char, String&);
- friend void cat(const char*,const SubString&,const String&,String&);
- friend void cat(const char*,const SubString&,const SubString&,String&);
- friend void cat(const char*,const SubString&, const char*, String&);
- friend void cat(const char*,const SubString&, char, String&);
- friend void cat(const char*,const char*, const String&, String&);
- friend void cat(const char*,const char*, const SubString&, String&);
- friend void cat(const char*,const char*, const char*, String&);
- friend void cat(const char*,const char*, char, String&);
+ friend inline void cat(const String&,const String&, const String&,String&);
+ friend inline void cat(const String&,const String&,const SubString&,String&);
+ friend inline void cat(const String&,const String&, const char*, String&);
+ friend inline void cat(const String&,const String&, char, String&);
+ friend inline void cat(const String&,const SubString&,const String&,String&);
+ inline friend void cat(const String&,const SubString&,const SubString&,String&);
+ friend inline void cat(const String&,const SubString&, const char*, String&);
+ friend inline void cat(const String&,const SubString&, char, String&);
+ friend inline void cat(const String&,const char*, const String&, String&);
+ friend inline void cat(const String&,const char*, const SubString&, String&);
+ friend inline void cat(const String&,const char*, const char*, String&);
+ friend inline void cat(const String&,const char*, char, String&);
+
+ friend inline void cat(const char*, const String&, const String&,String&);
+ friend inline void cat(const char*,const String&,const SubString&,String&);
+ friend inline void cat(const char*,const String&, const char*, String&);
+ friend inline void cat(const char*,const String&, char, String&);
+ friend inline void cat(const char*,const SubString&,const String&,String&);
+ friend inline void cat(const char*,const SubString&,const SubString&,String&);
+ friend inline void cat(const char*,const SubString&, const char*, String&);
+ friend inline void cat(const char*,const SubString&, char, String&);
+ friend inline void cat(const char*,const char*, const String&, String&);
+ friend inline void cat(const char*,const char*, const SubString&, String&);
+ friend inline void cat(const char*,const char*, const char*, String&);
+ friend inline void cat(const char*,const char*, char, String&);
// searching & matching
@@ -327,10 +326,10 @@ public:
// simple builtin transformations
- friend String reverse(const String& x);
- friend String upcase(const String& x);
- friend String downcase(const String& x);
- friend String capitalize(const String& x);
+ friend inline String reverse(const String& x);
+ friend inline String upcase(const String& x);
+ friend inline String downcase(const String& x);
+ friend inline String capitalize(const String& x);
// in-place versions of above
@@ -342,6 +341,7 @@ public:
// element extraction
char& operator [] (int i);
+ const char& operator [] (int i) const;
char elem(int i) const;
char firstchar() const;
char lastchar() const;
@@ -354,7 +354,7 @@ public:
// IO
- friend ostream& operator<<(ostream& s, const String& x);
+ friend inline ostream& operator<<(ostream& s, const String& x);
friend ostream& operator<<(ostream& s, const SubString& x);
friend istream& operator>>(istream& s, String& x);
@@ -395,64 +395,12 @@ int fcompare(const String& x, const String& y); // ignore case
extern StrRep _nilStrRep;
extern String _nilString;
-// other inlines
-
-String operator + (const String& x, const String& y);
-String operator + (const String& x, const SubString& y);
-String operator + (const String& x, const char* y);
-String operator + (const String& x, char y);
-String operator + (const SubString& x, const String& y);
-String operator + (const SubString& x, const SubString& y);
-String operator + (const SubString& x, const char* y);
-String operator + (const SubString& x, char y);
-String operator + (const char* x, const String& y);
-String operator + (const char* x, const SubString& y);
-
-int operator==(const String& x, const String& y);
-int operator!=(const String& x, const String& y);
-int operator> (const String& x, const String& y);
-int operator>=(const String& x, const String& y);
-int operator< (const String& x, const String& y);
-int operator<=(const String& x, const String& y);
-int operator==(const String& x, const SubString& y);
-int operator!=(const String& x, const SubString& y);
-int operator> (const String& x, const SubString& y);
-int operator>=(const String& x, const SubString& y);
-int operator< (const String& x, const SubString& y);
-int operator<=(const String& x, const SubString& y);
-int operator==(const String& x, const char* t);
-int operator!=(const String& x, const char* t);
-int operator> (const String& x, const char* t);
-int operator>=(const String& x, const char* t);
-int operator< (const String& x, const char* t);
-int operator<=(const String& x, const char* t);
-int operator==(const SubString& x, const String& y);
-int operator!=(const SubString& x, const String& y);
-int operator> (const SubString& x, const String& y);
-int operator>=(const SubString& x, const String& y);
-int operator< (const SubString& x, const String& y);
-int operator<=(const SubString& x, const String& y);
-int operator==(const SubString& x, const SubString& y);
-int operator!=(const SubString& x, const SubString& y);
-int operator> (const SubString& x, const SubString& y);
-int operator>=(const SubString& x, const SubString& y);
-int operator< (const SubString& x, const SubString& y);
-int operator<=(const SubString& x, const SubString& y);
-int operator==(const SubString& x, const char* t);
-int operator!=(const SubString& x, const char* t);
-int operator> (const SubString& x, const char* t);
-int operator>=(const SubString& x, const char* t);
-int operator< (const SubString& x, const char* t);
-int operator<=(const SubString& x, const char* t);
-
-
// status reports, needed before defining other things
inline unsigned int String::length() const { return rep->len; }
inline int String::empty() const { return rep->len == 0; }
inline const char* String::chars() const { return &(rep->s[0]); }
inline int String::allocation() const { return rep->sz; }
-inline void String::alloc(int newsize) { rep = Sresize(rep, newsize); }
inline unsigned int SubString::length() const { return len; }
inline int SubString::empty() const { return len == 0; }
@@ -948,6 +896,12 @@ inline char& String::operator [] (int i)
return rep->s[i];
}
+inline const char& String::operator [] (int i) const
+{
+ if (((unsigned)i) >= length()) error("invalid index");
+ return rep->s[i];
+}
+
inline char String::elem (int i) const
{
if (((unsigned)i) >= length()) error("invalid index");
diff --git a/gnu/lib/libg++/include/_G_config.h b/gnu/lib/libg++/include/_G_config.h
index 01a178795104..1e5e28dfd6ab 100644
--- a/gnu/lib/libg++/include/_G_config.h
+++ b/gnu/lib/libg++/include/_G_config.h
@@ -1,15 +1,10 @@
/* AUTOMATICALLY GENERATED; DO NOT EDIT! */
-#ifndef _G_config_h
-/*
- * XXX This #include added by hand, it SHOULD NOT be here, but we do
- * not currently have the tools that Automatically generate this file and must
- * resort to this hackery to make it compile under FreeBSD 2.X
- */
#include <sys/types.h>
+#ifndef _G_config_h
#define _G_config_h
-#define _G_LIB_VERSION "0.65"
+#define _G_LIB_VERSION "0.66"
#define _G_NAMES_HAVE_UNDERSCORE 1
-#define _G_VTABLE_LABEL_HAS_LENGTH 0
+#define _G_VTABLE_LABEL_HAS_LENGTH 1
#define _G_VTABLE_LABEL_PREFIX "__vt$"
#define _G_HAVE_ST_BLKSIZE 1
typedef unsigned long _G_clock_t;
@@ -37,7 +32,7 @@ typedef unsigned long _G_uid_t;
#endif
typedef __WCHAR_TYPE__ _G_wchar_t;
typedef int _G_ssize_t;
-typedef int _G_wint_t;
+typedef int /* default */ _G_wint_t;
typedef char* /* default */ _G_va_list;
#define _G_signal_return_type void
#define _G_sprintf_return_type int
@@ -61,9 +56,12 @@ typedef unsigned _G_uint64_t;
#else
#define _G_ARGS(ARGLIST) ()
#endif
-#if defined (__GNUG__) && defined (__STRICT_ANSI__)
+#if !defined (__GNUG__) || defined (__STRICT_ANSI__)
#define _G_NO_NRV
#endif
+#if !defined (__GNUG__)
+#define _G_NO_EXTERN_TEMPLATES
+#endif
#define _G_HAVE_ATEXIT 1
#define _G_HAVE_SYS_RESOURCE 0
#define _G_HAVE_SYS_SOCKET 1
@@ -72,5 +70,5 @@ typedef unsigned _G_uint64_t;
#define _G_HAVE_DIRENT 1
#define _G_HAVE_CURSES 1
#define _G_MATH_H_INLINES 0
-#define _G_HAVE_BOOL 0
+#define _G_HAVE_BOOL 1
#endif /* !_G_config_h */
diff --git a/gnu/lib/libg++/include/bitprims.h b/gnu/lib/libg++/include/bitprims.h
index 771acd9a5f5c..24b30512f42f 100644
--- a/gnu/lib/libg++/include/bitprims.h
+++ b/gnu/lib/libg++/include/bitprims.h
@@ -122,4 +122,4 @@ extern void _BS_xor __P((_BS_word*,int, const _BS_word*,int, _BS_size_t));
}
#endif
-#endif _BS_PRIMS
+#endif /* !_BS_PRIMS */
diff --git a/gnu/lib/libg++/include/builtin.h b/gnu/lib/libg++/include/builtin.h
index 7f8299c2f52e..73bb43187dde 100644
--- a/gnu/lib/libg++/include/builtin.h
+++ b/gnu/lib/libg++/include/builtin.h
@@ -64,21 +64,6 @@ extern two_arg_error_handler_t
set_lib_error_handler(two_arg_error_handler_t f);
-double abs(double arg);
-float abs(float arg);
-short abs(short arg);
-long abs(long arg);
-int sign(long arg);
-int sign(double arg);
-long sqr(long arg);
-double sqr(double arg);
-int even(long arg);
-int odd(long arg);
-long lcm(long x, long y);
-void (setbit)(long& x, long b);
-void clearbit(long& x, long b);
-int testbit(long x, long b);
-
#if !defined(IV)
#if ! _G_MATH_H_INLINES /* hpux and SCO define this in math.h */
diff --git a/gnu/lib/libg++/include/defines.h b/gnu/lib/libg++/include/defines.h
index ddb76e9e1cb4..0f2fb3be4f37 100644
--- a/gnu/lib/libg++/include/defines.h
+++ b/gnu/lib/libg++/include/defines.h
@@ -30,4 +30,6 @@ typedef void fvoid_t();
typedef _G_wint_t wint_t;
#endif
+enum capacity { default_size, reserve };
+
#endif
diff --git a/gnu/lib/libg++/include/iolibio.h b/gnu/lib/libg++/include/iolibio.h
index 2a7c145e8e33..08040fa4e10e 100644
--- a/gnu/lib/libg++/include/iolibio.h
+++ b/gnu/lib/libg++/include/iolibio.h
@@ -3,6 +3,10 @@
/* These emulate stdio functionality, but with a different name
(_IO_ungetc instead of ungetc), and using _IO_FILE instead of FILE. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern int _IO_fclose __P((_IO_FILE*));
extern _IO_FILE *_IO_fdopen __P((int, const char*));
extern int _IO_fflush __P((_IO_FILE*));
@@ -17,6 +21,7 @@ extern _IO_size_t _IO_fwrite __P((const void*,
_IO_size_t, _IO_size_t, _IO_FILE*));
extern char* _IO_gets __P((char*));
extern void _IO_perror __P((const char*));
+extern int _IO_printf __P((const char*, ...));
extern int _IO_puts __P((const char*));
extern int _IO_scanf __P((const char*, ...));
extern void _IO_setbuffer __P((_IO_FILE *, char*, _IO_size_t));
@@ -30,8 +35,6 @@ extern int _IO_vsprintf __P((char*, const char*, _IO_va_list));
#define _IO_pos_BAD ((_IO_fpos_t)(-1))
#endif
#define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN))
-#define _IO_feof(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
-#define _IO_ferror(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
#define _IO_fseek(__fp, __offset, __whence) \
(_IO_seekoff(__fp, __offset, (_IO_off_t)(__whence)) == _IO_pos_BAD ? EOF : 0)
#define _IO_rewind(FILE) (void)_IO_seekoff(FILE, 0, 0)
@@ -44,3 +47,6 @@ extern _IO_FILE* _IO_popen __P((const char*, const char*));
#define _IO_setbuf(_FP, _BUF) _IO_setbuffer(_FP, _BUF, _IO_BUFSIZ)
#define _IO_setlinebuf(_FP) _IO_setvbuf(_FP, NULL, 1, 0)
+#ifdef __cplusplus
+}
+#endif
diff --git a/gnu/lib/libg++/include/iomanip.h b/gnu/lib/libg++/include/iomanip.h
index cab4b977138b..bf3d6f46c06b 100644
--- a/gnu/lib/libg++/include/iomanip.h
+++ b/gnu/lib/libg++/include/iomanip.h
@@ -130,7 +130,7 @@ public:
omanip(ostream& (*f)(ostream&, TP), TP a) : _f(f), _a(a) {}
//
friend
- ostream& operator<<(ostream& o, omanip<TP>& m)
+ ostream& operator<<(ostream& o, const omanip<TP>& m)
{ return (*m._f)(o, m._a); }
};
diff --git a/gnu/lib/libg++/include/iostream.h b/gnu/lib/libg++/include/iostream.h
index 7348ce22d98f..e370be2725a9 100644
--- a/gnu/lib/libg++/include/iostream.h
+++ b/gnu/lib/libg++/include/iostream.h
@@ -92,6 +92,7 @@ class ostream : virtual public ios
#endif
ostream& operator<<(double n);
ostream& operator<<(float n) { return operator<<((double)n); }
+ ostream& operator<<(long double n) { return operator<<((double)n); }
ostream& operator<<(__omanip func) { return (*func)(*this); }
ostream& operator<<(__manip func) {(*func)(*this); return *this;}
ostream& operator<<(streambuf*);
@@ -103,6 +104,7 @@ class ostream : virtual public ios
class istream : virtual public ios
{
// NOTE: If fields are changed, you must fix _fake_istream in stdstreams.C!
+protected:
_IO_size_t _gcount;
int _skip_ws();
@@ -198,22 +200,32 @@ class istream : virtual public ios
#endif
istream& operator>>(float&);
istream& operator>>(double&);
+ istream& operator>>(long double&);
istream& operator>>( __manip func) {(*func)(*this); return *this;}
istream& operator>>(__imanip func) { return (*func)(*this); }
istream& operator>>(streambuf*);
};
-
class iostream : public istream, public ostream
{
- _IO_size_t _gcount;
public:
- iostream() { _gcount = 0; }
+ iostream() { }
iostream(streambuf* sb, ostream*tied=NULL);
};
-extern istream cin;
-extern ostream cout, cerr, clog; // clog->rdbuf() == cerr->rdbuf()
+class _IO_istream_withassign : public istream {
+public:
+ _IO_istream_withassign& operator=(istream&);
+};
+
+class _IO_ostream_withassign : public ostream {
+public:
+ _IO_ostream_withassign& operator=(ostream&);
+};
+
+extern _IO_istream_withassign cin;
+// clog->rdbuf() == cerr->rdbuf()
+extern _IO_ostream_withassign cout, cerr, clog;
struct Iostream_init { } ; // Compatibility hack for AT&T library.
diff --git a/gnu/lib/libg++/include/libiberty.h b/gnu/lib/libg++/include/libiberty.h
index 9854b4c397e5..0a71c527862f 100644
--- a/gnu/lib/libg++/include/libiberty.h
+++ b/gnu/lib/libg++/include/libiberty.h
@@ -61,6 +61,13 @@ extern int strtoerrno PARAMS ((const char *));
extern int signo_max PARAMS ((void));
+/* Return a signal message string for a signal number
+ (e.g., strsignal (SIGHUP) returns something like "Hangup"). */
+/* This is commented out as it can conflict with one in system headers.
+ We still document its existence though. */
+
+/*extern const char *strsignal PARAMS ((int));*/
+
/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
"SIGHUP"). */
diff --git a/gnu/lib/libg++/include/libio.h b/gnu/lib/libg++/include/libio.h
index a06419722948..8a9c25beee0c 100644
--- a/gnu/lib/libg++/include/libio.h
+++ b/gnu/lib/libg++/include/libio.h
@@ -73,7 +73,7 @@ typedef _IO_fpos_t _IO_pos_t;
#ifndef __STDC__
#define const
#endif
-#define USE_DTOA
+#define _IO_USE_DTOA
#if 0
#ifdef _IO_NEED_STDARG_H
@@ -236,6 +236,9 @@ extern unsigned __adjust_column __P((unsigned start, const char *line, int count
? __overflow(_fp, (unsigned char)(_ch)) \
: (unsigned char)(*(_fp)->_IO_write_ptr++ = (_ch)))
+#define _IO_feof(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
+#define _IO_ferror(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
+
/* This one is for Emacs. */
#define _IO_PENDING_OUTPUT_COUNT(_fp) \
((_fp)->_IO_write_ptr - (_fp)->_IO_write_base)
diff --git a/gnu/lib/libg++/include/libioP.h b/gnu/lib/libg++/include/libioP.h
index 11d90f56f09d..ca870479671f 100644
--- a/gnu/lib/libg++/include/libioP.h
+++ b/gnu/lib/libg++/include/libioP.h
@@ -146,9 +146,9 @@ extern struct _IO_jump_t _IO_streambuf_jumps;
extern struct _IO_jump_t _IO_proc_jumps;
extern struct _IO_jump_t _IO_str_jumps;
extern int _IO_do_write __P((_IO_FILE*, const char*, _IO_size_t));
-extern int _IO_flush_all __P(());
-extern void _IO_cleanup __P(());
-extern void _IO_flush_all_linebuffered __P(());
+extern int _IO_flush_all __P((void));
+extern void _IO_cleanup __P((void));
+extern void _IO_flush_all_linebuffered __P((void));
#define _IO_do_flush(_f) \
_IO_do_write(_f, (_f)->_IO_write_base, \
@@ -205,6 +205,7 @@ extern void _IO_str_init_readonly __P((_IO_FILE *, const char*, int));
extern _IO_ssize_t _IO_str_count __P ((_IO_FILE*));
extern _IO_size_t _IO_getline __P((_IO_FILE*,char*,_IO_size_t,int,int));
+extern _IO_ssize_t _IO_getdelim __P((char**, _IO_size_t*, int, _IO_FILE*));
extern double _IO_strtod __P((const char *, char **));
extern char * _IO_dtoa __P((double __d, int __mode, int __ndigits,
int *__decpt, int *__sign, char **__rve));
@@ -213,7 +214,7 @@ extern int _IO_outfloat __P((double __value, _IO_FILE *__sb, int __type,
int __sign_mode, int __fill));
extern _IO_FILE *_IO_list_all;
-extern void (*_IO_cleanup_registration_needed)();
+extern void (*_IO_cleanup_registration_needed) __P ((void));
#ifndef EOF
#define EOF (-1)
@@ -306,3 +307,20 @@ extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf;
(((FILE)->_IO_file_flags & _IO_MAGIC_MASK) == _OLD_MAGIC_MASK \
&& (FILE) = *(FILE**)&((int*)fp)[1])
#endif
+
+#ifdef EINVAL
+#define MAYBE_SET_EINVAL errno = EINVAL
+#else
+#define MAYBE_SET_EINVAL /* nothing */
+#endif
+
+#ifdef DEBUG
+#define CHECK_FILE(FILE,RET) \
+ if ((FILE) == NULL) { MAYBE_SET_EINVAL; return RET; } \
+ else { COERCE_FILE(FILE); \
+ if (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \
+ { errno = EINVAL; return RET; }}
+#else
+#define CHECK_FILE(FILE,RET) \
+ COERCE_FILE(FILE)
+#endif
diff --git a/gnu/lib/libg++/include/regex.h b/gnu/lib/libg++/include/regex.h
deleted file mode 100644
index 9e404e8da100..000000000000
--- a/gnu/lib/libg++/include/regex.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/* Definitions for data structures callers pass the regex library.
-
- Copyright (C) 1985, 1989-92 Free Software Foundation, Inc.
-
-This file is part of the GNU C++ Library. This library is free
-software; you can redistribute it and/or modify it under the terms of
-the GNU Library General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version. This library is distributed in the hope
-that it will be useful, but WITHOUT ANY WARRANTY; without even the
-implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU Library General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with this library; if not, write to the Free Software
-Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef __REGEXP_LIBRARY
-#define __REGEXP_LIBRARY
-
-#if defined(SHORT_NAMES) || defined(VMS)
-#define re_compile_pattern recmppat
-#define re_pattern_buffer repatbuf
-#define re_registers reregs
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Define number of parens for which we record the beginnings and ends.
- This affects how much space the `struct re_registers' type takes up. */
-#ifndef RE_NREGS
-#define RE_NREGS 10
-#endif
-
-#define BYTEWIDTH 8
-
-
-/* Maximum number of duplicates an interval can allow. */
-#ifndef RE_DUP_MAX /* kludge for AIX, which defines it */
-#define RE_DUP_MAX ((1 << 15) - 1)
-#endif
-
-/* This defines the various regexp syntaxes. */
-extern int obscure_syntax;
-
-
-/* The following bits are used in the obscure_syntax variable to choose among
- alternative regexp syntaxes. */
-
-/* If this bit is set, plain parentheses serve as grouping, and backslash
- parentheses are needed for literal searching.
- If not set, backslash-parentheses are grouping, and plain parentheses
- are for literal searching. */
-#define RE_NO_BK_PARENS 1
-
-/* If this bit is set, plain | serves as the `or'-operator, and \| is a
- literal.
- If not set, \| serves as the `or'-operator, and | is a literal. */
-#define RE_NO_BK_VBAR (1 << 1)
-
-/* If this bit is not set, plain + or ? serves as an operator, and \+, \? are
- literals.
- If set, \+, \? are operators and plain +, ? are literals. */
-#define RE_BK_PLUS_QM (1 << 2)
-
-/* If this bit is set, | binds tighter than ^ or $.
- If not set, the contrary. */
-#define RE_TIGHT_VBAR (1 << 3)
-
-/* If this bit is set, then treat newline as an OR operator.
- If not set, treat it as a normal character. */
-#define RE_NEWLINE_OR (1 << 4)
-
-/* If this bit is set, then special characters may act as normal
- characters in some contexts. Specifically, this applies to:
- ^ -- only special at the beginning, or after ( or |;
- $ -- only special at the end, or before ) or |;
- *, +, ? -- only special when not after the beginning, (, or |.
- If this bit is not set, special characters (such as *, ^, and $)
- always have their special meaning regardless of the surrounding
- context. */
-#define RE_CONTEXT_INDEP_OPS (1 << 5)
-
-/* If this bit is not set, then \ before anything inside [ and ] is taken as
- a real \.
- If set, then such a \ escapes the following character. This is a
- special case for awk. */
-#define RE_AWK_CLASS_HACK (1 << 6)
-
-/* If this bit is set, then \{ and \} or { and } serve as interval operators.
- If not set, then \{ and \} and { and } are treated as literals. */
-#define RE_INTERVALS (1 << 7)
-
-/* If this bit is not set, then \{ and \} serve as interval operators and
- { and } are literals.
- If set, then { and } serve as interval operators and \{ and \} are
- literals. */
-#define RE_NO_BK_CURLY_BRACES (1 << 8)
-
-/* If this bit is set, then character classes are supported; they are:
- [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
- [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
- If not set, then character classes are not supported. */
-#define RE_CHAR_CLASSES (1 << 9)
-
-/* If this bit is set, then the dot re doesn't match a null byte.
- If not set, it does. */
-#define RE_DOT_NOT_NULL (1 << 10)
-
-/* If this bit is set, then [^...] doesn't match a newline.
- If not set, it does. */
-#define RE_HAT_NOT_NEWLINE (1 << 11)
-
-/* If this bit is set, back references are recognized.
- If not set, they aren't. */
-#define RE_NO_BK_REFS (1 << 12)
-
-/* If this bit is set, back references must refer to a preceding
- subexpression. If not set, a back reference to a nonexistent
- subexpression is treated as literal characters. */
-#define RE_NO_EMPTY_BK_REF (1 << 13)
-
-/* If this bit is set, bracket expressions can't be empty.
- If it is set, they can be empty. */
-#define RE_NO_EMPTY_BRACKETS (1 << 14)
-
-/* If this bit is set, then *, +, ? and { cannot be first in an re or
- immediately after a |, or a (. Furthermore, a | cannot be first or
- last in an re, or immediately follow another | or a (. Also, a ^
- cannot appear in a nonleading position and a $ cannot appear in a
- nontrailing position (outside of bracket expressions, that is). */
-#define RE_CONTEXTUAL_INVALID_OPS (1 << 15)
-
-/* If this bit is set, then +, ? and | aren't recognized as operators.
- If it's not, they are. */
-#define RE_LIMITED_OPS (1 << 16)
-
-/* If this bit is set, then an ending range point has to collate higher
- or equal to the starting range point.
- If it's not set, then when the ending range point collates higher
- than the starting range point, the range is just considered empty. */
-#define RE_NO_EMPTY_RANGES (1 << 17)
-
-/* If this bit is set, then a hyphen (-) can't be an ending range point.
- If it isn't, then it can. */
-#define RE_NO_HYPHEN_RANGE_END (1 << 18)
-
-
-/* Define combinations of bits for the standard possibilities. */
-#define RE_SYNTAX_POSIX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
- | RE_CONTEXT_INDEP_OPS)
-#define RE_SYNTAX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
- | RE_CONTEXT_INDEP_OPS | RE_AWK_CLASS_HACK)
-#define RE_SYNTAX_EGREP (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
- | RE_CONTEXT_INDEP_OPS | RE_NEWLINE_OR)
-#define RE_SYNTAX_GREP (RE_BK_PLUS_QM | RE_NEWLINE_OR)
-#define RE_SYNTAX_EMACS 0
-#define RE_SYNTAX_POSIX_BASIC (RE_INTERVALS | RE_BK_PLUS_QM \
- | RE_CHAR_CLASSES | RE_DOT_NOT_NULL \
- | RE_HAT_NOT_NEWLINE | RE_NO_EMPTY_BK_REF \
- | RE_NO_EMPTY_BRACKETS | RE_LIMITED_OPS \
- | RE_NO_EMPTY_RANGES | RE_NO_HYPHEN_RANGE_END)
-
-#define RE_SYNTAX_POSIX_EXTENDED (RE_INTERVALS | RE_NO_BK_CURLY_BRACES \
- | RE_NO_BK_VBAR | RE_NO_BK_PARENS \
- | RE_HAT_NOT_NEWLINE | RE_CHAR_CLASSES \
- | RE_NO_EMPTY_BRACKETS | RE_CONTEXTUAL_INVALID_OPS \
- | RE_NO_BK_REFS | RE_NO_EMPTY_RANGES \
- | RE_NO_HYPHEN_RANGE_END)
-
-
-/* This data structure is used to represent a compiled pattern. */
-
-struct re_pattern_buffer
- {
- char *buffer; /* Space holding the compiled pattern commands. */
- long allocated; /* Size of space that `buffer' points to. */
- long used; /* Length of portion of buffer actually occupied */
- char *fastmap; /* Pointer to fastmap, if any, or zero if none. */
- /* re_search uses the fastmap, if there is one,
- to skip over totally implausible characters. */
- char *translate; /* Translate table to apply to all characters before
- comparing, or zero for no translation.
- The translation is applied to a pattern when it is
- compiled and to data when it is matched. */
- char fastmap_accurate;
- /* Set to zero when a new pattern is stored,
- set to one when the fastmap is updated from it. */
- char can_be_null; /* Set to one by compiling fastmap
- if this pattern might match the null string.
- It does not necessarily match the null string
- in that case, but if this is zero, it cannot.
- 2 as value means can match null string
- but at end of range or before a character
- listed in the fastmap. */
- };
-
-
-/* search.c (search_buffer) needs this one value. It is defined both in
- regex.c and here. */
-#define RE_EXACTN_VALUE 1
-
-
-/* Structure to store register contents data in.
-
- Pass the address of such a structure as an argument to re_match, etc.,
- if you want this information back.
-
- For i from 1 to RE_NREGS - 1, start[i] records the starting index in
- the string of where the ith subexpression matched, and end[i] records
- one after the ending index. start[0] and end[0] are analogous, for
- the entire pattern. */
-
-struct re_registers
- {
- int start[RE_NREGS];
- int end[RE_NREGS];
- };
-
-
-
-#if defined(__STDC__) || defined(__cplusplus)
-
-extern char *re_compile_pattern (const char *, int, struct re_pattern_buffer *);
-/* Is this really advertised? */
-extern void re_compile_fastmap (struct re_pattern_buffer *);
-extern int re_search (struct re_pattern_buffer *, char*, int, int, int,
- struct re_registers *);
-extern int re_search_2 (struct re_pattern_buffer *, char *, int,
- char *, int, int, int,
- struct re_registers *, int);
-extern int re_match (struct re_pattern_buffer *, char *, int, int,
- struct re_registers *);
-extern int re_match_2 (struct re_pattern_buffer *, char *, int,
- char *, int, int, struct re_registers *, int);
-
-#if 0
-/* 4.2 bsd compatibility. */
-extern char *re_comp (char *);
-extern int re_exec (char *);
-#endif
-
-#else /* !__STDC__ */
-
-#define const /* nothing */
-extern char *re_compile_pattern ();
-/* Is this really advertised? */
-extern void re_compile_fastmap ();
-extern int re_search (), re_search_2 ();
-extern int re_match (), re_match_2 ();
-
-#if 0
-/* 4.2 bsd compatibility. */
-extern char *re_comp ();
-extern int re_exec ();
-#endif
-
-#endif /* __STDC__ */
-
-
-#ifdef SYNTAX_TABLE
-extern char *re_syntax_table;
-#endif
-
-#ifdef __cplusplus
-extern int re_max_failures;
-}
-#endif
-
-#endif /* !__REGEXP_LIBRARY */
diff --git a/gnu/lib/libg++/include/rx.h b/gnu/lib/libg++/include/rx.h
new file mode 100644
index 000000000000..275f397aa4a2
--- /dev/null
+++ b/gnu/lib/libg++/include/rx.h
@@ -0,0 +1,3255 @@
+#if !defined(RXH) || defined(RX_WANT_SE_DEFS)
+#define RXH
+
+/* Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of the librx library.
+
+Librx is free software; you can redistribute it and/or modify it under
+the terms of the GNU Library General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+Librx 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 Library General Public
+License along with this software; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA
+02139, USA. */
+/* t. lord Wed Sep 23 18:20:57 1992 */
+
+
+
+
+
+
+
+
+#ifndef RX_WANT_SE_DEFS
+
+/* This page: Bitsets */
+
+#ifndef RX_subset
+typedef unsigned int RX_subset;
+#define RX_subset_bits (32)
+#define RX_subset_mask (RX_subset_bits - 1)
+#endif
+
+typedef RX_subset * rx_Bitset;
+
+#ifdef __STDC__
+typedef void (*rx_bitset_iterator) (void *, int member_index);
+#else
+typedef void (*rx_bitset_iterator) ();
+#endif
+
+#define rx_bitset_subset(N) ((N) / RX_subset_bits)
+#define rx_bitset_subset_val(B,N) ((B)[rx_bitset_subset(N)])
+#define RX_bitset_access(B,N,OP) \
+ ((B)[rx_bitset_subset(N)] OP rx_subset_singletons[(N) & RX_subset_mask])
+#define RX_bitset_member(B,N) RX_bitset_access(B, N, &)
+#define RX_bitset_enjoin(B,N) RX_bitset_access(B, N, |=)
+#define RX_bitset_remove(B,N) RX_bitset_access(B, N, &= ~)
+#define RX_bitset_toggle(B,N) RX_bitset_access(B, N, ^= )
+#define rx_bitset_numb_subsets(N) (((N) + RX_subset_bits - 1) / RX_subset_bits)
+#define rx_sizeof_bitset(N) (rx_bitset_numb_subsets(N) * sizeof(RX_subset))
+
+
+
+/* This page: Splay trees. */
+
+#ifdef __STDC__
+typedef int (*rx_sp_comparer) (void * a, void * b);
+#else
+typedef int (*rx_sp_comparer) ();
+#endif
+
+struct rx_sp_node
+{
+ void * key;
+ void * data;
+ struct rx_sp_node * kids[2];
+};
+
+#ifdef __STDC__
+typedef void (*rx_sp_key_data_freer) (struct rx_sp_node *);
+#else
+typedef void (*rx_sp_key_data_freer) ();
+#endif
+
+
+/* giant inflatable hash trees */
+
+struct rx_hash_item
+{
+ struct rx_hash_item * next_same_hash;
+ struct rx_hash * table;
+ unsigned long hash;
+ void * data;
+ void * binding;
+};
+
+struct rx_hash
+{
+ struct rx_hash * parent;
+ int refs;
+ struct rx_hash * children[13];
+ struct rx_hash_item * buckets [13];
+ int bucket_size [13];
+};
+
+struct rx_hash_rules;
+
+#ifdef __STDC__
+/* should return like == */
+typedef int (*rx_hash_eq)(void *, void *);
+typedef struct rx_hash * (*rx_alloc_hash)(struct rx_hash_rules *);
+typedef void (*rx_free_hash)(struct rx_hash *,
+ struct rx_hash_rules *);
+typedef struct rx_hash_item * (*rx_alloc_hash_item)(struct rx_hash_rules *,
+ void *);
+typedef void (*rx_free_hash_item)(struct rx_hash_item *,
+ struct rx_hash_rules *);
+#else
+typedef int (*rx_hash_eq)();
+typedef struct rx_hash * (*rx_alloc_hash)();
+typedef void (*rx_free_hash)();
+typedef struct rx_hash_item * (*rx_alloc_hash_item)();
+typedef void (*rx_free_hash_item)();
+#endif
+
+struct rx_hash_rules
+{
+ rx_hash_eq eq;
+ rx_alloc_hash hash_alloc;
+ rx_free_hash free_hash;
+ rx_alloc_hash_item hash_item_alloc;
+ rx_free_hash_item free_hash_item;
+};
+
+
+
+/* Matchers decide what to do by examining a series of these.
+ * Instruction types are described below.
+ */
+struct rx_inx
+{
+ void * inx;
+ void * data;
+ void * data_2;
+ void * fnord;
+};
+
+/* Struct RX holds a compiled regular expression - that is, an nfa ready to be
+ * converted on demand to a more efficient nfa. This is for the low level interface.
+ * The high-level interface incloses this in a `struct re_pattern_buffer'.
+ */
+struct rx_cache;
+#ifdef __STDC__
+struct rx_se_list;
+struct rx;
+typedef int (*rx_se_list_order) (struct rx *,
+ struct rx_se_list *, struct rx_se_list *);
+#else
+typedef int (*rx_se_list_order) ();
+#endif
+
+struct rx_superset;
+
+struct rx
+{
+ int rx_id; /* Every edition numbered and signed by eclose_nfa. */
+
+ struct rx_cache * cache; /* Where superstates come from */
+
+ /* Every regex defines the size of its own character set. */
+ int local_cset_size;
+
+ void * buffer; /* Malloced memory for the nfa. */
+ unsigned long allocated; /* Size of that memory. */
+
+ /* How much buffer space to save for external uses. After compilation,
+ * this space will be available at (buffer + allocated - reserved)
+ */
+ unsigned long reserved;
+
+ /* --------- The remaining fields are for internal use only. --------- */
+ /* --------- But! they should be initialized to 0. --------- */
+ /* NODEC is the number of nodes in the NFA with non-epsilon
+ * orx transitions.
+ */
+ int nodec;
+
+ /* EPSNODEC is the number of nodes with only epsilon (orx) transitions. */
+ int epsnodec;
+
+ /* The sum of NODEC & EPSNODEC is the total number of states in the
+ * compiled NFA.
+ */
+
+ /* side_effect_progs temporarily holds a tree of side effect lists. */
+ struct rx_hash se_list_memo;
+
+ /* A memo for sets of states in the possible_future lists of an nfa: */
+ struct rx_hash set_list_memo;
+
+ /* The instruction table is indexed by the enum of instructions defined in
+ * rxrun.h. The values in the table are used to fill in the `inx'
+ * slot of instruction frames (see rxrun.h).
+ */
+ void ** instruction_table;
+ struct rx_nfa_state *nfa_states;
+ struct rx_nfa_state *start;
+
+ /* This orders the search through super-nfa paths. */
+ rx_se_list_order se_list_cmp;
+
+ struct rx_superset * start_set;
+};
+
+/* An RX NFA may contain epsilon edges labeled with side effects.
+ * These side effects represent match actions that can not normally be
+ * defined in a `pure' NFA; for example, recording the location at
+ * which a paren is crossed in a register structure.
+ *
+ * A matcher is supposed to find a particular path
+ * through the NFA (such as leftmost-longest), and then to execute the
+ * side effects along that path. Operationally, the space of paths is
+ * searched and side effects are carried out incrementally, and with
+ * backtracking.
+ *
+ * As the NFA is manipulated during matching sets of side effects.
+ * Simple lists are used to hold side effect lists.
+ */
+
+typedef void * rx_side_effect;
+
+struct rx_se_list
+{
+ rx_side_effect car;
+ struct rx_se_list * cdr;
+};
+
+
+
+/* Struct rexp_node holds an expression tree that represents a regexp.
+ * In this expression tree, every node has a type, and some parameters
+ * appropriate to that type.
+ */
+
+enum rexp_node_type
+{
+ r_cset, /* Match from a character set. `a' or `[a-z]'*/
+ r_concat, /* Concat two regexps. `ab' */
+ r_alternate, /* Choose one of two regexps. `a\|b' */
+ r_opt, /* Optional regexp. `a?' */
+ r_star, /* Repeated regexp. `a*' */
+ r_2phase_star, /* hard to explain */
+ r_side_effect, /* Matches the empty string, but
+ * implies that a side effect must
+ * take place. These nodes are used
+ * by the parser to implement parens,
+ * backreferences etc.
+ */
+
+ r_data /* R_DATA is soley for the convenience
+ * of parsers or other rexp
+ * transformers that want to
+ * (temporarily) introduce new node
+ * types in rexp structures. These
+ * must be eliminated
+ * by the time build_nfa is called.
+ */
+};
+
+struct rexp_node
+{
+ enum rexp_node_type type;
+ union
+ {
+ rx_Bitset cset;
+ rx_side_effect side_effect;
+ struct
+ {
+ struct rexp_node *left;
+ struct rexp_node *right;
+ } pair;
+ void * data;
+ } params;
+};
+
+
+
+/* This defines the structure of the NFA into which rexps are compiled. */
+
+struct rx_nfa_state
+{
+ int id;
+ struct rx_nfa_edge *edges;
+ struct rx_possible_future *futures;
+ unsigned int is_final:1;
+ unsigned int is_start:1;
+ unsigned int eclosure_needed:1;
+ struct rx_nfa_state *next;
+ unsigned int mark:1;
+};
+
+enum rx_nfa_etype
+{
+ ne_cset,
+ ne_epsilon,
+ ne_side_effect /* A special kind of epsilon. */
+};
+
+struct rx_nfa_edge
+{
+ struct rx_nfa_edge *next;
+ enum rx_nfa_etype type;
+ struct rx_nfa_state *dest;
+ union
+ {
+ rx_Bitset cset;
+ rx_side_effect side_effect;
+ } params;
+};
+
+struct rx_nfa_state_set
+{
+ struct rx_nfa_state * car;
+ struct rx_nfa_state_set * cdr;
+};
+
+struct rx_possible_future
+{
+ struct rx_possible_future *next;
+ struct rx_se_list * effects;
+ struct rx_nfa_state_set * destset;
+};
+
+
+
+enum rx_opcode
+{
+ /*
+ * BACKTRACK_POINT is invoked when a transition results in more
+ * than one possible future.
+ *
+ * There is one occurence of this instruction per transition_class
+ * structure; that occurence is only ever executed if the
+ * transition_class contains a list of more than 1 edge.
+ */
+ rx_backtrack_point = 0, /* data is (struct transition_class *) */
+
+ /*
+ * RX_DO_SIDE_EFFECTS evaluates the side effects of an epsilon path.
+ * There is one occurence of this instruction per rx_distinct_future.
+ * This instruction is skipped if a rx_distinct_future has no side effects.
+ */
+ rx_do_side_effects = rx_backtrack_point + 1,
+ /* data is (struct rx_distinct_future *) */
+
+ /*
+ * RX_CACHE_MISS instructions are stored in rx_distinct_futures whose
+ * destination superstate has been reclaimed (or was never built).
+ * It recomputes the destination superstate.
+ * RX_CACHE_MISS is also stored in a superstate transition table before
+ * any of its edges have been built.
+ */
+ rx_cache_miss = rx_do_side_effects + 1,
+ /* data is (struct rx_distinct_future *) */
+
+ /*
+ * RX_NEXT_CHAR is called to consume the next character and take the
+ * corresponding transition. This is the only instruction that uses
+ * the DATA field of the instruction frame instead of DATA_2.
+ * (see EXPLORE_FUTURE in regex.c).
+ */
+ rx_next_char = rx_cache_miss + 1, /* data is (struct superstate *) */
+
+ /* RX_BACKTRACK indicates that a transition fails.
+ */
+ rx_backtrack = rx_next_char + 1, /* no data */
+
+ /*
+ * RX_ERROR_INX is stored only in places that should never be executed.
+ */
+ rx_error_inx = rx_backtrack + 1, /* Not supposed to occur. */
+
+ rx_num_instructions = rx_error_inx + 1
+};
+
+/* An id_instruction_table holds the values stored in instruction
+ * frames. The table is indexed by the enums declared above.
+ */
+extern void * rx_id_instruction_table[rx_num_instructions];
+
+#if 0 /* Already declared way above. */
+/* If the instruction is `rx_next_char' then data is valid. Otherwise it's 0
+ * and data_2 is valid.
+ */
+struct rx_inx
+{
+ void * inx;
+ void * data;
+ void * data_2;
+};
+#endif
+
+
+#ifndef RX_TAIL_ARRAY
+#define RX_TAIL_ARRAY 1
+#endif
+
+/* A superstate corresponds to a set of nfa states. Those sets are
+ * represented by STRUCT RX_SUPERSET. The constructors
+ * guarantee that only one (shared) structure is created for a given set.
+ */
+struct rx_superset
+{
+ int refs;
+ struct rx_nfa_state * car; /* May or may not be a valid addr. */
+ int id; /* == car->id for the initial value of *car */
+ struct rx_superset * cdr; /* May be NULL or a live or semifreed super*/
+
+ /* If the corresponding superstate exists: */
+ struct rx_superstate * superstate;
+
+ /* If this is a starting state (as built by re_search_2)
+ * this points to the `struct rx'. The memory for these objects
+ * is typed -- so even after they are freed it is safe to look
+ * at this field (to check, in fact, if this was freed.)
+ */
+ struct rx * starts_for;
+
+ struct rx_hash_item hash_item;
+};
+
+#define rx_protect_superset(RX,CON) (++(CON)->refs)
+
+/* Every character occurs in at most one super edge per super-state.
+ * But, that edge might have more than one option, indicating a point
+ * of non-determinism.
+ */
+struct rx_super_edge
+{
+ struct rx_super_edge *next;
+ struct rx_inx rx_backtrack_frame;
+ int cset_size;
+ rx_Bitset cset;
+ struct rx_distinct_future *options;
+};
+
+/* A superstate is a set of nfa states (RX_SUPERSET) along
+ * with a transition table. Superstates are built on demand and reclaimed
+ * without warning. To protect a superstate, use LOCK_SUPERSTATE.
+ *
+ * Joe Keane thought of calling these superstates and several people
+ * have commented on what a good name it is for what they do.
+ */
+struct rx_superstate
+{
+ int rx_id;
+ int locks;
+ struct rx_superstate * next_recyclable;
+ struct rx_superstate * prev_recyclable;
+ struct rx_distinct_future * transition_refs;
+ struct rx_superset * contents;
+ struct rx_super_edge * edges;
+ int is_semifree;
+ int trans_size;
+ struct rx_inx transitions[RX_TAIL_ARRAY]; /* cset sized */
+};
+
+struct rx_distinct_future
+{
+ struct rx_distinct_future * next_same_super_edge[2];
+ struct rx_distinct_future * next_same_dest;
+ struct rx_distinct_future * prev_same_dest;
+ struct rx_superstate * present; /* source state */
+ struct rx_superstate * future; /* destination state */
+ struct rx_super_edge * edge;
+ struct rx_inx future_frame;
+ struct rx_inx side_effects_frame;
+ struct rx_se_list * effects;
+};
+
+#define rx_lock_superstate(R,S) ((S)->locks++)
+#define rx_unlock_superstate(R,S) (--(S)->locks)
+
+
+/* This page destined for rx.h */
+
+struct rx_blocklist
+{
+ struct rx_blocklist * next;
+ int bytes;
+};
+
+struct rx_freelist
+{
+ struct rx_freelist * next;
+};
+
+struct rx_cache;
+
+#ifdef __STDC__
+typedef void (*rx_morecore_fn)(struct rx_cache *);
+#else
+typedef void (*rx_morecore_fn)();
+#endif
+
+/* You use this to control the allocation of superstate data
+ * during matching. Most of it should be initialized to 0.
+ *
+ * A MORECORE function is necessary. It should allocate
+ * a new block of memory or return 0.
+ * A default that uses malloc is called `rx_morecore'.
+ *
+ * The number of SUPERSTATES_ALLOWED indirectly limits how much memory
+ * the system will try to allocate. The default is 128. Batch style
+ * applications that are very regexp intensive should use as high a number
+ * as possible without thrashing.
+ *
+ * The LOCAL_CSET_SIZE is the number of characters in a character set.
+ * It is therefore the number of entries in a superstate transition table.
+ * Generally, it should be 256. If your character set has 16 bits,
+ * it is better to translate your regexps into equivalent 8 bit patterns.
+ */
+
+struct rx_cache
+{
+ struct rx_hash_rules superset_hash_rules;
+
+ /* Objects are allocated by incrementing a pointer that
+ * scans across rx_blocklists.
+ */
+ struct rx_blocklist * memory;
+ struct rx_blocklist * memory_pos;
+ int bytes_left;
+ char * memory_addr;
+ rx_morecore_fn morecore;
+
+ /* Freelists. */
+ struct rx_freelist * free_superstates;
+ struct rx_freelist * free_transition_classes;
+ struct rx_freelist * free_discernable_futures;
+ struct rx_freelist * free_supersets;
+ struct rx_freelist * free_hash;
+
+ /* Two sets of superstates -- those that are semifreed, and those
+ * that are being used.
+ */
+ struct rx_superstate * lru_superstate;
+ struct rx_superstate * semifree_superstate;
+
+ struct rx_superset * empty_superset;
+
+ int superstates;
+ int semifree_superstates;
+ int hits;
+ int misses;
+ int superstates_allowed;
+
+ int local_cset_size;
+ void ** instruction_table;
+
+ struct rx_hash superset_table;
+};
+
+
+
+/* The lowest-level search function supports arbitrarily fragmented
+ * strings and (optionally) suspendable/resumable searches.
+ *
+ * Callers have to provide a few hooks.
+ */
+
+#ifndef __GNUC__
+#ifdef __STDC__
+#define __const__ const
+#else
+#define __const__
+#endif
+#endif
+
+/* This holds a matcher position */
+struct rx_string_position
+{
+ __const__ unsigned char * pos; /* The current pos. */
+ __const__ unsigned char * string; /* The current string burst. */
+ __const__ unsigned char * end; /* First invalid position >= POS. */
+ int offset; /* Integer address of the current burst. */
+ int size; /* Current string's size. */
+ int search_direction; /* 1 or -1 */
+ int search_end; /* First position to not try. */
+};
+
+
+enum rx_get_burst_return
+{
+ rx_get_burst_continuation,
+ rx_get_burst_error,
+ rx_get_burst_ok,
+ rx_get_burst_no_more
+};
+
+
+/* A call to get burst should make POS valid. It might be invalid
+ * if the STRING field doesn't point to a burst that actually
+ * contains POS.
+ *
+ * GET_BURST should take a clue from SEARCH_DIRECTION (1 or -1) as to
+ * whether or not to pad to the left. Padding to the right is always
+ * appropriate, but need not go past the point indicated by STOP.
+ *
+ * If a continuation is returned, then the reentering call to
+ * a search function will retry the get_burst.
+ */
+
+#ifdef __STDC__
+typedef enum rx_get_burst_return
+ (*rx_get_burst_fn) (struct rx_string_position * pos,
+ void * app_closure,
+ int stop);
+
+#else
+typedef enum rx_get_burst_return (*rx_get_burst_fn) ();
+#endif
+
+
+enum rx_back_check_return
+{
+ rx_back_check_continuation,
+ rx_back_check_error,
+ rx_back_check_pass,
+ rx_back_check_fail
+};
+
+/* Back_check should advance the position it is passed
+ * over rparen - lparen characters and return pass iff
+ * the characters starting at POS match those indexed
+ * by [LPAREN..RPAREN].
+ *
+ * If a continuation is returned, then the reentering call to
+ * a search function will retry the back_check.
+ */
+
+#ifdef __STDC__
+typedef enum rx_back_check_return
+ (*rx_back_check_fn) (struct rx_string_position * pos,
+ int lparen,
+ int rparen,
+ unsigned char * translate,
+ void * app_closure,
+ int stop);
+
+#else
+typedef enum rx_back_check_return (*rx_back_check_fn) ();
+#endif
+
+
+
+
+/* A call to fetch_char should return the character at POS or POS + 1.
+ * Returning continuations here isn't supported. OFFSET is either 0 or 1
+ * and indicates which characters is desired.
+ */
+
+#ifdef __STDC__
+typedef int (*rx_fetch_char_fn) (struct rx_string_position * pos,
+ int offset,
+ void * app_closure,
+ int stop);
+#else
+typedef int (*rx_fetch_char_fn) ();
+#endif
+
+
+enum rx_search_return
+{
+ rx_search_continuation = -4,
+ rx_search_error = -3,
+ rx_search_soft_fail = -2, /* failed by running out of string */
+ rx_search_fail = -1 /* failed only by reaching failure states */
+ /* return values >= 0 indicate the position of a successful match */
+};
+
+
+
+
+
+
+/* regex.h
+ *
+ * The remaining declarations replace regex.h.
+ */
+
+/* This is an array of error messages corresponding to the error codes.
+ */
+extern __const__ char *re_error_msg[];
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Not implemented. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+
+/* The regex.c support, as a client of rx, defines a set of possible
+ * side effects that can be added to the edge lables of nfa edges.
+ * Here is the list of sidef effects in use.
+ */
+
+enum re_side_effects
+{
+#define RX_WANT_SE_DEFS 1
+#undef RX_DEF_SE
+#undef RX_DEF_CPLX_SE
+#define RX_DEF_SE(IDEM, NAME, VALUE) NAME VALUE,
+#define RX_DEF_CPLX_SE(IDEM, NAME, VALUE) NAME VALUE,
+#include "rx.h"
+#undef RX_DEF_SE
+#undef RX_DEF_CPLX_SE
+#undef RX_WANT_SE_DEFS
+ re_floogle_flap = 65533
+};
+
+/* These hold paramaters for the kinds of side effects that are possible
+ * in the supported pattern languages. These include things like the
+ * numeric bounds of {} operators and the index of paren registers for
+ * subexpression measurement or backreferencing.
+ */
+struct re_se_params
+{
+ enum re_side_effects se;
+ int op1;
+ int op2;
+};
+
+typedef unsigned reg_syntax_t;
+
+struct re_pattern_buffer
+{
+ struct rx rx;
+ reg_syntax_t syntax; /* See below for syntax bit definitions. */
+
+ unsigned int no_sub:1; /* If set, don't return register offsets. */
+ unsigned int not_bol:1; /* If set, the anchors ('^' and '$') don't */
+ unsigned int not_eol:1; /* match at the ends of the string. */
+ unsigned int newline_anchor:1;/* If true, an anchor at a newline matches.*/
+ unsigned int least_subs:1; /* If set, and returning registers, return
+ * as few values as possible. Only
+ * backreferenced groups and group 0 (the whole
+ * match) will be returned.
+ */
+
+ /* If true, this says that the matcher should keep registers on its
+ * backtracking stack. For many patterns, we can easily determine that
+ * this isn't necessary.
+ */
+ unsigned int match_regs_on_stack:1;
+ unsigned int search_regs_on_stack:1;
+
+ /* is_anchored and begbuf_only are filled in by rx_compile. */
+ unsigned int is_anchored:1; /* Anchorded by ^? */
+ unsigned int begbuf_only:1; /* Anchored to char position 0? */
+
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ * for `max (RE_NREGS, re_nsub + 1)' groups.
+ * If REGS_REALLOCATE, reallocate space if necessary.
+ * If REGS_FIXED, use what's there.
+ */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned int regs_allocated:2;
+
+
+ /* Either a translate table to apply to all characters before
+ * comparing them, or zero for no translation. The translation
+ * is applied to a pattern when it is compiled and to a string
+ * when it is matched.
+ */
+ unsigned char * translate;
+
+ /* If this is a valid pointer, it tells rx not to store the extents of
+ * certain subexpressions (those corresponding to non-zero entries).
+ * Passing 0x1 is the same as passing an array of all ones. Passing 0x0
+ * is the same as passing an array of all zeros.
+ * The array should contain as many entries as their are subexps in the
+ * regexp.
+ */
+ char * syntax_parens;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ void * buffer; /* Malloced memory for the nfa. */
+ unsigned long allocated; /* Size of that memory. */
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses
+ * the fastmap, if there is one, to skip over impossible
+ * starting points for matches. */
+ char *fastmap;
+
+ unsigned int fastmap_accurate:1; /* These three are internal. */
+ unsigned int can_match_empty:1;
+ struct rx_nfa_state * start; /* The nfa starting state. */
+
+ /* This is the list of iterator bounds for {lo,hi} constructs.
+ * The memory pointed to is part of the rx->buffer.
+ */
+ struct re_se_params *se_params;
+
+ /* This is a bitset representation of the fastmap.
+ * This is a true fastmap that already takes the translate
+ * table into account.
+ */
+ rx_Bitset fastset;
+};
+
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
+struct re_registers
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
+
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported. They are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VAR | RE_NO_EMPTY_RANGES \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+ replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+#undef RE_DUP_MAX
+#endif
+#define RE_DUP_MAX ((1 << 15) - 1)
+
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ * `re_match_2' returns information about at least this many registers
+ * the first time a `regs' structure is passed.
+ *
+ * Also, this is the greatest number of backreferenced subexpressions
+ * allowed in a pattern being matched without caller-supplied registers.
+ */
+#ifndef RE_NREGS
+#define RE_NREGS 30
+#endif
+
+extern int rx_cache_bound;
+extern char rx_version_string[];
+
+
+
+#ifdef RX_WANT_RX_DEFS
+
+/* This is decls to the interesting subsystems and lower layers
+ * of rx. Everything which doesn't have a public counterpart in
+ * regex.c is declared here.
+ */
+
+
+#ifdef __STDC__
+typedef void (*rx_hash_freefn) (struct rx_hash_item * it);
+#else /* ndef __STDC__ */
+typedef void (*rx_hash_freefn) ();
+#endif /* ndef __STDC__ */
+
+
+
+
+#ifdef __STDC__
+RX_DECL int rx_bitset_is_equal (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL int rx_bitset_is_subset (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL int rx_bitset_empty (int size, rx_Bitset set);
+RX_DECL void rx_bitset_null (int size, rx_Bitset b);
+RX_DECL void rx_bitset_universe (int size, rx_Bitset b);
+RX_DECL void rx_bitset_complement (int size, rx_Bitset b);
+RX_DECL void rx_bitset_assign (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_union (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_intersection (int size,
+ rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_difference (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_revdifference (int size,
+ rx_Bitset a, rx_Bitset b);
+RX_DECL void rx_bitset_xor (int size, rx_Bitset a, rx_Bitset b);
+RX_DECL unsigned long rx_bitset_hash (int size, rx_Bitset b);
+RX_DECL struct rx_hash_item * rx_hash_find (struct rx_hash * table,
+ unsigned long hash,
+ void * value,
+ struct rx_hash_rules * rules);
+RX_DECL struct rx_hash_item * rx_hash_store (struct rx_hash * table,
+ unsigned long hash,
+ void * value,
+ struct rx_hash_rules * rules);
+RX_DECL void rx_hash_free (struct rx_hash_item * it, struct rx_hash_rules * rules);
+RX_DECL void rx_free_hash_table (struct rx_hash * tab, rx_hash_freefn freefn,
+ struct rx_hash_rules * rules);
+RX_DECL rx_Bitset rx_cset (struct rx *rx);
+RX_DECL rx_Bitset rx_copy_cset (struct rx *rx, rx_Bitset a);
+RX_DECL void rx_free_cset (struct rx * rx, rx_Bitset c);
+RX_DECL struct rexp_node * rexp_node (struct rx *rx,
+ enum rexp_node_type type);
+RX_DECL struct rexp_node * rx_mk_r_cset (struct rx * rx,
+ rx_Bitset b);
+RX_DECL struct rexp_node * rx_mk_r_concat (struct rx * rx,
+ struct rexp_node * a,
+ struct rexp_node * b);
+RX_DECL struct rexp_node * rx_mk_r_alternate (struct rx * rx,
+ struct rexp_node * a,
+ struct rexp_node * b);
+RX_DECL struct rexp_node * rx_mk_r_opt (struct rx * rx,
+ struct rexp_node * a);
+RX_DECL struct rexp_node * rx_mk_r_star (struct rx * rx,
+ struct rexp_node * a);
+RX_DECL struct rexp_node * rx_mk_r_2phase_star (struct rx * rx,
+ struct rexp_node * a,
+ struct rexp_node * b);
+RX_DECL struct rexp_node * rx_mk_r_side_effect (struct rx * rx,
+ rx_side_effect a);
+RX_DECL struct rexp_node * rx_mk_r_data (struct rx * rx,
+ void * a);
+RX_DECL void rx_free_rexp (struct rx * rx, struct rexp_node * node);
+RX_DECL struct rexp_node * rx_copy_rexp (struct rx *rx,
+ struct rexp_node *node);
+RX_DECL struct rx_nfa_state * rx_nfa_state (struct rx *rx);
+RX_DECL void rx_free_nfa_state (struct rx_nfa_state * n);
+RX_DECL struct rx_nfa_state * rx_id_to_nfa_state (struct rx * rx,
+ int id);
+RX_DECL struct rx_nfa_edge * rx_nfa_edge (struct rx *rx,
+ enum rx_nfa_etype type,
+ struct rx_nfa_state *start,
+ struct rx_nfa_state *dest);
+RX_DECL void rx_free_nfa_edge (struct rx_nfa_edge * e);
+RX_DECL void rx_free_nfa (struct rx *rx);
+RX_DECL int rx_build_nfa (struct rx *rx,
+ struct rexp_node *rexp,
+ struct rx_nfa_state **start,
+ struct rx_nfa_state **end);
+RX_DECL void rx_name_nfa_states (struct rx *rx);
+RX_DECL int rx_eclose_nfa (struct rx *rx);
+RX_DECL void rx_delete_epsilon_transitions (struct rx *rx);
+RX_DECL int rx_compactify_nfa (struct rx *rx,
+ void **mem, unsigned long *size);
+RX_DECL void rx_release_superset (struct rx *rx,
+ struct rx_superset *set);
+RX_DECL struct rx_superset * rx_superset_cons (struct rx * rx,
+ struct rx_nfa_state *car, struct rx_superset *cdr);
+RX_DECL struct rx_superset * rx_superstate_eclosure_union
+ (struct rx * rx, struct rx_superset *set, struct rx_nfa_state_set *ecl);
+RX_DECL struct rx_superstate * rx_superstate (struct rx *rx,
+ struct rx_superset *set);
+RX_DECL struct rx_inx * rx_handle_cache_miss
+ (struct rx *rx, struct rx_superstate *super, unsigned char chr, void *data);
+RX_DECL reg_errcode_t rx_compile (__const__ char *pattern, int size,
+ reg_syntax_t syntax,
+ struct re_pattern_buffer * rxb);
+RX_DECL void rx_blow_up_fastmap (struct re_pattern_buffer * rxb);
+#else /* STDC */
+RX_DECL int rx_bitset_is_equal ();
+RX_DECL int rx_bitset_is_subset ();
+RX_DECL int rx_bitset_empty ();
+RX_DECL void rx_bitset_null ();
+RX_DECL void rx_bitset_universe ();
+RX_DECL void rx_bitset_complement ();
+RX_DECL void rx_bitset_assign ();
+RX_DECL void rx_bitset_union ();
+RX_DECL void rx_bitset_intersection ();
+RX_DECL void rx_bitset_difference ();
+RX_DECL void rx_bitset_revdifference ();
+RX_DECL void rx_bitset_xor ();
+RX_DECL unsigned long rx_bitset_hash ();
+RX_DECL struct rx_hash_item * rx_hash_find ();
+RX_DECL struct rx_hash_item * rx_hash_store ();
+RX_DECL void rx_hash_free ();
+RX_DECL void rx_free_hash_table ();
+RX_DECL rx_Bitset rx_cset ();
+RX_DECL rx_Bitset rx_copy_cset ();
+RX_DECL void rx_free_cset ();
+RX_DECL struct rexp_node * rexp_node ();
+RX_DECL struct rexp_node * rx_mk_r_cset ();
+RX_DECL struct rexp_node * rx_mk_r_concat ();
+RX_DECL struct rexp_node * rx_mk_r_alternate ();
+RX_DECL struct rexp_node * rx_mk_r_opt ();
+RX_DECL struct rexp_node * rx_mk_r_star ();
+RX_DECL struct rexp_node * rx_mk_r_2phase_star ();
+RX_DECL struct rexp_node * rx_mk_r_side_effect ();
+RX_DECL struct rexp_node * rx_mk_r_data ();
+RX_DECL void rx_free_rexp ();
+RX_DECL struct rexp_node * rx_copy_rexp ();
+RX_DECL struct rx_nfa_state * rx_nfa_state ();
+RX_DECL void rx_free_nfa_state ();
+RX_DECL struct rx_nfa_state * rx_id_to_nfa_state ();
+RX_DECL struct rx_nfa_edge * rx_nfa_edge ();
+RX_DECL void rx_free_nfa_edge ();
+RX_DECL void rx_free_nfa ();
+RX_DECL int rx_build_nfa ();
+RX_DECL void rx_name_nfa_states ();
+RX_DECL int rx_eclose_nfa ();
+RX_DECL void rx_delete_epsilon_transitions ();
+RX_DECL int rx_compactify_nfa ();
+RX_DECL void rx_release_superset ();
+RX_DECL struct rx_superset * rx_superset_cons ();
+RX_DECL struct rx_superset * rx_superstate_eclosure_union ();
+RX_DECL struct rx_superstate * rx_superstate ();
+RX_DECL struct rx_inx * rx_handle_cache_miss ();
+RX_DECL reg_errcode_t rx_compile ();
+RX_DECL void rx_blow_up_fastmap ();
+#endif /* STDC */
+
+
+#endif /* RX_WANT_RX_DEFS */
+
+
+
+#ifdef __STDC__
+extern int re_search_2 (struct re_pattern_buffer *rxb,
+ __const__ char * string1, int size1,
+ __const__ char * string2, int size2,
+ int startpos, int range,
+ struct re_registers *regs,
+ int stop);
+extern int re_search (struct re_pattern_buffer * rxb, __const__ char *string,
+ int size, int startpos, int range,
+ struct re_registers *regs);
+extern int re_match_2 (struct re_pattern_buffer * rxb,
+ __const__ char * string1, int size1,
+ __const__ char * string2, int size2,
+ int pos, struct re_registers *regs, int stop);
+extern int re_match (struct re_pattern_buffer * rxb,
+ __const__ char * string,
+ int size, int pos,
+ struct re_registers *regs);
+extern reg_syntax_t re_set_syntax (reg_syntax_t syntax);
+extern void re_set_registers (struct re_pattern_buffer *bufp,
+ struct re_registers *regs,
+ unsigned num_regs,
+ regoff_t * starts, regoff_t * ends);
+extern __const__ char * re_compile_pattern (__const__ char *pattern,
+ int length,
+ struct re_pattern_buffer * rxb);
+extern int re_compile_fastmap (struct re_pattern_buffer * rxb);
+extern char * re_comp (__const__ char *s);
+extern int re_exec (__const__ char *s);
+extern int regcomp (regex_t * preg, __const__ char * pattern, int cflags);
+extern int regexec (__const__ regex_t *preg, __const__ char *string,
+ size_t nmatch, regmatch_t pmatch[],
+ int eflags);
+extern size_t regerror (int errcode, __const__ regex_t *preg,
+ char *errbuf, size_t errbuf_size);
+extern void regfree (regex_t *preg);
+
+#else /* STDC */
+extern int re_search_2 ();
+extern int re_search ();
+extern int re_match_2 ();
+extern int re_match ();
+extern reg_syntax_t re_set_syntax ();
+extern void re_set_registers ();
+extern __const__ char * re_compile_pattern ();
+extern int re_compile_fastmap ();
+extern char * re_comp ();
+extern int re_exec ();
+extern int regcomp ();
+extern int regexec ();
+extern size_t regerror ();
+extern void regfree ();
+
+#endif /* STDC */
+
+
+
+#ifdef RX_WANT_RX_DEFS
+
+struct rx_counter_frame
+{
+ int tag;
+ int val;
+ struct rx_counter_frame * inherited_from; /* If this is a copy. */
+ struct rx_counter_frame * cdr;
+};
+
+struct rx_backtrack_frame
+{
+ char * counter_stack_sp;
+
+ /* A frame is used to save the matchers state when it crosses a
+ * backtracking point. The `stk_' fields correspond to variables
+ * in re_search_2 (just strip off thes `stk_'). They are documented
+ * tere.
+ */
+ struct rx_superstate * stk_super;
+ unsigned int stk_c;
+ struct rx_string_position stk_test_pos;
+ int stk_last_l;
+ int stk_last_r;
+ int stk_test_ret;
+
+ /* This is the list of options left to explore at the backtrack
+ * point for which this frame was created.
+ */
+ struct rx_distinct_future * df;
+ struct rx_distinct_future * first_df;
+
+#ifdef RX_DEBUG
+ int stk_line_no;
+#endif
+};
+
+struct rx_stack_chunk
+{
+ struct rx_stack_chunk * next_chunk;
+ int bytes_left;
+ char * sp;
+};
+
+enum rx_outer_entry
+{
+ rx_outer_start,
+ rx_outer_fastmap,
+ rx_outer_test,
+ rx_outer_restore_pos
+};
+
+enum rx_fastmap_return
+{
+ rx_fastmap_continuation,
+ rx_fastmap_error,
+ rx_fastmap_ok,
+ rx_fastmap_fail
+};
+
+enum rx_fastmap_entry
+{
+ rx_fastmap_start,
+ rx_fastmap_string_break
+};
+
+enum rx_test_return
+{
+ rx_test_continuation,
+ rx_test_error,
+ rx_test_fail,
+ rx_test_ok
+};
+
+enum rx_test_internal_return
+{
+ rx_test_internal_error,
+ rx_test_found_first,
+ rx_test_line_finished
+};
+
+enum rx_test_match_entry
+{
+ rx_test_start,
+ rx_test_cache_hit_loop,
+ rx_test_backreference_check,
+ rx_test_backtrack_return
+};
+
+struct rx_search_state
+{
+ /* Two groups of registers are kept. The group with the register state
+ * of the current test match, and the group that holds the state at the end
+ * of the best known match, if any.
+ *
+ * For some patterns, there may also be registers saved on the stack.
+ */
+ unsigned num_regs; /* Includes an element for register zero. */
+ regoff_t * lparen; /* scratch space for register returns */
+ regoff_t * rparen;
+ regoff_t * best_lpspace; /* in case the user doesn't want these */
+ regoff_t * best_rpspace; /* values, we still need space to store
+ * them. Normally, this memoryis unused
+ * and the space pointed to by REGS is
+ * used instead.
+ */
+
+ int last_l; /* Highest index of a valid lparen. */
+ int last_r; /* It's dual. */
+
+ int * best_lparen; /* This contains the best known register */
+ int * best_rparen; /* assignments.
+ * This may point to the same mem as
+ * best_lpspace, or it might point to memory
+ * passed by the caller.
+ */
+ int best_last_l; /* best_last_l:best_lparen::last_l:lparen */
+ int best_last_r;
+
+
+ unsigned char * translate;
+
+ struct rx_string_position outer_pos;
+
+ struct rx_superstate * start_super;
+ int nfa_choice;
+ int first_found; /* If true, return after finding any match. */
+ int ret_val;
+
+ /* For continuations... */
+ enum rx_outer_entry outer_search_resume_pt;
+ struct re_pattern_buffer * saved_rxb;
+ int saved_startpos;
+ int saved_range;
+ int saved_stop;
+ int saved_total_size;
+ rx_get_burst_fn saved_get_burst;
+ rx_back_check_fn saved_back_check;
+ struct re_registers * saved_regs;
+
+ /**
+ ** state for fastmap
+ **/
+ char * fastmap;
+ int fastmap_chr;
+ int fastmap_val;
+
+ /* for continuations in the fastmap procedure: */
+ enum rx_fastmap_entry fastmap_resume_pt;
+
+ /**
+ ** state for test_match
+ **/
+
+ /* The current superNFA position of the matcher. */
+ struct rx_superstate * super;
+
+ /* The matcher interprets a series of instruction frames.
+ * This is the `instruction counter' for the interpretation.
+ */
+ struct rx_inx * ifr;
+
+ /* We insert a ghost character in the string to prime
+ * the nfa. test_pos.pos, test_pos.str_half, and test_pos.end_half
+ * keep track of the test-match position and string-half.
+ */
+ unsigned char c;
+
+ /* Position within the string. */
+ struct rx_string_position test_pos;
+
+ struct rx_stack_chunk * counter_stack;
+ struct rx_stack_chunk * backtrack_stack;
+ int backtrack_frame_bytes;
+ int chunk_bytes;
+ struct rx_stack_chunk * free_chunks;
+
+ /* To return from this function, set test_ret and
+ * `goto test_do_return'.
+ *
+ * Possible return values are:
+ * 1 --- end of string while the superNFA is still going
+ * 0 --- internal error (out of memory)
+ * -1 --- search completed by reaching the superNFA fail state
+ * -2 --- a match was found, maybe not the longest.
+ *
+ * When the search is complete (-1), best_last_r indicates whether
+ * a match was found.
+ *
+ * -2 is return only if search_state.first_found is non-zero.
+ *
+ * if search_state.first_found is non-zero, a return of -1 indicates no match,
+ * otherwise, best_last_r has to be checked.
+ */
+ int test_ret;
+
+ int could_have_continued;
+
+#ifdef RX_DEBUG
+ int backtrack_depth;
+ /* There is a search tree with every node as set of deterministic
+ * transitions in the super nfa. For every branch of a
+ * backtrack point is an edge in the tree.
+ * This counts up a pre-order of nodes in that tree.
+ * It's saved on the search stack and printed when debugging.
+ */
+ int line_no;
+ int lines_found;
+#endif
+
+
+ /* For continuations within the match tester */
+ enum rx_test_match_entry test_match_resume_pt;
+ struct rx_inx * saved_next_tr_table;
+ struct rx_inx * saved_this_tr_table;
+ int saved_reg;
+ struct rx_backtrack_frame * saved_bf;
+
+};
+
+
+extern char rx_slowmap[];
+extern unsigned char rx_id_translation[];
+
+static __inline__ void
+init_fastmap (rxb, search_state)
+ struct re_pattern_buffer * rxb;
+ struct rx_search_state * search_state;
+{
+ search_state->fastmap = (rxb->fastmap
+ ? (char *)rxb->fastmap
+ : (char *)rx_slowmap);
+ /* Update the fastmap now if not correct already.
+ * When the regexp was compiled, the fastmap was computed
+ * and stored in a bitset. This expands the bitset into a
+ * character array containing 1s and 0s.
+ */
+ if ((search_state->fastmap == rxb->fastmap) && !rxb->fastmap_accurate)
+ rx_blow_up_fastmap (rxb);
+ search_state->fastmap_chr = -1;
+ search_state->fastmap_val = 0;
+ search_state->fastmap_resume_pt = rx_fastmap_start;
+}
+
+static __inline__ void
+uninit_fastmap (rxb, search_state)
+ struct re_pattern_buffer * rxb;
+ struct rx_search_state * search_state;
+{
+ /* Unset the fastmap sentinel */
+ if (search_state->fastmap_chr >= 0)
+ search_state->fastmap[search_state->fastmap_chr]
+ = search_state->fastmap_val;
+}
+
+static __inline__ int
+fastmap_search (rxb, stop, get_burst, app_closure, search_state)
+ struct re_pattern_buffer * rxb;
+ int stop;
+ rx_get_burst_fn get_burst;
+ void * app_closure;
+ struct rx_search_state * search_state;
+{
+ enum rx_fastmap_entry pc;
+
+ if (0)
+ {
+ return_continuation:
+ search_state->fastmap_resume_pt = pc;
+ return rx_fastmap_continuation;
+ }
+
+ pc = search_state->fastmap_resume_pt;
+
+ switch (pc)
+ {
+ case rx_fastmap_start:
+ init_fastmap_sentinal:
+ /* For the sake of fast fastmapping, set a sentinal in the fastmap.
+ * This sentinal will trap the fastmap loop when it reaches the last
+ * valid character in a string half.
+ *
+ * This must be reset when the fastmap/search loop crosses a string
+ * boundry, and before returning to the caller. So sometimes,
+ * the fastmap loop is restarted with `continue', othertimes by
+ * `goto init_fastmap_sentinal'.
+ */
+ if (search_state->outer_pos.size)
+ {
+ search_state->fastmap_chr = ((search_state->outer_pos.search_direction == 1)
+ ? *(search_state->outer_pos.end - 1)
+ : *search_state->outer_pos.string);
+ search_state->fastmap_val
+ = search_state->fastmap[search_state->fastmap_chr];
+ search_state->fastmap[search_state->fastmap_chr] = 1;
+ }
+ else
+ {
+ search_state->fastmap_chr = -1;
+ search_state->fastmap_val = 0;
+ }
+
+ if (search_state->outer_pos.pos >= search_state->outer_pos.end)
+ goto fastmap_hit_bound;
+ else
+ {
+ if (search_state->outer_pos.search_direction == 1)
+ {
+ if (search_state->fastmap_val)
+ {
+ for (;;)
+ {
+ while (!search_state->fastmap[*search_state->outer_pos.pos])
+ ++search_state->outer_pos.pos;
+ return rx_fastmap_ok;
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ while (!search_state->fastmap[*search_state->outer_pos.pos])
+ ++search_state->outer_pos.pos;
+ if (*search_state->outer_pos.pos != search_state->fastmap_chr)
+ return rx_fastmap_ok;
+ else
+ {
+ ++search_state->outer_pos.pos;
+ if (search_state->outer_pos.pos == search_state->outer_pos.end)
+ goto fastmap_hit_bound;
+ }
+ }
+ }
+ }
+ else
+ {
+ __const__ unsigned char * bound;
+ bound = search_state->outer_pos.string - 1;
+ if (search_state->fastmap_val)
+ {
+ for (;;)
+ {
+ while (!search_state->fastmap[*search_state->outer_pos.pos])
+ --search_state->outer_pos.pos;
+ return rx_fastmap_ok;
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ while (!search_state->fastmap[*search_state->outer_pos.pos])
+ --search_state->outer_pos.pos;
+ if ((*search_state->outer_pos.pos != search_state->fastmap_chr) || search_state->fastmap_val)
+ return rx_fastmap_ok;
+ else
+ {
+ --search_state->outer_pos.pos;
+ if (search_state->outer_pos.pos == bound)
+ goto fastmap_hit_bound;
+ }
+ }
+ }
+ }
+ }
+
+ case rx_fastmap_string_break:
+ fastmap_hit_bound:
+ {
+ /* If we hit a bound, it may be time to fetch another burst
+ * of string, or it may be time to return a continuation to
+ * the caller, or it might be time to fail.
+ */
+
+ int burst_state;
+ burst_state = get_burst (&search_state->outer_pos, app_closure, stop);
+ switch (burst_state)
+ {
+ case rx_get_burst_continuation:
+ {
+ pc = rx_fastmap_string_break;
+ goto return_continuation;
+ }
+ case rx_get_burst_error:
+ return rx_fastmap_error;
+ case rx_get_burst_ok:
+ goto init_fastmap_sentinal;
+ case rx_get_burst_no_more:
+ /* ...not a string split, simply no more string.
+ *
+ * When searching backward, running out of string
+ * is reason to quit.
+ *
+ * When searching forward, we allow the possibility
+ * of an (empty) match after the last character in the
+ * virtual string. So, fall through to the matcher
+ */
+ return ( (search_state->outer_pos.search_direction == 1)
+ ? rx_fastmap_ok
+ : rx_fastmap_fail);
+ }
+ }
+ }
+
+}
+
+
+
+#ifdef emacs
+/* The `emacs' switch turns on certain matching commands
+ * that make sense only in Emacs.
+ */
+#include "config.h"
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+/* Emacs uses `NULL' as a predicate. */
+#undef NULL
+#else /* not emacs */
+/* Setting RX_MEMDBUG is useful if you have dbmalloc. Maybe with similar
+ * packages too.
+ */
+#ifdef RX_MEMDBUG
+#include <malloc.h>
+#else /* not RX_RX_MEMDBUG */
+
+/* We used to test for `BSTRING' here, but only GCC and Emacs define
+ * `BSTRING', as far as I know, and neither of them use this code.
+ */
+#if HAVE_STRING_H || STDC_HEADERS
+#include <string.h>
+
+#ifndef bcmp
+#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
+#endif
+
+#ifndef bcopy
+#define bcopy(s, d, n) memcpy ((d), (s), (n))
+#endif
+
+#ifndef bzero
+#define bzero(s, n) memset ((s), 0, (n))
+#endif
+
+#else /* HAVE_STRING_H || STDC_HEADERS */
+#include <strings.h>
+#endif /* not RX_MEMDBUG */
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else /* not STDC_HEADERS */
+char *malloc ();
+char *realloc ();
+#endif /* not STDC_HEADERS */
+
+#endif /* not emacs */
+
+
+
+/* Define the syntax basics for \<, \>, etc.
+ * This must be nonzero for the wordchar and notwordchar pattern
+ * commands in re_match_2.
+ */
+#ifndef Sword
+#define Sword 1
+#endif
+
+/* How many characters in the character set. */
+#define CHAR_SET_SIZE (1 << CHARBITS)
+#define SYNTAX(c) re_syntax_table[c]
+RX_DECL char re_syntax_table[CHAR_SET_SIZE];
+
+#endif /* not emacs */
+
+
+/* Test if at very beginning or at very end of the virtual concatenation
+ * of `string1' and `string2'. If only one string, it's `string2'.
+ */
+
+#define AT_STRINGS_BEG() \
+ ( -1 \
+ == ((search_state.test_pos.pos - search_state.test_pos.string) \
+ + search_state.test_pos.offset))
+
+#define AT_STRINGS_END() \
+ ( (total_size - 1) \
+ == ((search_state.test_pos.pos - search_state.test_pos.string) \
+ + search_state.test_pos.offset))
+
+
+/* Test if POS + 1 points to a character which is word-constituent. We have
+ * two special cases to check for: if past the end of string1, look at
+ * the first character in string2; and if before the beginning of
+ * string2, look at the last character in string1.
+ *
+ * Assumes `string1' exists, so use in conjunction with AT_STRINGS_BEG ().
+ */
+#define LETTER_P(POS,OFF) \
+ ( SYNTAX (fetch_char(POS, OFF, app_closure, stop)) \
+ == Sword)
+
+/* Test if the character at D and the one after D differ with respect
+ * to being word-constituent.
+ */
+#define AT_WORD_BOUNDARY(d) \
+ (AT_STRINGS_BEG () || AT_STRINGS_END () || LETTER_P (d,0) != LETTER_P (d, 1))
+
+
+#ifdef RX_SUPPORT_CONTINUATIONS
+#define RX_STACK_ALLOC(BYTES) malloc(BYTES)
+#define RX_STACK_FREE(MEM) free(MEM)
+#else
+#define RX_STACK_ALLOC(BYTES) alloca(BYTES)
+#define RX_STACK_FREE(MEM) \
+ ((struct rx_stack_chunk *)MEM)->next_chunk = search_state.free_chunks; \
+ search_state.free_chunks = ((struct rx_stack_chunk *)MEM);
+
+#endif
+
+#define PUSH(CHUNK_VAR,BYTES) \
+ if (!CHUNK_VAR || (CHUNK_VAR->bytes_left < (BYTES))) \
+ { \
+ struct rx_stack_chunk * new_chunk; \
+ if (search_state.free_chunks) \
+ { \
+ new_chunk = search_state.free_chunks; \
+ search_state.free_chunks = search_state.free_chunks->next_chunk; \
+ } \
+ else \
+ { \
+ new_chunk = (struct rx_stack_chunk *)RX_STACK_ALLOC(search_state.chunk_bytes); \
+ if (!new_chunk) \
+ { \
+ search_state.ret_val = 0; \
+ goto test_do_return; \
+ } \
+ } \
+ new_chunk->sp = (char *)new_chunk + sizeof (struct rx_stack_chunk); \
+ new_chunk->bytes_left = (search_state.chunk_bytes \
+ - (BYTES) \
+ - sizeof (struct rx_stack_chunk)); \
+ new_chunk->next_chunk = CHUNK_VAR; \
+ CHUNK_VAR = new_chunk; \
+ } \
+ else \
+ (CHUNK_VAR->sp += (BYTES)), (CHUNK_VAR->bytes_left -= (BYTES))
+
+#define POP(CHUNK_VAR,BYTES) \
+ if (CHUNK_VAR->sp == ((char *)CHUNK_VAR + sizeof(*CHUNK_VAR))) \
+ { \
+ struct rx_stack_chunk * new_chunk = CHUNK_VAR->next_chunk; \
+ RX_STACK_FREE(CHUNK_VAR); \
+ CHUNK_VAR = new_chunk; \
+ } \
+ else \
+ (CHUNK_VAR->sp -= BYTES), (CHUNK_VAR->bytes_left += BYTES)
+
+
+
+#define SRCH_TRANSLATE(C) search_state.translate[(unsigned char) (C)]
+
+
+
+
+#ifdef __STDC__
+RX_DECL __inline__ int
+rx_search (struct re_pattern_buffer * rxb,
+ int startpos,
+ int range,
+ int stop,
+ int total_size,
+ rx_get_burst_fn get_burst,
+ rx_back_check_fn back_check,
+ rx_fetch_char_fn fetch_char,
+ void * app_closure,
+ struct re_registers * regs,
+ struct rx_search_state * resume_state,
+ struct rx_search_state * save_state)
+#else
+RX_DECL __inline__ int
+rx_search (rxb, startpos, range, stop, total_size,
+ get_burst, back_check, fetch_char,
+ app_closure, regs, resume_state, save_state)
+ struct re_pattern_buffer * rxb;
+ int startpos;
+ int range;
+ int stop;
+ int total_size;
+ rx_get_burst_fn get_burst;
+ rx_back_check_fn back_check;
+ rx_fetch_char_fn fetch_char;
+ void * app_closure;
+ struct re_registers * regs;
+ struct rx_search_state * resume_state;
+ struct rx_search_state * save_state;
+#endif
+{
+ int pc;
+ int test_state;
+ struct rx_search_state search_state;
+
+ if (!resume_state)
+ pc = rx_outer_start;
+ else
+ {
+ search_state = *resume_state;
+ regs = search_state.saved_regs;
+ rxb = search_state.saved_rxb;
+ startpos = search_state.saved_startpos;
+ range = search_state.saved_range;
+ stop = search_state.saved_stop;
+ total_size = search_state.saved_total_size;
+ get_burst = search_state.saved_get_burst;
+ back_check = search_state.saved_back_check;
+ pc = search_state.outer_search_resume_pt;
+ if (0)
+ {
+ return_continuation:
+ if (save_state)
+ {
+ *save_state = search_state;
+ save_state->saved_regs = regs;
+ save_state->saved_rxb = rxb;
+ save_state->saved_startpos = startpos;
+ save_state->saved_range = range;
+ save_state->saved_stop = stop;
+ save_state->saved_total_size = total_size;
+ save_state->saved_get_burst = get_burst;
+ save_state->saved_back_check = back_check;
+ save_state->outer_search_resume_pt = pc;
+ }
+ return rx_search_continuation;
+ }
+ }
+
+ switch (pc)
+ {
+ case rx_outer_start:
+ search_state.ret_val = rx_search_fail;
+ ( search_state.lparen
+ = search_state.rparen
+ = search_state.best_lpspace
+ = search_state.best_rpspace
+ = 0);
+
+ /* figure the number of registers we may need for use in backreferences.
+ * the number here includes an element for register zero.
+ */
+ search_state.num_regs = rxb->re_nsub + 1;
+
+
+ /* check for out-of-range startpos. */
+ if ((startpos < 0) || (startpos > total_size))
+ return rx_search_fail;
+
+ /* fix up range if it might eventually take us outside the string. */
+ {
+ int endpos;
+ endpos = startpos + range;
+ if (endpos < -1)
+ range = (-1 - startpos);
+ else if (endpos > total_size)
+ range = total_size - startpos;
+ }
+
+ /* if the search isn't to be a backwards one, don't waste time in a
+ * long search for a pattern that says it is anchored.
+ */
+ if (rxb->begbuf_only && (range > 0))
+ {
+ if (startpos > 0)
+ return rx_search_fail;
+ else
+ range = 1;
+ }
+
+ /* decide whether to use internal or user-provided reg buffers. */
+ if (!regs || rxb->no_sub)
+ {
+ search_state.best_lpspace =
+ (regoff_t *)REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t));
+ search_state.best_rpspace =
+ (regoff_t *)REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t));
+ search_state.best_lparen = search_state.best_lpspace;
+ search_state.best_rparen = search_state.best_rpspace;
+ }
+ else
+ {
+ /* have the register data arrays been allocated? */
+ if (rxb->regs_allocated == REGS_UNALLOCATED)
+ { /* no. so allocate them with malloc. we need one
+ extra element beyond `search_state.num_regs' for the `-1' marker
+ gnu code uses. */
+ regs->num_regs = MAX (RE_NREGS, rxb->re_nsub + 1);
+ regs->start = ((regoff_t *)
+ malloc (regs->num_regs * sizeof ( regoff_t)));
+ regs->end = ((regoff_t *)
+ malloc (regs->num_regs * sizeof ( regoff_t)));
+ if (regs->start == 0 || regs->end == 0)
+ return rx_search_error;
+ rxb->regs_allocated = REGS_REALLOCATE;
+ }
+ else if (rxb->regs_allocated == REGS_REALLOCATE)
+ { /* yes. if we need more elements than were already
+ allocated, reallocate them. if we need fewer, just
+ leave it alone. */
+ if (regs->num_regs < search_state.num_regs + 1)
+ {
+ regs->num_regs = search_state.num_regs + 1;
+ regs->start = ((regoff_t *)
+ realloc (regs->start,
+ regs->num_regs * sizeof (regoff_t)));
+ regs->end = ((regoff_t *)
+ realloc (regs->end,
+ regs->num_regs * sizeof ( regoff_t)));
+ if (regs->start == 0 || regs->end == 0)
+ return rx_search_error;
+ }
+ }
+ else if (rxb->regs_allocated != REGS_FIXED)
+ return rx_search_error;
+
+ if (regs->num_regs < search_state.num_regs + 1)
+ {
+ search_state.best_lpspace =
+ ((regoff_t *)
+ REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t)));
+ search_state.best_rpspace =
+ ((regoff_t *)
+ REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t)));
+ search_state.best_lparen = search_state.best_lpspace;
+ search_state.best_rparen = search_state.best_rpspace;
+ }
+ else
+ {
+ search_state.best_lparen = regs->start;
+ search_state.best_rparen = regs->end;
+ }
+ }
+
+ search_state.lparen =
+ (regoff_t *) REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t));
+ search_state.rparen =
+ (regoff_t *) REGEX_ALLOCATE (search_state.num_regs * sizeof(regoff_t));
+
+ if (! ( search_state.best_rparen
+ && search_state.best_lparen
+ && search_state.lparen && search_state.rparen))
+ return rx_search_error;
+
+ search_state.best_last_l = search_state.best_last_r = -1;
+
+ search_state.translate = (rxb->translate
+ ? rxb->translate
+ : rx_id_translation);
+
+
+
+ /*
+ * two nfa's were compiled.
+ * `0' is complete.
+ * `1' faster but gets registers wrong and ends too soon.
+ */
+ search_state.nfa_choice = (regs && !rxb->least_subs) ? '\0' : '\1';
+
+ /* we have the option to look for the best match or the first
+ * one we can find. if the user isn't asking for register information,
+ * we don't need to find the best match.
+ */
+ search_state.first_found = !regs;
+
+ if (range >= 0)
+ {
+ search_state.outer_pos.search_end = MIN (total_size, startpos + range) + 1;
+ search_state.outer_pos.search_direction = 1;
+ }
+ else
+ {
+ search_state.outer_pos.search_end = MAX(-1, startpos + range);
+ search_state.outer_pos.search_direction = -1;
+ }
+
+ /* the vacuous search always turns up nothing. */
+ if ((search_state.outer_pos.search_direction == 1)
+ ? (startpos > search_state.outer_pos.search_end)
+ : (startpos < search_state.outer_pos.search_end))
+ return rx_search_fail;
+
+ /* now we build the starting state of the supernfa. */
+ {
+ struct rx_superset * start_contents;
+ struct rx_nfa_state_set * start_nfa_set;
+
+ /* we presume here that the nfa start state has only one
+ * possible future with no side effects.
+ */
+ start_nfa_set = rxb->start->futures->destset;
+ if ( rxb->rx.start_set
+ && (rxb->rx.start_set->starts_for == &rxb->rx))
+ start_contents = rxb->rx.start_set;
+ else
+ {
+ start_contents =
+ rx_superstate_eclosure_union (&rxb->rx,
+ rx_superset_cons (&rxb->rx, 0, 0),
+ start_nfa_set);
+
+ if (!start_contents)
+ return rx_search_fail;
+
+ start_contents->starts_for = &rxb->rx;
+ rxb->rx.start_set = start_contents;
+ }
+ if ( start_contents->superstate
+ && (start_contents->superstate->rx_id == rxb->rx.rx_id))
+ {
+ search_state.start_super = start_contents->superstate;
+ rx_lock_superstate (&rxb->rx, search_state.start_super);
+ }
+ else
+ {
+ rx_protect_superset (&rxb->rx, start_contents);
+
+ search_state.start_super = rx_superstate (&rxb->rx, start_contents);
+ if (!search_state.start_super)
+ return rx_search_fail;
+ rx_lock_superstate (&rxb->rx, search_state.start_super);
+ rx_release_superset (&rxb->rx, start_contents);
+ }
+ }
+
+
+
+ ( search_state.outer_pos.string
+ = search_state.outer_pos.end
+ = 0);
+
+ search_state.outer_pos.offset = 0;
+ search_state.outer_pos.size = 0;
+ search_state.outer_pos.pos = (unsigned char *)startpos;
+ init_fastmap (rxb, &search_state);
+
+ search_state.fastmap_resume_pt = rx_fastmap_start;
+ case rx_outer_fastmap:
+ /* do { */
+ pseudo_do:
+ {
+ {
+ int fastmap_state;
+ fastmap_state = fastmap_search (rxb, stop, get_burst, app_closure,
+ &search_state);
+ switch (fastmap_state)
+ {
+ case rx_fastmap_continuation:
+ pc = rx_outer_fastmap;
+ goto return_continuation;
+ case rx_fastmap_fail:
+ goto finish;
+ case rx_fastmap_ok:
+ break;
+ }
+ }
+
+ /* now the fastmap loop has brought us to a plausible
+ * starting point for a match. so, it's time to run the
+ * nfa and see if a match occured.
+ */
+ startpos = ( search_state.outer_pos.pos
+ - search_state.outer_pos.string
+ + search_state.outer_pos.offset);
+ if (startpos == search_state.outer_pos.search_end)
+ goto finish;
+ }
+
+ search_state.test_match_resume_pt = rx_test_start;
+ /* do interrupted for entry point... */
+ case rx_outer_test:
+ /* ...do continued */
+ {
+ goto test_match;
+ test_returns_to_search:
+ switch (test_state)
+ {
+ case rx_test_continuation:
+ pc = rx_outer_test;
+ goto return_continuation;
+ case rx_test_error:
+ search_state.ret_val = rx_search_error;
+ goto finish;
+ case rx_test_fail:
+ break;
+ case rx_test_ok:
+ goto finish;
+ }
+ search_state.outer_pos.pos += search_state.outer_pos.search_direction;
+ startpos += search_state.outer_pos.search_direction;
+ }
+ /* do interrupted for entry point... */
+ case rx_outer_restore_pos:
+ {
+ int x;
+ x = get_burst (&search_state.outer_pos, app_closure, stop);
+ switch (x)
+ {
+ case rx_get_burst_continuation:
+ pc = rx_outer_restore_pos;
+ goto return_continuation;
+ case rx_get_burst_error:
+ search_state.ret_val = rx_search_error;
+ goto finish;
+ case rx_get_burst_no_more:
+ goto finish;
+ case rx_get_burst_ok:
+ break;
+ }
+ } /* } while (...see below...) */
+ if ((search_state.outer_pos.search_direction == 1)
+ ? (startpos < search_state.outer_pos.search_end)
+ : (startpos > search_state.outer_pos.search_end))
+ goto pseudo_do;
+
+
+ finish:
+ uninit_fastmap (rxb, &search_state);
+ if (search_state.start_super)
+ rx_unlock_superstate (&rxb->rx, search_state.start_super);
+
+#ifdef regex_malloc
+ if (search_state.lparen) free (search_state.lparen);
+ if (search_state.rparen) free (search_state.rparen);
+ if (search_state.best_lpspace) free (search_state.best_lpspace);
+ if (search_state.best_rpspace) free (search_state.best_rpspace);
+#endif
+ return search_state.ret_val;
+ }
+
+
+ test_match:
+ {
+ enum rx_test_match_entry test_pc;
+ int inx;
+ test_pc = search_state.test_match_resume_pt;
+ if (test_pc == rx_test_start)
+ {
+#ifdef RX_DEBUG
+ search_state.backtrack_depth = 0;
+#endif
+ search_state.last_l = search_state.last_r = 0;
+ search_state.lparen[0] = startpos;
+ search_state.super = search_state.start_super;
+ search_state.c = search_state.nfa_choice;
+ search_state.test_pos.pos = search_state.outer_pos.pos - 1;
+ search_state.test_pos.string = search_state.outer_pos.string;
+ search_state.test_pos.end = search_state.outer_pos.end;
+ search_state.test_pos.offset = search_state.outer_pos.offset;
+ search_state.test_pos.size = search_state.outer_pos.size;
+ search_state.test_pos.search_direction = 1;
+ search_state.counter_stack = 0;
+ search_state.backtrack_stack = 0;
+ search_state.backtrack_frame_bytes =
+ (sizeof (struct rx_backtrack_frame)
+ + (rxb->match_regs_on_stack
+ ? sizeof (regoff_t) * (search_state.num_regs + 1) * 2
+ : 0));
+ search_state.chunk_bytes = search_state.backtrack_frame_bytes * 64;
+ search_state.free_chunks = 0;
+ search_state.test_ret = rx_test_line_finished;
+ search_state.could_have_continued = 0;
+ }
+ /* This is while (1)...except that the body of the loop is interrupted
+ * by some alternative entry points.
+ */
+ pseudo_while_1:
+ switch (test_pc)
+ {
+ case rx_test_cache_hit_loop:
+ goto resume_continuation_1;
+ case rx_test_backreference_check:
+ goto resume_continuation_2;
+ case rx_test_backtrack_return:
+ goto resume_continuation_3;
+ case rx_test_start:
+#ifdef RX_DEBUG
+ /* There is a search tree with every node as set of deterministic
+ * transitions in the super nfa. For every branch of a
+ * backtrack point is an edge in the tree.
+ * This counts up a pre-order of nodes in that tree.
+ * It's saved on the search stack and printed when debugging.
+ */
+ search_state.line_no = 0;
+ search_state.lines_found = 0;
+#endif
+
+ top_of_cycle:
+ /* A superstate is basicly a transition table, indexed by
+ * characters from the string being tested, and containing
+ * RX_INX (`instruction frame') structures.
+ */
+ search_state.ifr = &search_state.super->transitions [search_state.c];
+
+ recurse_test_match:
+ /* This is the point to which control is sent when the
+ * test matcher `recurses'. Before jumping here, some variables
+ * need to be saved on the stack and the next instruction frame
+ * has to be computed.
+ */
+
+ restart:
+ /* Some instructions don't advance the matcher, but just
+ * carry out some side effects and fetch a new instruction.
+ * To dispatch that new instruction, `goto restart'.
+ */
+
+ {
+ struct rx_inx * next_tr_table;
+ struct rx_inx * this_tr_table;
+ /* The fastest route through the loop is when the instruction
+ * is RX_NEXT_CHAR. This case is detected when SEARCH_STATE.IFR->DATA
+ * is non-zero. In that case, it points to the next
+ * superstate.
+ *
+ * This allows us to not bother fetching the bytecode.
+ */
+ next_tr_table = (struct rx_inx *)search_state.ifr->data;
+ this_tr_table = search_state.super->transitions;
+ while (next_tr_table)
+ {
+#ifdef RX_DEBUG
+ if (rx_debug_trace)
+ {
+ struct rx_superset * setp;
+
+ fprintf (stderr, "%d %d>> re_next_char @ %d (%d)",
+ search_state.line_no,
+ search_state.backtrack_depth,
+ (search_state.test_pos.pos - search_state.test_pos.string
+ + search_state.test_pos.offset), search_state.c);
+
+ search_state.super =
+ ((struct rx_superstate *)
+ ((char *)this_tr_table
+ - ((unsigned long)
+ ((struct rx_superstate *)0)->transitions)));
+
+ setp = search_state.super->contents;
+ fprintf (stderr, " superstet (rx=%d, &=%x: ",
+ rxb->rx.rx_id, setp);
+ while (setp)
+ {
+ fprintf (stderr, "%d ", setp->id);
+ setp = setp->cdr;
+ }
+ fprintf (stderr, "\n");
+ }
+#endif
+ this_tr_table = next_tr_table;
+ ++search_state.test_pos.pos;
+ if (search_state.test_pos.pos == search_state.test_pos.end)
+ {
+ int burst_state;
+ try_burst_1:
+ burst_state = get_burst (&search_state.test_pos,
+ app_closure, stop);
+ switch (burst_state)
+ {
+ case rx_get_burst_continuation:
+ search_state.saved_this_tr_table = this_tr_table;
+ search_state.saved_next_tr_table = next_tr_table;
+ test_pc = rx_test_cache_hit_loop;
+ goto test_return_continuation;
+
+ resume_continuation_1:
+ /* Continuation one jumps here to do its work: */
+ search_state.saved_this_tr_table = this_tr_table;
+ search_state.saved_next_tr_table = next_tr_table;
+ goto try_burst_1;
+
+ case rx_get_burst_ok:
+ /* get_burst succeeded...keep going */
+ break;
+
+ case rx_get_burst_no_more:
+ search_state.test_ret = rx_test_line_finished;
+ search_state.could_have_continued = 1;
+ goto test_do_return;
+
+ case rx_get_burst_error:
+ /* An error... */
+ search_state.test_ret = rx_test_internal_error;
+ goto test_do_return;
+ }
+ }
+ search_state.c = *search_state.test_pos.pos;
+ search_state.ifr = this_tr_table + search_state.c;
+ next_tr_table = (struct rx_inx *)search_state.ifr->data;
+ } /* Fast loop through cached transition tables */
+
+ /* Here when we ran out of cached next-char transitions.
+ * So, it will be necessary to do a more expensive
+ * dispatch on the current instruction. The superstate
+ * pointer is allowed to become invalid during next-char
+ * transitions -- now we must bring it up to date.
+ */
+ search_state.super =
+ ((struct rx_superstate *)
+ ((char *)this_tr_table
+ - ((unsigned long)
+ ((struct rx_superstate *)0)->transitions)));
+ }
+
+ /* We've encountered an instruction other than next-char.
+ * Dispatch that instruction:
+ */
+ inx = (int)search_state.ifr->inx;
+#ifdef RX_DEBUG
+ if (rx_debug_trace)
+ {
+ struct rx_superset * setp = search_state.super->contents;
+
+ fprintf (stderr, "%d %d>> %s @ %d (%d)", search_state.line_no,
+ search_state.backtrack_depth,
+ inx_names[inx],
+ (search_state.test_pos.pos - search_state.test_pos.string
+ + (test_pos.half == 0 ? 0 : size1)), search_state.c);
+
+ fprintf (stderr, " superstet (rx=%d, &=%x: ",
+ rxb->rx.rx_id, setp);
+ while (setp)
+ {
+ fprintf (stderr, "%d ", setp->id);
+ setp = setp->cdr;
+ }
+ fprintf (stderr, "\n");
+ }
+#endif
+ switch ((enum rx_opcode)inx)
+ {
+ case rx_do_side_effects:
+
+ /* RX_DO_SIDE_EFFECTS occurs when we cross epsilon
+ * edges associated with parentheses, backreferencing, etc.
+ */
+ {
+ struct rx_distinct_future * df =
+ (struct rx_distinct_future *)search_state.ifr->data_2;
+ struct rx_se_list * el = df->effects;
+ /* Side effects come in lists. This walks down
+ * a list, dispatching.
+ */
+ while (el)
+ {
+ long effect;
+ effect = (long)el->car;
+ if (effect < 0)
+ {
+#ifdef RX_DEBUG
+ if (rx_debug_trace)
+ {
+ struct rx_superset * setp = search_state.super->contents;
+
+ fprintf (stderr, "....%d %d>> %s\n", search_state.line_no,
+ search_state.backtrack_depth,
+ efnames[-effect]);
+ }
+#endif
+ switch ((enum re_side_effects) effect)
+
+ {
+ case re_se_pushback:
+ search_state.ifr = &df->future_frame;
+ if (!search_state.ifr->data)
+ {
+ struct rx_superstate * sup;
+ sup = search_state.super;
+ rx_lock_superstate (rx, sup);
+ if (!rx_handle_cache_miss (&rxb->rx,
+ search_state.super,
+ search_state.c,
+ (search_state.ifr
+ ->data_2)))
+ {
+ rx_unlock_superstate (rx, sup);
+ search_state.test_ret = rx_test_internal_error;
+ goto test_do_return;
+ }
+ rx_unlock_superstate (rx, sup);
+ }
+ /* --search_state.test_pos.pos; */
+ search_state.c = 't';
+ search_state.super
+ = ((struct rx_superstate *)
+ ((char *)search_state.ifr->data
+ - (long)(((struct rx_superstate *)0)
+ ->transitions)));
+ goto top_of_cycle;
+ break;
+ case re_se_push0:
+ {
+ struct rx_counter_frame * old_cf
+ = (search_state.counter_stack
+ ? ((struct rx_counter_frame *)
+ search_state.counter_stack->sp)
+ : 0);
+ struct rx_counter_frame * cf;
+ PUSH (search_state.counter_stack,
+ sizeof (struct rx_counter_frame));
+ cf = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ cf->tag = re_se_iter;
+ cf->val = 0;
+ cf->inherited_from = 0;
+ cf->cdr = old_cf;
+ break;
+ }
+ case re_se_fail:
+ goto test_do_return;
+ case re_se_begbuf:
+ if (!AT_STRINGS_BEG ())
+ goto test_do_return;
+ break;
+ case re_se_endbuf:
+ if (!AT_STRINGS_END ())
+ goto test_do_return;
+ break;
+ case re_se_wordbeg:
+ if ( LETTER_P (&search_state.test_pos, 1)
+ && ( AT_STRINGS_BEG()
+ || !LETTER_P (&search_state.test_pos, 0)))
+ break;
+ else
+ goto test_do_return;
+ case re_se_wordend:
+ if ( !AT_STRINGS_BEG ()
+ && LETTER_P (&search_state.test_pos, 0)
+ && (AT_STRINGS_END ()
+ || !LETTER_P (&search_state.test_pos, 1)))
+ break;
+ else
+ goto test_do_return;
+ case re_se_wordbound:
+ if (AT_WORD_BOUNDARY (&search_state.test_pos))
+ break;
+ else
+ goto test_do_return;
+ case re_se_notwordbound:
+ if (!AT_WORD_BOUNDARY (&search_state.test_pos))
+ break;
+ else
+ goto test_do_return;
+ case re_se_hat:
+ if (AT_STRINGS_BEG ())
+ {
+ if (rxb->not_bol)
+ goto test_do_return;
+ else
+ break;
+ }
+ else
+ {
+ char pos_c = *search_state.test_pos.pos;
+ if ( (SRCH_TRANSLATE (pos_c)
+ == SRCH_TRANSLATE('\n'))
+ && rxb->newline_anchor)
+ break;
+ else
+ goto test_do_return;
+ }
+ case re_se_dollar:
+ if (AT_STRINGS_END ())
+ {
+ if (rxb->not_eol)
+ goto test_do_return;
+ else
+ break;
+ }
+ else
+ {
+ if ( ( SRCH_TRANSLATE (fetch_char
+ (&search_state.test_pos, 1,
+ app_closure, stop))
+ == SRCH_TRANSLATE ('\n'))
+ && rxb->newline_anchor)
+ break;
+ else
+ goto test_do_return;
+ }
+
+ case re_se_try:
+ /* This is the first side effect in every
+ * expression.
+ *
+ * FOR NO GOOD REASON...get rid of it...
+ */
+ break;
+
+ case re_se_pushpos:
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+ struct rx_counter_frame * old_cf
+ = (search_state.counter_stack
+ ? ((struct rx_counter_frame *)
+ search_state.counter_stack->sp)
+ : 0);
+ struct rx_counter_frame * cf;
+ PUSH(search_state.counter_stack,
+ sizeof (struct rx_counter_frame));
+ cf = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ cf->tag = re_se_pushpos;
+ cf->val = urhere;
+ cf->inherited_from = 0;
+ cf->cdr = old_cf;
+ break;
+ }
+
+ case re_se_chkpos:
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+ struct rx_counter_frame * cf
+ = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ if (cf->val == urhere)
+ goto test_do_return;
+ cf->val = urhere;
+ break;
+ }
+ break;
+
+ case re_se_poppos:
+ POP(search_state.counter_stack,
+ sizeof (struct rx_counter_frame));
+ break;
+
+
+ case re_se_at_dot:
+ case re_se_syntax:
+ case re_se_not_syntax:
+#ifdef emacs
+ this release lacks emacs support;
+ (coming soon);
+#endif
+ break;
+ case re_se_win:
+ case re_se_lparen:
+ case re_se_rparen:
+ case re_se_backref:
+ case re_se_iter:
+ case re_se_end_iter:
+ case re_se_tv:
+ case re_floogle_flap:
+ search_state.ret_val = 0;
+ goto test_do_return;
+ }
+ }
+ else
+ {
+#ifdef RX_DEBUG
+ if (rx_debug_trace)
+ fprintf (stderr, "....%d %d>> %s %d %d\n", search_state.line_no,
+ search_state.backtrack_depth,
+ efnames2[rxb->se_params [effect].se],
+ rxb->se_params [effect].op1,
+ rxb->se_params [effect].op2);
+#endif
+ switch (rxb->se_params [effect].se)
+ {
+ case re_se_win:
+ /* This side effect indicates that we've
+ * found a match, though not necessarily the
+ * best match. This is a fancy assignment to
+ * register 0 unless the caller didn't
+ * care about registers. In which case,
+ * this stops the match.
+ */
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+
+ if ( (search_state.best_last_r < 0)
+ || (urhere + 1 > search_state.best_rparen[0]))
+ {
+ /* Record the best known and keep
+ * looking.
+ */
+ int x;
+ for (x = 0; x <= search_state.last_l; ++x)
+ search_state.best_lparen[x] = search_state.lparen[x];
+ search_state.best_last_l = search_state.last_l;
+ for (x = 0; x <= search_state.last_r; ++x)
+ search_state.best_rparen[x] = search_state.rparen[x];
+ search_state.best_rparen[0] = urhere + 1;
+ search_state.best_last_r = search_state.last_r;
+ }
+ /* If we're not reporting the match-length
+ * or other register info, we need look no
+ * further.
+ */
+ if (search_state.first_found)
+ {
+ search_state.test_ret = rx_test_found_first;
+ goto test_do_return;
+ }
+ }
+ break;
+ case re_se_lparen:
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+
+ int reg = rxb->se_params [effect].op1;
+#if 0
+ if (reg > search_state.last_l)
+#endif
+ {
+ search_state.lparen[reg] = urhere + 1;
+ /* In addition to making this assignment,
+ * we now know that lower numbered regs
+ * that haven't already been assigned,
+ * won't be. We make sure they're
+ * filled with -1, so they can be
+ * recognized as unassigned.
+ */
+ if (search_state.last_l < reg)
+ while (++search_state.last_l < reg)
+ search_state.lparen[search_state.last_l] = -1;
+ }
+ break;
+ }
+
+ case re_se_rparen:
+ {
+ int urhere =
+ ((int)(search_state.test_pos.pos
+ - search_state.test_pos.string)
+ + search_state.test_pos.offset);
+ int reg = rxb->se_params [effect].op1;
+ search_state.rparen[reg] = urhere + 1;
+ if (search_state.last_r < reg)
+ {
+ while (++search_state.last_r < reg)
+ search_state.rparen[search_state.last_r]
+ = -1;
+ }
+ break;
+ }
+
+ case re_se_backref:
+ {
+ int reg = rxb->se_params [effect].op1;
+ if ( reg > search_state.last_r
+ || search_state.rparen[reg] < 0)
+ goto test_do_return;
+
+ {
+ int backref_status;
+ check_backreference:
+ backref_status
+ = back_check (&search_state.test_pos,
+ search_state.lparen[reg],
+ search_state.rparen[reg],
+ search_state.translate,
+ app_closure,
+ stop);
+ switch (backref_status)
+ {
+ case rx_back_check_continuation:
+ search_state.saved_reg = reg;
+ test_pc = rx_test_backreference_check;
+ goto test_return_continuation;
+ resume_continuation_2:
+ reg = search_state.saved_reg;
+ goto check_backreference;
+ case rx_back_check_fail:
+ /* Fail */
+ goto test_do_return;
+ case rx_back_check_pass:
+ /* pass --
+ * test_pos now advanced to last
+ * char matched by backref
+ */
+ break;
+ }
+ }
+ break;
+ }
+ case re_se_iter:
+ {
+ struct rx_counter_frame * csp
+ = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ if (csp->val == rxb->se_params[effect].op2)
+ goto test_do_return;
+ else
+ ++csp->val;
+ break;
+ }
+ case re_se_end_iter:
+ {
+ struct rx_counter_frame * csp
+ = ((struct rx_counter_frame *)
+ search_state.counter_stack->sp);
+ if (csp->val < rxb->se_params[effect].op1)
+ goto test_do_return;
+ else
+ {
+ struct rx_counter_frame * source = csp;
+ while (source->inherited_from)
+ source = source->inherited_from;
+ if (!source || !source->cdr)
+ {
+ POP(search_state.counter_stack,
+ sizeof(struct rx_counter_frame));
+ }
+ else
+ {
+ source = source->cdr;
+ csp->val = source->val;
+ csp->tag = source->tag;
+ csp->cdr = 0;
+ csp->inherited_from = source;
+ }
+ }
+ break;
+ }
+ case re_se_tv:
+ /* is a noop */
+ break;
+ case re_se_try:
+ case re_se_pushback:
+ case re_se_push0:
+ case re_se_pushpos:
+ case re_se_chkpos:
+ case re_se_poppos:
+ case re_se_at_dot:
+ case re_se_syntax:
+ case re_se_not_syntax:
+ case re_se_begbuf:
+ case re_se_hat:
+ case re_se_wordbeg:
+ case re_se_wordbound:
+ case re_se_notwordbound:
+ case re_se_wordend:
+ case re_se_endbuf:
+ case re_se_dollar:
+ case re_se_fail:
+ case re_floogle_flap:
+ search_state.ret_val = 0;
+ goto test_do_return;
+ }
+ }
+ el = el->cdr;
+ }
+ /* Now the side effects are done,
+ * so get the next instruction.
+ * and move on.
+ */
+ search_state.ifr = &df->future_frame;
+ goto restart;
+ }
+
+ case rx_backtrack_point:
+ {
+ /* A backtrack point indicates that we've reached a
+ * non-determinism in the superstate NFA. This is a
+ * loop that exhaustively searches the possibilities.
+ *
+ * A backtracking strategy is used. We keep track of what
+ * registers are valid so we can erase side effects.
+ *
+ * First, make sure there is some stack space to hold
+ * our state.
+ */
+
+ struct rx_backtrack_frame * bf;
+
+ PUSH(search_state.backtrack_stack,
+ search_state.backtrack_frame_bytes);
+#ifdef RX_DEBUG
+ ++search_state.backtrack_depth;
+#endif
+
+ bf = ((struct rx_backtrack_frame *)
+ search_state.backtrack_stack->sp);
+ {
+ bf->stk_super = search_state.super;
+ /* We prevent the current superstate from being
+ * deleted from the superstate cache.
+ */
+ rx_lock_superstate (&rxb->rx, search_state.super);
+#ifdef RX_DEBUG
+ bf->stk_search_state.line_no = search_state.line_no;
+#endif
+ bf->stk_c = search_state.c;
+ bf->stk_test_pos = search_state.test_pos;
+ bf->stk_last_l = search_state.last_l;
+ bf->stk_last_r = search_state.last_r;
+ bf->df = ((struct rx_super_edge *)
+ search_state.ifr->data_2)->options;
+ bf->first_df = bf->df;
+ bf->counter_stack_sp = (search_state.counter_stack
+ ? search_state.counter_stack->sp
+ : 0);
+ bf->stk_test_ret = search_state.test_ret;
+ if (rxb->match_regs_on_stack)
+ {
+ int x;
+ regoff_t * stk =
+ (regoff_t *)((char *)bf + sizeof (*bf));
+ for (x = 0; x <= search_state.last_l; ++x)
+ stk[x] = search_state.lparen[x];
+ stk += x;
+ for (x = 0; x <= search_state.last_r; ++x)
+ stk[x] = search_state.rparen[x];
+ }
+ }
+
+ /* Here is a while loop whose body is mainly a function
+ * call and some code to handle a return from that
+ * function.
+ *
+ * From here on for the rest of `case backtrack_point' it
+ * is unsafe to assume that the search_state copies of
+ * variables saved on the backtracking stack are valid
+ * -- so read their values from the backtracking stack.
+ *
+ * This lets us use one generation fewer stack saves in
+ * the call-graph of a search.
+ */
+
+ while_non_det_options:
+#ifdef RX_DEBUG
+ ++search_state.lines_found;
+ if (rx_debug_trace)
+ fprintf (stderr, "@@@ %d calls %d @@@\n",
+ search_state.line_no, search_state.lines_found);
+
+ search_state.line_no = search_state.lines_found;
+#endif
+
+ if (bf->df->next_same_super_edge[0] == bf->first_df)
+ {
+ /* This is a tail-call optimization -- we don't recurse
+ * for the last of the possible futures.
+ */
+ search_state.ifr = (bf->df->effects
+ ? &bf->df->side_effects_frame
+ : &bf->df->future_frame);
+
+ rx_unlock_superstate (&rxb->rx, search_state.super);
+ POP(search_state.backtrack_stack,
+ search_state.backtrack_frame_bytes);
+#ifdef RX_DEBUG
+ --search_state.backtrack_depth;
+#endif
+ goto restart;
+ }
+ else
+ {
+ if (search_state.counter_stack)
+ {
+ struct rx_counter_frame * old_cf
+ = ((struct rx_counter_frame *)search_state.counter_stack->sp);
+ struct rx_counter_frame * cf;
+ PUSH(search_state.counter_stack, sizeof (struct rx_counter_frame));
+ cf = ((struct rx_counter_frame *)search_state.counter_stack->sp);
+ cf->tag = old_cf->tag;
+ cf->val = old_cf->val;
+ cf->inherited_from = old_cf;
+ cf->cdr = 0;
+ }
+ /* `Call' this test-match block */
+ search_state.ifr = (bf->df->effects
+ ? &bf->df->side_effects_frame
+ : &bf->df->future_frame);
+ goto recurse_test_match;
+ }
+
+ /* Returns in this block are accomplished by
+ * goto test_do_return. There are two cases.
+ * If there is some search-stack left,
+ * then it is a return from a `recursive' call.
+ * If there is no search-stack left, then
+ * we should return to the fastmap/search loop.
+ */
+
+ test_do_return:
+
+ if (!search_state.backtrack_stack)
+ {
+#ifdef RX_DEBUG
+ if (rx_debug_trace)
+ fprintf (stderr, "!!! %d bails returning %d !!!\n",
+ search_state.line_no, search_state.test_ret);
+#endif
+
+ /* No more search-stack -- this test is done. */
+ if (search_state.test_ret)
+ goto return_from_test_match;
+ else
+ goto error_in_testing_match;
+ }
+
+ /* Returning from a recursive call to
+ * the test match block:
+ */
+
+ bf = ((struct rx_backtrack_frame *)
+ search_state.backtrack_stack->sp);
+#ifdef RX_DEBUG
+ if (rx_debug_trace)
+ fprintf (stderr, "+++ %d returns %d (to %d)+++\n",
+ search_state.line_no,
+ search_state.test_ret,
+ bf->stk_search_state.line_no);
+#endif
+
+ while (search_state.counter_stack
+ && (!bf->counter_stack_sp
+ || (bf->counter_stack_sp
+ != search_state.counter_stack->sp)))
+ {
+ POP(search_state.counter_stack,
+ sizeof (struct rx_counter_frame));
+ }
+
+ if (search_state.test_ret == rx_test_error)
+ {
+ POP (search_state.backtrack_stack,
+ search_state.backtrack_frame_bytes);
+ goto test_do_return;
+ }
+
+ /* If a non-longest match was found and that is good
+ * enough, return immediately.
+ */
+ if ( (search_state.test_ret == rx_test_found_first)
+ && search_state.first_found)
+ {
+ rx_unlock_superstate (&rxb->rx, bf->stk_super);
+ POP (search_state.backtrack_stack,
+ search_state.backtrack_frame_bytes);
+ goto test_do_return;
+ }
+
+ search_state.test_ret = bf->stk_test_ret;
+ search_state.last_l = bf->stk_last_l;
+ search_state.last_r = bf->stk_last_r;
+ bf->df = bf->df->next_same_super_edge[0];
+ search_state.super = bf->stk_super;
+ search_state.c = bf->stk_c;
+#ifdef RX_DEBUG
+ search_state.line_no = bf->stk_search_state.line_no;
+#endif
+
+ if (rxb->match_regs_on_stack)
+ {
+ int x;
+ regoff_t * stk =
+ (regoff_t *)((char *)bf + sizeof (*bf));
+ for (x = 0; x <= search_state.last_l; ++x)
+ search_state.lparen[x] = stk[x];
+ stk += x;
+ for (x = 0; x <= search_state.last_r; ++x)
+ search_state.rparen[x] = stk[x];
+ }
+
+ {
+ int x;
+ try_burst_2:
+ x = get_burst (&bf->stk_test_pos, app_closure, stop);
+ switch (x)
+ {
+ case rx_get_burst_continuation:
+ search_state.saved_bf = bf;
+ test_pc = rx_test_backtrack_return;
+ goto test_return_continuation;
+ resume_continuation_3:
+ bf = search_state.saved_bf;
+ goto try_burst_2;
+ case rx_get_burst_no_more:
+ /* Since we've been here before, it is some kind of
+ * error that we can't return.
+ */
+ case rx_get_burst_error:
+ search_state.test_ret = rx_test_internal_error;
+ goto test_do_return;
+ case rx_get_burst_ok:
+ break;
+ }
+ }
+ search_state.test_pos = bf->stk_test_pos;
+ goto while_non_det_options;
+ }
+
+
+ case rx_cache_miss:
+ /* Because the superstate NFA is lazily constructed,
+ * and in fact may erode from underneath us, we sometimes
+ * have to construct the next instruction from the hard way.
+ * This invokes one step in the lazy-conversion.
+ */
+ search_state.ifr = rx_handle_cache_miss (&rxb->rx,
+ search_state.super,
+ search_state.c,
+ search_state.ifr->data_2);
+ if (!search_state.ifr)
+ {
+ search_state.test_ret = rx_test_internal_error;
+ goto test_do_return;
+ }
+ goto restart;
+
+ case rx_backtrack:
+ /* RX_BACKTRACK means that we've reached the empty
+ * superstate, indicating that match can't succeed
+ * from this point.
+ */
+ goto test_do_return;
+
+ case rx_next_char:
+ case rx_error_inx:
+ case rx_num_instructions:
+ search_state.ret_val = 0;
+ goto test_do_return;
+ }
+ goto pseudo_while_1;
+ }
+
+ /* Healthy exits from the test-match loop do a
+ * `goto return_from_test_match' On the other hand,
+ * we might end up here.
+ */
+ error_in_testing_match:
+ test_state = rx_test_error;
+ goto test_returns_to_search;
+
+ /***** fastmap/search loop body
+ * considering the results testing for a match
+ */
+
+ return_from_test_match:
+
+ if (search_state.best_last_l >= 0)
+ {
+ if (regs && (regs->start != search_state.best_lparen))
+ {
+ bcopy (search_state.best_lparen, regs->start,
+ regs->num_regs * sizeof (int));
+ bcopy (search_state.best_rparen, regs->end,
+ regs->num_regs * sizeof (int));
+ }
+ if (regs && !rxb->no_sub)
+ {
+ int q;
+ int bound = (regs->num_regs > search_state.num_regs
+ ? regs->num_regs
+ : search_state.num_regs);
+ regoff_t * s = regs->start;
+ regoff_t * e = regs->end;
+ for (q = search_state.best_last_l + 1; q < bound; ++q)
+ s[q] = e[q] = -1;
+ }
+ search_state.ret_val = search_state.best_lparen[0];
+ test_state = rx_test_ok;
+ goto test_returns_to_search;
+ }
+ else
+ {
+ test_state = rx_test_fail;
+ goto test_returns_to_search;
+ }
+
+ test_return_continuation:
+ search_state.test_match_resume_pt = test_pc;
+ test_state = rx_test_continuation;
+ goto test_returns_to_search;
+ }
+}
+
+
+
+#endif /* RX_WANT_RX_DEFS */
+
+
+
+#else /* RX_WANT_SE_DEFS */
+ /* Integers are used to represent side effects.
+ *
+ * Simple side effects are given negative integer names by these enums.
+ *
+ * Non-negative names are reserved for complex effects.
+ *
+ * Complex effects are those that take arguments. For example,
+ * a register assignment associated with a group is complex because
+ * it requires an argument to tell which group is being matched.
+ *
+ * The integer name of a complex effect is an index into rxb->se_params.
+ */
+
+ RX_DEF_SE(1, re_se_try, = -1) /* Epsilon from start state */
+
+ RX_DEF_SE(0, re_se_pushback, = re_se_try - 1)
+ RX_DEF_SE(0, re_se_push0, = re_se_pushback -1)
+ RX_DEF_SE(0, re_se_pushpos, = re_se_push0 - 1)
+ RX_DEF_SE(0, re_se_chkpos, = re_se_pushpos -1)
+ RX_DEF_SE(0, re_se_poppos, = re_se_chkpos - 1)
+
+ RX_DEF_SE(1, re_se_at_dot, = re_se_poppos - 1) /* Emacs only */
+ RX_DEF_SE(0, re_se_syntax, = re_se_at_dot - 1) /* Emacs only */
+ RX_DEF_SE(0, re_se_not_syntax, = re_se_syntax - 1) /* Emacs only */
+
+ RX_DEF_SE(1, re_se_begbuf, = re_se_not_syntax - 1) /* match beginning of buffer */
+ RX_DEF_SE(1, re_se_hat, = re_se_begbuf - 1) /* match beginning of line */
+
+ RX_DEF_SE(1, re_se_wordbeg, = re_se_hat - 1)
+ RX_DEF_SE(1, re_se_wordbound, = re_se_wordbeg - 1)
+ RX_DEF_SE(1, re_se_notwordbound, = re_se_wordbound - 1)
+
+ RX_DEF_SE(1, re_se_wordend, = re_se_notwordbound - 1)
+ RX_DEF_SE(1, re_se_endbuf, = re_se_wordend - 1)
+
+ /* This fails except at the end of a line.
+ * It deserves to go here since it is typicly one of the last steps
+ * in a match.
+ */
+ RX_DEF_SE(1, re_se_dollar, = re_se_endbuf - 1)
+
+ /* Simple effects: */
+ RX_DEF_SE(1, re_se_fail, = re_se_dollar - 1)
+
+ /* Complex effects. These are used in the 'se' field of
+ * a struct re_se_params. Indexes into the se array
+ * are stored as instructions on nfa edges.
+ */
+ RX_DEF_CPLX_SE(1, re_se_win, = 0)
+ RX_DEF_CPLX_SE(1, re_se_lparen, = re_se_win + 1)
+ RX_DEF_CPLX_SE(1, re_se_rparen, = re_se_lparen + 1)
+ RX_DEF_CPLX_SE(0, re_se_backref, = re_se_rparen + 1)
+ RX_DEF_CPLX_SE(0, re_se_iter, = re_se_backref + 1)
+ RX_DEF_CPLX_SE(0, re_se_end_iter, = re_se_iter + 1)
+ RX_DEF_CPLX_SE(0, re_se_tv, = re_se_end_iter + 1)
+
+#endif
+
+#endif
diff --git a/gnu/lib/libg++/include/streambuf.h b/gnu/lib/libg++/include/streambuf.h
index 60181a4ffad7..efbab12c2b59 100644
--- a/gnu/lib/libg++/include/streambuf.h
+++ b/gnu/lib/libg++/include/streambuf.h
@@ -117,6 +117,7 @@ enum open_mode {
#endif
class ios : public _ios_fields {
+ ios& operator=(ios&); /* Not allowed! */
public:
typedef __fmtflags fmtflags;
typedef int iostate;
@@ -200,10 +201,8 @@ class ios : public _ios_fields {
void _IO_fix_vtable(); /* TEMPORARY - for binary compatibility */
void _IO_fix_vtable() const; /* TEMPORARY - for binary compatibility */
#endif
-#if 0
streambuf* rdbuf(streambuf *_s) {
- streambuf *_old = _strbuf; _strbuf = _s; return _old; }
-#endif
+ streambuf *_old = _strbuf; _strbuf = _s; clear (); return _old; }
void clear(iostate state = 0) {
_state = _strbuf ? state : state|badbit;
if (_state & _exceptions) _throw_failure(); }
diff --git a/gnu/lib/libg++/libg++/ACG.cc b/gnu/lib/libg++/libg++/ACG.cc
index 27e7aa22564c..620608027172 100644
--- a/gnu/lib/libg++/libg++/ACG.cc
+++ b/gnu/lib/libg++/libg++/ACG.cc
@@ -123,7 +123,7 @@ static randomStateTable[][3] = {
//
#define RANDOM_PERM_SIZE 64
-unsigned long randomPermutations[RANDOM_PERM_SIZE] = {
+_G_uint32_t randomPermutations[RANDOM_PERM_SIZE] = {
0xffffffff, 0x00000000, 0x00000000, 0x00000000, // 3210
0x0000ffff, 0x00ff0000, 0x00000000, 0xff000000, // 2310
0xff0000ff, 0x0000ff00, 0x00000000, 0x00ff0000, // 3120
@@ -149,7 +149,7 @@ unsigned long randomPermutations[RANDOM_PERM_SIZE] = {
// SEED_TABLE_SIZE must be a power of 2
//
#define SEED_TABLE_SIZE 32
-static unsigned long seedTable[SEED_TABLE_SIZE] = {
+static _G_uint32_t seedTable[SEED_TABLE_SIZE] = {
0xbdcc47e5, 0x54aea45d, 0xec0df859, 0xda84637b,
0xc8c6cb4f, 0x35574b01, 0x28260b7d, 0x0d07fdbf,
0x9faaeeb0, 0x613dd169, 0x5ce2d818, 0x85b9e706,
@@ -171,15 +171,15 @@ static unsigned long seedTable[SEED_TABLE_SIZE] = {
// LC_C = result of a long trial & error series = 3907864577
//
-static const unsigned long LC_A = 66049;
-static const unsigned long LC_C = 3907864577;
-static inline unsigned long LCG(unsigned long x)
+static const _G_uint32_t LC_A = 66049;
+static const _G_uint32_t LC_C = 3907864577;
+static inline _G_uint32_t LCG(_G_uint32_t x)
{
return( x * LC_A + LC_C );
}
-ACG::ACG(unsigned long seed, int size)
+ACG::ACG(_G_uint32_t seed, int size)
{
initialSeed = seed;
@@ -205,7 +205,7 @@ ACG::ACG(unsigned long seed, int size)
// Allocate the state table & the auxillary table in a single malloc
//
- state = new unsigned long[stateSize + auxSize];
+ state = new _G_uint32_t[stateSize + auxSize];
auxState = &state[stateSize];
reset();
@@ -217,7 +217,7 @@ ACG::ACG(unsigned long seed, int size)
void
ACG::reset()
{
- register unsigned long u;
+ register _G_uint32_t u;
if (initialSeed < SEED_TABLE_SIZE) {
u = seedTable[ initialSeed ];
@@ -247,7 +247,7 @@ ACG::reset()
lcgRecurr = u;
- assert(sizeof(double) == 2 * sizeof(long));
+ assert(sizeof(double) == 2 * sizeof(_G_int32_t));
}
ACG::~ACG()
@@ -261,15 +261,16 @@ ACG::~ACG()
// Returns 32 bits of random information.
//
-unsigned long ACG::asLong()
+_G_uint32_t
+ACG::asLong()
{
- unsigned long result = state[k] + state[j];
+ _G_uint32_t result = state[k] + state[j];
state[k] = result;
j = (j <= 0) ? (stateSize-1) : (j-1);
k = (k <= 0) ? (stateSize-1) : (k-1);
short int auxIndex = (result >> 24) & (auxSize - 1);
- register unsigned long auxACG = auxState[auxIndex];
+ register _G_uint32_t auxACG = auxState[auxIndex];
auxState[auxIndex] = lcgRecurr = LCG(lcgRecurr);
//
@@ -277,7 +278,7 @@ unsigned long ACG::asLong()
// do not want to run off the end of the permutation table.
// This insures that we have always got four entries left.
//
- register unsigned long *perm = & randomPermutations[result & 0x3c];
+ register _G_uint32_t *perm = & randomPermutations[result & 0x3c];
result = *(perm++) & auxACG;
result |= *(perm++) & ((auxACG << 24)
diff --git a/gnu/lib/libg++/libg++/DLList.cc b/gnu/lib/libg++/libg++/DLList.cc
index 87874c37656d..ff8a81b89002 100644
--- a/gnu/lib/libg++/libg++/DLList.cc
+++ b/gnu/lib/libg++/libg++/DLList.cc
@@ -25,7 +25,7 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#include <builtin.h>
#include "DLList.h"
-void BaseDLList::error(const char* msg)
+void BaseDLList::error(const char* msg) const
{
(*lib_error_handler)("DLList", msg);
}
@@ -164,7 +164,7 @@ void BaseDLList::join(BaseDLList& b)
}
}
-int BaseDLList::owns(Pix p)
+int BaseDLList::owns(Pix p) const
{
BaseDLNode* t = h;
if (t != 0 && p != 0)
@@ -207,7 +207,7 @@ void BaseDLList::del(Pix& p, int dir)
t->fd->bk = t->bk;
if (t == h) h = t->fd;
}
- delete t;
+ delete_node(t);
}
void BaseDLList::del_after(Pix& p)
@@ -305,7 +305,7 @@ void BaseDLList::del_rear()
}
-int BaseDLList::OK()
+int BaseDLList::OK() const
{
int v = 1;
if (h != 0)
diff --git a/gnu/lib/libg++/libg++/Fix.cc b/gnu/lib/libg++/libg++/Fix.cc
index f067eb3ddb39..7e9e4742f186 100644
--- a/gnu/lib/libg++/libg++/Fix.cc
+++ b/gnu/lib/libg++/libg++/Fix.cc
@@ -347,7 +347,7 @@ Fix::multiply(const Rep* x, int y, Rep* r)
a = (_G_int32_t) (_G_int16_t )x->s[0] * y + carry;
r->s[0] = a;
a &= 0xffff8000L;
- if ( a != 0xffff8000L && a != 0L ) {
+ if ( a != (_G_int32_t)0xffff8000L && a != (_G_int32_t)0L ) {
r->s[0] = 0x8000 ^ x->s[0] ^ y;
overflow_handler(r);
}
@@ -419,7 +419,7 @@ Fix::shift(const Rep* x, int y, Rep* r)
return r;
}
- int ay = abs((long) y),
+ int ay = abs((_G_int32_t) y),
ayh = ay >> 4,
ayl = ay & 0x0f;
int xl, u, ilow, ihigh;
@@ -492,7 +492,7 @@ Fix::printon(ostream& s, int width) const
{
double val = value(*this);
int old_precision = s.precision(width-3);
- long old_flags = s.setf(ios::fixed, ios::fixed|ios::scientific);
+ _G_int32_t old_flags = s.setf(ios::fixed, ios::fixed|ios::scientific);
if (val >= 0)
s << ' ';
s.width(width-2);
diff --git a/gnu/lib/libg++/libg++/Fix16.cc b/gnu/lib/libg++/libg++/Fix16.cc
index a66bfbf9b19d..3974fb316255 100644
--- a/gnu/lib/libg++/libg++/Fix16.cc
+++ b/gnu/lib/libg++/libg++/Fix16.cc
@@ -48,19 +48,19 @@ short Fix16::assign(double d)
return round(Fix16_mult * d);
}
-long Fix32::assign(double d)
+_G_int32_t Fix32::assign(double d)
{
if (d == 1.0)
return Fix32_m_max;
else if (d > Fix32_max)
{
- long i = Fix32_m_max;
+ _G_int32_t i = Fix32_m_max;
range_error(i);
return i;
}
else if (d < Fix32_min)
{
- long i = Fix32_m_min;
+ _G_int32_t i = Fix32_m_min;
range_error(i);
return i;
}
@@ -75,20 +75,20 @@ Fix32 operator * (const Fix32& a, const Fix32& b)
// multiply, with rounding
int apos = (a.m >= 0);
- unsigned long ua = (apos)? a.m : - a.m;
+ _G_uint32_t ua = (apos)? a.m : - a.m;
ua <<= 1; // ua is biased so result will be 31 bit mantissa, not 30:
- unsigned long hi_a = (ua >> 16) & ((1 << 16) - 1);
- unsigned long lo_a = ua & ((1 << 16) - 1);
+ _G_uint32_t hi_a = (ua >> 16) & ((1 << 16) - 1);
+ _G_uint32_t lo_a = ua & ((1 << 16) - 1);
int bpos = (b.m >= 0);
- unsigned long ub = (bpos)? b.m : -b.m;
- unsigned long hi_b = (ub >> 16) & ((1 << 16) - 1);
- unsigned long lo_b = ub & ((1 << 16) - 1);
+ _G_uint32_t ub = (bpos)? b.m : -b.m;
+ _G_uint32_t hi_b = (ub >> 16) & ((1 << 16) - 1);
+ _G_uint32_t lo_b = ub & ((1 << 16) - 1);
- unsigned long r = lo_a * lo_b + (1 << 15);
+ _G_uint32_t r = lo_a * lo_b + (1 << 15);
r = (r >> 16) + hi_a * lo_b + lo_a * hi_b + (1 << 15);
r = (r >> 16) + hi_a * hi_b;
- long p = (apos != bpos)? -r : r;
+ _G_int32_t p = (apos != bpos)? -r : r;
return Fix32(p);
}
@@ -96,8 +96,8 @@ Fix16 operator / (const Fix16& a, const Fix16& b)
{
short q;
int apos = (a.m >= 0);
- long la = (apos)? a.m : -a.m;
- long scaled_a = la << 15;
+ _G_int32_t la = (apos)? a.m : -a.m;
+ _G_int32_t scaled_a = la << 15;
int bpos = (b.m >= 0);
short sb = (bpos)? b.m: -b.m;
if (la >= sb)
@@ -116,11 +116,11 @@ Fix16 operator / (const Fix16& a, const Fix16& b)
Fix32 operator / (const Fix32& a, const Fix32& b)
{
- long q;
+ _G_int32_t q;
int apos = (a.m >= 0);
- unsigned long la = (apos)? a.m : -a.m;
+ _G_uint32_t la = (apos)? a.m : -a.m;
int bpos = (b.m >= 0);
- unsigned long lb = (bpos)? b.m: -b.m;
+ _G_uint32_t lb = (bpos)? b.m: -b.m;
if (la >= lb)
{
q = (apos == bpos)? Fix32_m_max: Fix32_m_min;
@@ -129,7 +129,7 @@ Fix32 operator / (const Fix32& a, const Fix32& b)
else // standard shift-based division alg
{
q = 0;
- long r = la;
+ _G_int32_t r = la;
for (int i = 32; i > 0; i--)
{
@@ -155,7 +155,7 @@ void Fix16::overflow(short& i) const
(*Fix16_overflow_handler)(i);
}
-void Fix32::overflow(long& i) const
+void Fix32::overflow(_G_int32_t& i) const
{
(*Fix32_overflow_handler)(i);
}
@@ -165,7 +165,7 @@ void Fix16::range_error(short& i) const
(*Fix16_range_error_handler)(i);
}
-void Fix32::range_error(long& i) const
+void Fix32::range_error(_G_int32_t& i) const
{
(*Fix32_range_error_handler)(i);
}
@@ -225,14 +225,14 @@ void Fix16_overflow_warning_saturate(short& i)
void Fix16_abort(short&)
{ cerr << "error: Fix16 result out of range\n"; abort(); }
-void Fix32_ignore(long&) {}
-void Fix32_overflow_saturate(long& i)
+void Fix32_ignore(_G_int32_t&) {}
+void Fix32_overflow_saturate(_G_int32_t& i)
{ i = (i > 0 ? Fix32_m_min : Fix32_m_max); }
-void Fix32_warning(long&)
+void Fix32_warning(_G_int32_t&)
{ cerr << "warning: Fix32 result out of range\n"; }
-void Fix32_overflow_warning_saturate(long& i)
+void Fix32_overflow_warning_saturate(_G_int32_t& i)
{ cerr << "warning: Fix32 result out of range\n";
Fix32_overflow_saturate(i); }
-void Fix32_abort(long&)
+void Fix32_abort(_G_int32_t&)
{ cerr << "error: Fix32 result out of range\n"; abort(); }
diff --git a/gnu/lib/libg++/libg++/Fix24.cc b/gnu/lib/libg++/libg++/Fix24.cc
index 22e23dcbcf2a..84cb83486eb3 100644
--- a/gnu/lib/libg++/libg++/Fix24.cc
+++ b/gnu/lib/libg++/libg++/Fix24.cc
@@ -28,25 +28,27 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
// basic operators too large to be inline
-long Fix24::assign(double d)
+_G_int32_t Fix24::assign(double d)
{
if (d == 1.0)
return Fix24_m_max;
else if (d > Fix24_max)
{
- long i = Fix24_m_max;
+ _G_int32_t i = Fix24_m_max;
range_error(i);
return i;
}
else if (d < Fix24_min)
{
- long i = Fix24_m_min;
+ _G_int32_t i = Fix24_m_min;
range_error(i);
return i;
}
else {
- d = (long) (d * (1 << 24) + ((d >= 0)? 0.5 : -0.5)); // Round to 24 bits
- return ((long) d) << (Fix24_shift - 24); /* Convert to integer format */
+ // Round to 24 bits
+ d = (_G_int32_t) (d * (1 << 24) + ((d >= 0)? 0.5 : -0.5));
+ /* Convert to integer format */
+ return ((_G_int32_t) d) << (Fix24_shift - 24);
}
}
@@ -72,14 +74,14 @@ twolongs Fix48::assign(double d)
/* First, convert the absolute value of d to a 48-bit integer format */
if (d < 0) d = -d;
- i.u = ((long)(d *= Fix24_mult)) & 0xffffff00;
- i.l = ((unsigned long)((d - i.u)* (Fix24_mult / (1 << 7)))) & 0xffffff00;
+ i.u = ((_G_int32_t)(d *= Fix24_mult)) & 0xffffff00;
+ i.l = ((_G_uint32_t)((d - i.u)* (Fix24_mult / (1 << 7)))) & 0xffffff00;
/* Calculate the two's complement if d was negative */
if (sign) {
- unsigned long oldlower = i.l;
+ _G_uint32_t oldlower = i.l;
i.l = (~i.l + 1) & 0xffffff00;
- i.u = (~i.u + (((oldlower ^ i.l) & Fix24_msb)? 0 : 1)) & 0xffffff00;
+ i.u = (~i.u + (((oldlower ^ i.l) & Fix24_msb)? 0 : 1)) & ~0xffL;
}
return i;
}
@@ -92,17 +94,17 @@ Fix48 operator * (const Fix24& a, const Fix24& b)
// multiply, with rounding
int apos = (a.m >= 0);
- unsigned long ua = (apos)? a.m : - a.m;
+ _G_uint32_t ua = (apos)? a.m : - a.m;
ua <<= 1; // ua is biased so result will be 47 bit mantissa, not 46:
- unsigned long hi_a = (ua >> 16) & ((1 << 16) - 1);
- unsigned long lo_a = ua & ((1 << 16) - 1);
+ _G_uint32_t hi_a = (ua >> 16) & ((1 << 16) - 1);
+ _G_uint32_t lo_a = ua & ((1 << 16) - 1);
int bpos = (b.m >= 0);
- unsigned long ub = (bpos)? b.m : -b.m;
- unsigned long hi_b = (ub >> 16) & ((1 << 16) - 1);
- unsigned long lo_b = ub & ((1 << 16) - 1);
+ _G_uint32_t ub = (bpos)? b.m : -b.m;
+ _G_uint32_t hi_b = (ub >> 16) & ((1 << 16) - 1);
+ _G_uint32_t lo_b = ub & ((1 << 16) - 1);
- unsigned long
+ _G_uint32_t
hi_r = hi_a * hi_b,
mi_r = hi_a * lo_b + lo_a * hi_b,
lo_r = lo_a * lo_b,
@@ -113,7 +115,7 @@ Fix48 operator * (const Fix24& a, const Fix24& b)
r.l = rl << 8;
if ( apos != bpos ) {
- unsigned long l = r.l;
+ _G_uint32_t l = r.l;
r.l = -r.l;
r.u = (~r.u + ((l ^ r.l) & Fix24_msb ? 0 : Fix24_lsb)) & 0xffffff00;
}
@@ -122,11 +124,11 @@ Fix48 operator * (const Fix24& a, const Fix24& b)
Fix24 operator / (const Fix24& a, const Fix24& b)
{
- long q;
+ _G_int32_t q;
int apos = (a.m >= 0);
- unsigned long la = (apos)? a.m : -a.m;
+ _G_uint32_t la = (apos)? a.m : -a.m;
int bpos = (b.m >= 0);
- unsigned long lb = (bpos)? b.m: -b.m;
+ _G_uint32_t lb = (bpos)? b.m: -b.m;
if (la >= lb)
{
q = (apos == bpos)? Fix24_m_max: Fix24_m_min;
@@ -135,7 +137,7 @@ Fix24 operator / (const Fix24& a, const Fix24& b)
else // standard shift-based division alg
{
q = 0;
- long r = la;
+ _G_int32_t r = la;
for (int i = 32; i > 0; i--)
{
@@ -151,13 +153,13 @@ Fix24 operator / (const Fix24& a, const Fix24& b)
q += 0x80; // Round result to 24 bits
if (apos != bpos) q = -q; // Fix sign
}
- return (q & ~0xFF);
+ return (q & ~0xff);
}
Fix48 operator + (const Fix48& f, const Fix48& g)
{
- long lo_r = (f.m.l >> 8) + (g.m.l >> 8);
+ _G_int32_t lo_r = (f.m.l >> 8) + (g.m.l >> 8);
twolongs r;
r.u = f.m.u + g.m.u + (lo_r & 0x01000000L ? 0x00000100L : 0);
r.l = lo_r << 8;
@@ -189,15 +191,15 @@ Fix48 operator * (const Fix48& a, int b)
a.range_error(r);
}
else {
- unsigned long
+ _G_uint32_t
lo_r = (a.m.l & 0xffff) * ub,
mi_r = ((a.m.l >> 16) & 0xffff) * ub,
hi_r = a.m.u * ub;
r.l = lo_r + (mi_r << 16);
r.u = hi_r + ((mi_r >> 8) & 0x00ffff00L);
if ( !bpos ) {
- unsigned long l = r.l;
- r.l = -r.l;
+ _G_uint32_t l = r.l;
+ r.l = -r.l & 0xffffffff;
r.u = ~r.u + ((l ^ r.l) & Fix24_msb ? 0 : Fix24_lsb);
}
}
@@ -223,15 +225,15 @@ Fix48 operator >> (const Fix48& a, int b)
twolongs r; r.u = 0; r.l = 0;
if ( b >= 0 )
if ( b < 24 ) {
- r.l = (a.m.u << (24 - b)) + ((a.m.l >> b) & 0xffffff00L);
- r.u = (a.m.u >> b) & 0xffffff00L;
+ r.l = ((a.m.u << (24 - b)) & 0xffffffffL) + ((a.m.l >> b) & 0xffffff00L);
+ r.u = (a.m.u >> b) & ~0xffL;
}
else if ( b < 48 ) {
r.l = (a.m.u >> (b - 24)) & 0xffffff00L;
- r.u = (a.m.u >> 24) & 0xffffff00L;
+ r.u = (a.m.u >> 24) & ~0xffL;
}
else {
- r.l = (a.m.u >> 24) & 0xffffff00L;
+ r.l = (a.m.u >> 24) & ~0xffL;
r.u = r.l;
}
return r;
@@ -239,7 +241,7 @@ Fix48 operator >> (const Fix48& a, int b)
// error handling
-void Fix24::overflow(long& i) const
+void Fix24::overflow(_G_int32_t& i) const
{
(*Fix24_overflow_handler)(i);
}
@@ -249,7 +251,7 @@ void Fix48::overflow(twolongs& i) const
(*Fix48_overflow_handler)(i);
}
-void Fix24::range_error(long& i) const
+void Fix24::range_error(_G_int32_t& i) const
{
(*Fix24_range_error_handler)(i);
}
@@ -303,15 +305,15 @@ void set_range_error_handler(Fix24_peh handler24, Fix48_peh handler48) {
set_Fix48_range_error_handler(handler48);
}
-void Fix24_overflow_saturate(long& i)
+void Fix24_overflow_saturate(_G_int32_t& i)
{ i = (i > 0 ? Fix24_m_min : Fix24_m_max); }
-void Fix24_ignore(long&) {}
-void Fix24_warning(long&)
+void Fix24_ignore(_G_int32_t&) {}
+void Fix24_warning(_G_int32_t&)
{ cerr << "warning: Fix24 result out of range\n"; }
-void Fix24_overflow_warning_saturate(long& i)
+void Fix24_overflow_warning_saturate(_G_int32_t& i)
{ cerr << "warning: Fix24 result out of range\n";
Fix24_overflow_saturate(i); }
-void Fix24_abort(long&)
+void Fix24_abort(_G_int32_t&)
{ cerr << "error: Fix24 result out of range\n"; abort(); }
void Fix48_ignore(twolongs&) {}
diff --git a/gnu/lib/libg++/libg++/MLCG.cc b/gnu/lib/libg++/libg++/MLCG.cc
index cdc116565918..053325eb5df0 100644
--- a/gnu/lib/libg++/libg++/MLCG.cc
+++ b/gnu/lib/libg++/libg++/MLCG.cc
@@ -79,7 +79,7 @@ MLCG::reset()
seedTwo = (seedTwo % 2147483397) + 1;
}
-unsigned long MLCG::asLong()
+_G_uint32_t MLCG::asLong()
{
_G_int32_t k = seedOne % 53668;
diff --git a/gnu/lib/libg++/libg++/Regex.cc b/gnu/lib/libg++/libg++/Regex.cc
index 990f7b8b6d25..37e564b8c1c5 100644
--- a/gnu/lib/libg++/libg++/Regex.cc
+++ b/gnu/lib/libg++/libg++/Regex.cc
@@ -28,7 +28,11 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#include <builtin.h>
extern "C" {
-#include <regex.h>
+#if 1
+#include <rx.h>
+#else
+#include <gnuregex.h>
+#endif
}
#include <Regex.h>
@@ -46,17 +50,18 @@ Regex::Regex(const char* t, int fast, int bufsize,
{
int tlen = (t == 0)? 0 : strlen(t);
buf = new re_pattern_buffer;
+ memset (buf, 0, sizeof(re_pattern_buffer));
reg = new re_registers;
if (fast)
buf->fastmap = (char*)malloc(256);
else
buf->fastmap = 0;
- buf->translate = (char*)transtable;
+ buf->translate = (unsigned char*)transtable;
if (tlen > bufsize)
bufsize = tlen;
buf->allocated = bufsize;
buf->buffer = (char *)malloc(buf->allocated);
- char* msg = re_compile_pattern((const char*)t, tlen, buf);
+ const char* msg = re_compile_pattern((const char*)t, tlen, buf);
if (msg != 0)
(*lib_error_handler)("Regex", msg);
else if (fast)
diff --git a/gnu/lib/libg++/libg++/SLList.cc b/gnu/lib/libg++/libg++/SLList.cc
index 6efd99766a50..7c19b3c74933 100644
--- a/gnu/lib/libg++/libg++/SLList.cc
+++ b/gnu/lib/libg++/libg++/SLList.cc
@@ -25,7 +25,7 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#include <builtin.h>
#include "SLList.h"
-void BaseSLList::error(const char* msg)
+void BaseSLList::error(const char* msg) const
{
(*lib_error_handler)("SLList", msg);
}
@@ -184,7 +184,7 @@ void BaseSLList::del_after(Pix p)
delete_node(t);
}
-int BaseSLList::owns(Pix p)
+int BaseSLList::owns(Pix p) const
{
BaseSLNode* t = last;
if (t != 0 && p != 0)
@@ -227,7 +227,7 @@ void BaseSLList::del_front()
delete_node(t);
}
-int BaseSLList::OK()
+int BaseSLList::OK() const
{
int v = 1;
if (last != 0)
diff --git a/gnu/lib/libg++/libg++/String.cc b/gnu/lib/libg++/libg++/String.cc
index ad86079a6a17..cb2c52477731 100644
--- a/gnu/lib/libg++/libg++/String.cc
+++ b/gnu/lib/libg++/libg++/String.cc
@@ -29,10 +29,6 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#include <new.h>
#include <builtin.h>
-// extern "C" {
-#include <regex.h>
-// }
-
void String::error(const char* msg) const
{
(*lib_error_handler)("String", msg);
@@ -171,7 +167,8 @@ StrRep* Salloc(StrRep* old, const char* src, int srclen, int newlen)
// generally be faster in the long run to get new space & copy
// than to call realloc
-StrRep* Sresize(StrRep* old, int newlen)
+static StrRep*
+Sresize(StrRep* old, int newlen)
{
if (old == &_nilStrRep) old = 0;
StrRep* rep;
@@ -191,6 +188,14 @@ StrRep* Sresize(StrRep* old, int newlen)
return rep;
}
+void
+String::alloc (int newsize)
+{
+ unsigned short old_len = rep->len;
+ rep = Sresize(rep, newsize);
+ rep->len = old_len;
+}
+
// like allocate, but we know that src is a StrRep
StrRep* Scopy(StrRep* old, const StrRep* s)
@@ -960,41 +965,25 @@ int split(const String& src, String results[], int n, const Regex& r)
#if defined(__GNUG__) && !defined(_G_NO_NRV)
+#define RETURN(r) return
+#define RETURNS(r) return r;
+#define RETURN_OBJECT(TYPE, NAME) /* nothing */
+#else /* _G_NO_NRV */
+#define RETURN(r) return r
+#define RETURNS(r) /* nothing */
+#define RETURN_OBJECT(TYPE, NAME) TYPE NAME;
+#endif
-String join(String src[], int n, const String& separator) return x;
-{
- String sep = separator;
- int xlen = 0;
- for (int i = 0; i < n; ++i)
- xlen += src[i].length();
- xlen += (n - 1) * sep.length();
-
- x.alloc(xlen);
-
- int j = 0;
-
- for (i = 0; i < n - 1; ++i)
- {
- ncopy(src[i].chars(), &(x.rep->s[j]), src[i].length());
- j += src[i].length();
- ncopy(sep.chars(), &(x.rep->s[j]), sep.length());
- j += sep.length();
- }
- ncopy0(src[i].chars(), &(x.rep->s[j]), src[i].length());
-}
-
-#else
-
-String join(String src[], int n, const String& separator)
+String join(String src[], int n, const String& separator) RETURNS(x)
{
- String x;
+ RETURN_OBJECT(String,x)
String sep = separator;
int xlen = 0;
for (int i = 0; i < n; ++i)
xlen += src[i].length();
xlen += (n - 1) * sep.length();
- x.alloc(xlen);
+ x.rep = Sresize (x.rep, xlen);
int j = 0;
@@ -1006,10 +995,8 @@ String join(String src[], int n, const String& separator)
j += sep.length();
}
ncopy0(src[i].chars(), &(x.rep->s[j]), src[i].length());
- return x;
+ RETURN(x);
}
-
-#endif
/*
misc
diff --git a/gnu/lib/libg++/libg++/error.cc b/gnu/lib/libg++/libg++/error.cc
index 852b3df97502..9283d14fdde9 100644
--- a/gnu/lib/libg++/libg++/error.cc
+++ b/gnu/lib/libg++/libg++/error.cc
@@ -26,7 +26,7 @@ typedef _VOLATILE_VOID (*NoReturnFunc)(void);
This is to avoid a warning from g++ that a `volatile' function does return. */
#define ABORT() ((NoReturnFunc)abort)()
#else
-#define ABORT abort()
+#define ABORT() abort()
#endif
_VOLATILE_VOID default_one_arg_error_handler(const char* msg)
diff --git a/gnu/lib/libg++/libg++/except.c b/gnu/lib/libg++/libg++/except.c
new file mode 100644
index 000000000000..84adf22aeb41
--- /dev/null
+++ b/gnu/lib/libg++/libg++/except.c
@@ -0,0 +1,79 @@
+/* This is part of GNU C++ Library.
+Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU C++ Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* terminate(), unexpected(), set_terminate(), set_unexpected() as
+ well as the default terminate func and default unexpected func */
+
+#if 0
+extern int printf();
+#endif
+
+typedef void (*vfp)();
+
+void
+__default_terminate()
+{
+ abort();
+}
+
+void
+__default_unexpected()
+{
+ __default_terminate();
+}
+
+static vfp __terminate_func = __default_terminate;
+static vfp __unexpected_func = __default_unexpected;
+
+vfp
+set_terminate(func)
+vfp func;
+{
+ vfp old = __terminate_func;
+
+ __terminate_func = func;
+ return old;
+}
+
+vfp
+set_unexpected(func)
+vfp func;
+{
+ vfp old = __unexpected_func;
+
+ __unexpected_func = func;
+ return old;
+}
+
+void
+terminate()
+{
+ __terminate_func();
+}
+
+void
+unexpected()
+{
+ __unexpected_func();
+}
diff --git a/gnu/lib/libg++/libg++/regex.cc b/gnu/lib/libg++/libg++/regex.cc
deleted file mode 100644
index db23a51995bc..000000000000
--- a/gnu/lib/libg++/libg++/regex.cc
+++ /dev/null
@@ -1,2757 +0,0 @@
-/* Extended regular expression matching and search library.
- Copyright (C) 1985, 1989-90 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-// This is a translation into C++ of regex.c, the GNU regexp package.
-
-/* To test, compile with -Dtest. This Dtestable feature turns this into
- a self-contained program which reads a pattern, describes how it
- compiles, then reads a string and searches for it.
-
- On the other hand, if you compile with both -Dtest and -Dcanned you
- can run some tests we've already thought of. */
-
-/* AIX requires the alloca decl to be the first thing in the file. */
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else
-#ifdef sparc
-#include <alloca.h>
-extern "C" void *__builtin_alloca(...);
-#else
-#ifdef _AIX
-#pragma alloca
-#else
-char *alloca ();
-#endif
-#endif
-#endif
-
-#ifdef emacs
-
-/* The `emacs' switch turns on certain special matching commands
- that make sense only in emacs. */
-
-#include "config.h"
-#include "lisp.h"
-#include "buffer.h"
-#include "syntax.h"
-
-#else /* not emacs */
-
-#include <_G_config.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* Define the syntax stuff, so we can do the \<, \>, etc. */
-
-/* This must be nonzero for the wordchar and notwordchar pattern
- commands in re_match_2. */
-#ifndef Sword
-#define Sword 1
-#endif
-
-#define SYNTAX(c) re_syntax_table[c]
-
-
-#ifdef SYNTAX_TABLE
-
-char *re_syntax_table;
-
-#else /* not SYNTAX_TABLE */
-
-static char re_syntax_table[256];
-
-
-static void
-init_syntax_once ()
-{
- register int c;
- static int done = 0;
-
- if (done)
- return;
-
- memset (re_syntax_table, 0, sizeof re_syntax_table);
-
- for (c = 'a'; c <= 'z'; c++)
- re_syntax_table[c] = Sword;
-
- for (c = 'A'; c <= 'Z'; c++)
- re_syntax_table[c] = Sword;
-
- for (c = '0'; c <= '9'; c++)
- re_syntax_table[c] = Sword;
-
- done = 1;
-}
-
-#endif /* SYNTAX_TABLE */
-#endif /* emacs */
-
-/* We write fatal error messages on standard error. */
-#include <stdio.h>
-
-/* isalpha(3) etc. are used for the character classes. */
-#include <ctype.h>
-/* Sequents are missing isgraph. */
-#ifndef isgraph
-#define isgraph(c) (isprint((c)) && !isspace((c)))
-#endif
-
-/* Get the interface, including the syntax bits. */
-#include "regex.h"
-
-
-/* These are the command codes that appear in compiled regular
- expressions, one per byte. Some command codes are followed by
- argument bytes. A command code can specify any interpretation
- whatsoever for its arguments. Zero-bytes may appear in the compiled
- regular expression.
-
- The value of `exactn' is needed in search.c (search_buffer) in emacs.
- So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of
- `exactn' we use here must also be 1. */
-
-enum regexpcode
- {
- unused=0,
- exactn=1, /* Followed by one byte giving n, then by n literal bytes. */
- begline, /* Fail unless at beginning of line. */
- endline, /* Fail unless at end of line. */
- jump, /* Followed by two bytes giving relative address to jump to. */
- on_failure_jump, /* Followed by two bytes giving relative address of
- place to resume at in case of failure. */
- finalize_jump, /* Throw away latest failure point and then jump to
- address. */
- maybe_finalize_jump, /* Like jump but finalize if safe to do so.
- This is used to jump back to the beginning
- of a repeat. If the command that follows
- this jump is clearly incompatible with the
- one at the beginning of the repeat, such that
- we can be sure that there is no use backtracking
- out of repetitions already completed,
- then we finalize. */
- dummy_failure_jump, /* Jump, and push a dummy failure point. This
- failure point will be thrown away if an attempt
- is made to use it for a failure. A + construct
- makes this before the first repeat. Also
- use it as an intermediary kind of jump when
- compiling an or construct. */
- succeed_n, /* Used like on_failure_jump except has to succeed n times;
- then gets turned into an on_failure_jump. The relative
- address following it is useless until then. The
- address is followed by two bytes containing n. */
- jump_n, /* Similar to jump, but jump n times only; also the relative
- address following is in turn followed by yet two more bytes
- containing n. */
- set_number_at, /* Set the following relative location to the
- subsequent number. */
- anychar, /* Matches any (more or less) one character. */
- charset, /* Matches any one char belonging to specified set.
- First following byte is number of bitmap bytes.
- Then come bytes for a bitmap saying which chars are in.
- Bits in each byte are ordered low-bit-first.
- A character is in the set if its bit is 1.
- A character too large to have a bit in the map
- is automatically not in the set. */
- charset_not, /* Same parameters as charset, but match any character
- that is not one of those specified. */
- start_memory, /* Start remembering the text that is matched, for
- storing in a memory register. Followed by one
- byte containing the register number. Register numbers
- must be in the range 0 through RE_NREGS. */
- stop_memory, /* Stop remembering the text that is matched
- and store it in a memory register. Followed by
- one byte containing the register number. Register
- numbers must be in the range 0 through RE_NREGS. */
- duplicate, /* Match a duplicate of something remembered.
- Followed by one byte containing the index of the memory
- register. */
-#ifdef emacs
- before_dot, /* Succeeds if before point. */
- at_dot, /* Succeeds if at point. */
- after_dot, /* Succeeds if after point. */
-#endif
- begbuf, /* Succeeds if at beginning of buffer. */
- endbuf, /* Succeeds if at end of buffer. */
- wordchar, /* Matches any word-constituent character. */
- notwordchar, /* Matches any char that is not a word-constituent. */
- wordbeg, /* Succeeds if at word beginning. */
- wordend, /* Succeeds if at word end. */
- wordbound, /* Succeeds if at a word boundary. */
- notwordbound /* Succeeds if not at a word boundary. */
-#ifdef emacs
- ,syntaxspec, /* Matches any character whose syntax is specified.
- followed by a byte which contains a syntax code,
- e.g., Sword. */
- notsyntaxspec /* Matches any character whose syntax differs from
- that specified. */
-#endif
- };
-
-
-/* Number of failure points to allocate space for initially,
- when matching. If this number is exceeded, more space is allocated,
- so it is not a hard limit. */
-
-#ifndef NFAILURES
-#define NFAILURES 80
-#endif
-
-
-#ifndef SIGN_EXTEND_CHAR
-#ifdef __STDC__
-#define SIGN_EXTEND_CHAR(c) ((signed char)(c))
-#else
-#define SIGN_EXTEND_CHAR(c) (((c)^128) - 128) /* As in Harbison and Steele. */
-#endif
-#endif /* not SIGN_EXTEND_CHAR */
-
-/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
-#define STORE_NUMBER(destination, number) \
- { (destination)[0] = (char)((number) & 0377); \
- (destination)[1] = (number) >> 8; }
-
-/* Same as STORE_NUMBER, except increment the destination pointer to
- the byte after where the number is stored. Watch out that values for
- DESTINATION such as p + 1 won't work, whereas p will. */
-#define STORE_NUMBER_AND_INCR(destination, number) \
- { STORE_NUMBER(destination, number); \
- (destination) += 2; }
-
-
-/* Put into DESTINATION a number stored in two contingous bytes starting
- at SOURCE. */
-#define EXTRACT_NUMBER(destination, source) \
- { (destination) = *(source) & 0377; \
- (destination) += SIGN_EXTEND_CHAR (*(char *)((source) + 1)) << 8; }
-
-/* Same as EXTRACT_NUMBER, except increment the pointer for source to
- point to second byte of SOURCE. Note that SOURCE has to be a value
- such as p, not, e.g., p + 1. */
-#define EXTRACT_NUMBER_AND_INCR(destination, source) \
- { EXTRACT_NUMBER (destination, source); \
- (source) += 2; }
-
-
-/* Specify the precise syntax of regexps for compilation. This provides
- for compatibility for various utilities which historically have
- different, incompatible syntaxes.
-
- The argument SYNTAX is a bit-mask comprised of the various bits
- defined in regex.h. */
-
-int
-re_set_syntax (int syntax)
-{
- int ret;
-
- ret = obscure_syntax;
- obscure_syntax = syntax;
- return ret;
-}
-
-/* Set by re_set_syntax to the current regexp syntax to recognize. */
-int obscure_syntax = 0;
-
-
-
-/* Macros for re_compile_pattern, which is found below these definitions. */
-
-#define CHAR_CLASS_MAX_LENGTH 6
-
-/* Fetch the next character in the uncompiled pattern, translating it if
- necessary. */
-#define PATFETCH(c) \
- {if (p == pend) goto end_of_pattern; \
- c = * (const unsigned char *) p++; \
- if (translate) c = translate[c]; }
-
-/* Fetch the next character in the uncompiled pattern, with no
- translation. */
-#define PATFETCH_RAW(c) \
- {if (p == pend) goto end_of_pattern; \
- c = * (const unsigned char *) p++; }
-
-#define PATUNFETCH p--
-
-
-/* If the buffer isn't allocated when it comes in, use this. */
-#define INIT_BUF_SIZE 28
-
-/* Make sure we have at least N more bytes of space in buffer. */
-#define GET_BUFFER_SPACE(n) \
- { \
- while (b - bufp->buffer + (n) >= bufp->allocated) \
- EXTEND_BUFFER; \
- }
-
-/* Make sure we have one more byte of buffer space and then add CH to it. */
-#define BUFPUSH(ch) \
- { \
- GET_BUFFER_SPACE (1); \
- *b++ = (char) (ch); \
- }
-
-/* Extend the buffer by twice its current size via reallociation and
- reset the pointers that pointed into the old allocation to point to
- the correct places in the new allocation. If extending the buffer
- results in it being larger than 1 << 16, then flag memory exhausted. */
-#define EXTEND_BUFFER \
- { char *old_buffer = bufp->buffer; \
- if (bufp->allocated == (1L<<16)) goto too_big; \
- bufp->allocated *= 2; \
- if (bufp->allocated > (1L<<16)) bufp->allocated = (1L<<16); \
- bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated); \
- if (bufp->buffer == 0) \
- goto memory_exhausted; \
- b = (b - old_buffer) + bufp->buffer; \
- if (fixup_jump) \
- fixup_jump = (fixup_jump - old_buffer) + bufp->buffer; \
- if (laststart) \
- laststart = (laststart - old_buffer) + bufp->buffer; \
- begalt = (begalt - old_buffer) + bufp->buffer; \
- if (pending_exact) \
- pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
- }
-
-/* Set the bit for character C in a character set list. */
-#define SET_LIST_BIT(c) (b[(c) / BYTEWIDTH] |= 1 << ((c) % BYTEWIDTH))
-
-/* Get the next unsigned number in the uncompiled pattern. */
-#define GET_UNSIGNED_NUMBER(num) \
- { if (p != pend) \
- { \
- PATFETCH (c); \
- while (isdigit (c)) \
- { \
- if (num < 0) \
- num = 0; \
- num = num * 10 + c - '0'; \
- if (p == pend) \
- break; \
- PATFETCH (c); \
- } \
- } \
- }
-
-/* Subroutines for re_compile_pattern. */
-static void store_jump (char *from, char opcode, char *to);
-static void insert_jump (char op, char *from, char *to, char *current_end);
-static void store_jump_n (char *from, char opcode, char *to, unsigned n);
-static void insert_jump_n (char, char *, char *, char *, unsigned);
-static void insert_op_2 (char, char *, char *_end, int, int);
-
-
-/* re_compile_pattern takes a regular-expression string
- and converts it into a buffer full of byte commands for matching.
-
- PATTERN is the address of the pattern string
- SIZE is the length of it.
- BUFP is a struct re_pattern_buffer * which points to the info
- on where to store the byte commands.
- This structure contains a char * which points to the
- actual space, which should have been obtained with malloc.
- re_compile_pattern may use realloc to grow the buffer space.
-
- The number of bytes of commands can be found out by looking in
- the `struct re_pattern_buffer' that bufp pointed to, after
- re_compile_pattern returns. */
-
-char *
-re_compile_pattern (const char *pattern, int size, struct re_pattern_buffer *bufp)
-{
- register char *b = bufp->buffer;
- register const char *p = pattern;
- const char *pend = pattern + size;
- register unsigned c, c1;
- const char *p1;
- unsigned char *translate = (unsigned char *) bufp->translate;
-
- /* Address of the count-byte of the most recently inserted `exactn'
- command. This makes it possible to tell whether a new exact-match
- character can be added to that command or requires a new `exactn'
- command. */
-
- char *pending_exact = 0;
-
- /* Address of the place where a forward-jump should go to the end of
- the containing expression. Each alternative of an `or', except the
- last, ends with a forward-jump of this sort. */
-
- char *fixup_jump = 0;
-
- /* Address of start of the most recently finished expression.
- This tells postfix * where to find the start of its operand. */
-
- char *laststart = 0;
-
- /* In processing a repeat, 1 means zero matches is allowed. */
-
- char zero_times_ok;
-
- /* In processing a repeat, 1 means many matches is allowed. */
-
- char many_times_ok;
-
- /* Address of beginning of regexp, or inside of last \(. */
-
- char *begalt = b;
-
- /* In processing an interval, at least this many matches must be made. */
- int lower_bound;
-
- /* In processing an interval, at most this many matches can be made. */
- int upper_bound;
-
- /* Place in pattern (i.e., the {) to which to go back if the interval
- is invalid. */
- const char *beg_interval = 0;
-
- /* Stack of information saved by \( and restored by \).
- Four stack elements are pushed by each \(:
- First, the value of b.
- Second, the value of fixup_jump.
- Third, the value of regnum.
- Fourth, the value of begalt. */
-
- int stackb[40];
- int *stackp = stackb;
- int *stacke = stackb + 40;
- int *stackt;
-
- /* Counts \('s as they are encountered. Remembered for the matching \),
- where it becomes the register number to put in the stop_memory
- command. */
-
- unsigned regnum = 1;
-
- bufp->fastmap_accurate = 0;
-
-#ifndef emacs
-#ifndef SYNTAX_TABLE
- /* Initialize the syntax table. */
- init_syntax_once();
-#endif
-#endif
-
- if (bufp->allocated == 0)
- {
- bufp->allocated = INIT_BUF_SIZE;
- if (bufp->buffer)
- /* EXTEND_BUFFER loses when bufp->allocated is 0. */
- bufp->buffer = (char *) realloc (bufp->buffer, INIT_BUF_SIZE);
- else
- /* Caller did not allocate a buffer. Do it for them. */
- bufp->buffer = (char *) malloc (INIT_BUF_SIZE);
- if (!bufp->buffer) goto memory_exhausted;
- begalt = b = bufp->buffer;
- }
-
- while (p != pend)
- {
- PATFETCH (c);
-
- switch (c)
- {
- case '$':
- {
- const char *p1 = p;
- /* When testing what follows the $,
- look past the \-constructs that don't consume anything. */
- if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
- while (p1 != pend)
- {
- if (*p1 == '\\' && p1 + 1 != pend
- && (p1[1] == '<' || p1[1] == '>'
- || p1[1] == '`' || p1[1] == '\''
-#ifdef emacs
- || p1[1] == '='
-#endif
- || p1[1] == 'b' || p1[1] == 'B'))
- p1 += 2;
- else
- break;
- }
- if (obscure_syntax & RE_TIGHT_VBAR)
- {
- if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p1 != pend)
- goto normal_char;
- /* Make operand of last vbar end before this `$'. */
- if (fixup_jump)
- store_jump (fixup_jump, jump, b);
- fixup_jump = 0;
- BUFPUSH (endline);
- break;
- }
- /* $ means succeed if at end of line, but only in special contexts.
- If validly in the middle of a pattern, it is a normal character. */
-
- if ((obscure_syntax & RE_CONTEXTUAL_INVALID_OPS) && p1 != pend)
- goto invalid_pattern;
- if (p1 == pend || *p1 == '\n'
- || (obscure_syntax & RE_CONTEXT_INDEP_OPS)
- || (obscure_syntax & RE_NO_BK_PARENS
- ? *p1 == ')'
- : *p1 == '\\' && p1[1] == ')')
- || (obscure_syntax & RE_NO_BK_VBAR
- ? *p1 == '|'
- : *p1 == '\\' && p1[1] == '|'))
- {
- BUFPUSH (endline);
- break;
- }
- goto normal_char;
- }
- case '^':
- /* ^ means succeed if at beg of line, but only if no preceding
- pattern. */
-
- if ((obscure_syntax & RE_CONTEXTUAL_INVALID_OPS) && laststart)
- goto invalid_pattern;
- if (laststart && p - 2 >= pattern && p[-2] != '\n'
- && !(obscure_syntax & RE_CONTEXT_INDEP_OPS))
- goto normal_char;
- if (obscure_syntax & RE_TIGHT_VBAR)
- {
- if (p != pattern + 1
- && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
- goto normal_char;
- BUFPUSH (begline);
- begalt = b;
- }
- else
- BUFPUSH (begline);
- break;
-
- case '+':
- case '?':
- if ((obscure_syntax & RE_BK_PLUS_QM)
- || (obscure_syntax & RE_LIMITED_OPS))
- goto normal_char;
- handle_plus:
- case '*':
- /* If there is no previous pattern, char not special. */
- if (!laststart)
- {
- if (obscure_syntax & RE_CONTEXTUAL_INVALID_OPS)
- goto invalid_pattern;
- else if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
- goto normal_char;
- }
- /* If there is a sequence of repetition chars,
- collapse it down to just one. */
- zero_times_ok = 0;
- many_times_ok = 0;
- while (1)
- {
- zero_times_ok |= c != '+';
- many_times_ok |= c != '?';
- if (p == pend)
- break;
- PATFETCH (c);
- if (c == '*')
- ;
- else if (!(obscure_syntax & RE_BK_PLUS_QM)
- && (c == '+' || c == '?'))
- ;
- else if ((obscure_syntax & RE_BK_PLUS_QM)
- && c == '\\')
- {
- int c1;
- PATFETCH (c1);
- if (!(c1 == '+' || c1 == '?'))
- {
- PATUNFETCH;
- PATUNFETCH;
- break;
- }
- c = c1;
- }
- else
- {
- PATUNFETCH;
- break;
- }
- }
-
- /* Star, etc. applied to an empty pattern is equivalent
- to an empty pattern. */
- if (!laststart)
- break;
-
- /* Now we know whether or not zero matches is allowed
- and also whether or not two or more matches is allowed. */
- if (many_times_ok)
- {
- /* If more than one repetition is allowed, put in at the
- end a backward relative jump from b to before the next
- jump we're going to put in below (which jumps from
- laststart to after this jump). */
- GET_BUFFER_SPACE (3);
- store_jump (b, maybe_finalize_jump, laststart - 3);
- b += 3; /* Because store_jump put stuff here. */
- }
- /* On failure, jump from laststart to b + 3, which will be the
- end of the buffer after this jump is inserted. */
- GET_BUFFER_SPACE (3);
- insert_jump (on_failure_jump, laststart, b + 3, b);
- pending_exact = 0;
- b += 3;
- if (!zero_times_ok)
- {
- /* At least one repetition is required, so insert a
- dummy-failure before the initial on-failure-jump
- instruction of the loop. This effects a skip over that
- instruction the first time we hit that loop. */
- GET_BUFFER_SPACE (6);
- insert_jump (dummy_failure_jump, laststart, laststart + 6, b);
- b += 3;
- }
- break;
-
- case '.':
- laststart = b;
- BUFPUSH (anychar);
- break;
-
- case '[':
- if (p == pend)
- goto invalid_pattern;
- while (b - bufp->buffer
- > bufp->allocated - 3 - (1 << BYTEWIDTH) / BYTEWIDTH)
- EXTEND_BUFFER;
-
- laststart = b;
- if (*p == '^')
- {
- BUFPUSH (charset_not);
- p++;
- }
- else
- BUFPUSH (charset);
- p1 = p;
-
- BUFPUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
- /* Clear the whole map */
- memset (b, 0, (1 << BYTEWIDTH) / BYTEWIDTH);
-
- if ((obscure_syntax & RE_HAT_NOT_NEWLINE) && b[-2] == charset_not)
- SET_LIST_BIT ('\n');
-
-
- /* Read in characters and ranges, setting map bits. */
- while (1)
- {
- /* Don't translate while fetching, in case it's a range bound.
- When we set the bit for the character, we translate it. */
- PATFETCH_RAW (c);
-
- /* If set, \ escapes characters when inside [...]. */
- if ((obscure_syntax & RE_AWK_CLASS_HACK) && c == '\\')
- {
- PATFETCH(c1);
- SET_LIST_BIT (c1);
- continue;
- }
- if (c == ']')
- {
- if (p == p1 + 1)
- {
- /* If this is an empty bracket expression. */
- if ((obscure_syntax & RE_NO_EMPTY_BRACKETS)
- && p == pend)
- goto invalid_pattern;
- }
- else
- /* Stop if this isn't merely a ] inside a bracket
- expression, but rather the end of a bracket
- expression. */
- break;
- }
- /* Get a range. */
- if (p[0] == '-' && p[1] != ']')
- {
- PATFETCH (c1);
- /* Don't translate the range bounds while fetching them. */
- PATFETCH_RAW (c1);
-
- if ((obscure_syntax & RE_NO_EMPTY_RANGES) && c > c1)
- goto invalid_pattern;
-
- if ((obscure_syntax & RE_NO_HYPHEN_RANGE_END)
- && c1 == '-' && *p != ']')
- goto invalid_pattern;
-
- while (c <= c1)
- {
- /* Translate each char that's in the range. */
- if (translate)
- SET_LIST_BIT (translate[c]);
- else
- SET_LIST_BIT (c);
- c++;
- }
- }
- else if ((obscure_syntax & RE_CHAR_CLASSES)
- && c == '[' && p[0] == ':')
- {
- /* Longest valid character class word has six characters. */
- char str[CHAR_CLASS_MAX_LENGTH];
- PATFETCH (c);
- c1 = 0;
- /* If no ] at end. */
- if (p == pend)
- goto invalid_pattern;
- while (1)
- {
- /* Don't translate the ``character class'' characters. */
- PATFETCH_RAW (c);
- if (c == ':' || c == ']' || p == pend
- || c1 == CHAR_CLASS_MAX_LENGTH)
- break;
- str[c1++] = c;
- }
- str[c1] = '\0';
- if (p == pend
- || c == ']' /* End of the bracket expression. */
- || p[0] != ']'
- || p + 1 == pend
- || (strcmp (str, "alpha") != 0
- && strcmp (str, "upper") != 0
- && strcmp (str, "lower") != 0
- && strcmp (str, "digit") != 0
- && strcmp (str, "alnum") != 0
- && strcmp (str, "xdigit") != 0
- && strcmp (str, "space") != 0
- && strcmp (str, "print") != 0
- && strcmp (str, "punct") != 0
- && strcmp (str, "graph") != 0
- && strcmp (str, "cntrl") != 0))
- {
- /* Undo the ending character, the letters, and leave
- the leading : and [ (but set bits for them). */
- c1++;
- while (c1--)
- PATUNFETCH;
- SET_LIST_BIT ('[');
- SET_LIST_BIT (':');
- }
- else
- {
- /* The ] at the end of the character class. */
- PATFETCH (c);
- if (c != ']')
- goto invalid_pattern;
- for (c = 0; c < (1 << BYTEWIDTH); c++)
- {
- if ((strcmp (str, "alpha") == 0 && isalpha (c))
- || (strcmp (str, "upper") == 0 && isupper (c))
- || (strcmp (str, "lower") == 0 && islower (c))
- || (strcmp (str, "digit") == 0 && isdigit (c))
- || (strcmp (str, "alnum") == 0 && isalnum (c))
- || (strcmp (str, "xdigit") == 0 && isxdigit (c))
- || (strcmp (str, "space") == 0 && isspace (c))
- || (strcmp (str, "print") == 0 && isprint (c))
- || (strcmp (str, "punct") == 0 && ispunct (c))
- || (strcmp (str, "graph") == 0 && isgraph (c))
- || (strcmp (str, "cntrl") == 0 && iscntrl (c)))
- SET_LIST_BIT (c);
- }
- }
- }
- else if (translate)
- SET_LIST_BIT (translate[c]);
- else
- SET_LIST_BIT (c);
- }
-
- /* Discard any character set/class bitmap bytes that are all
- 0 at the end of the map. Decrement the map-length byte too. */
- while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
- b[-1]--;
- b += b[-1];
- break;
-
- case '(':
- if (! (obscure_syntax & RE_NO_BK_PARENS))
- goto normal_char;
- else
- goto handle_open;
-
- case ')':
- if (! (obscure_syntax & RE_NO_BK_PARENS))
- goto normal_char;
- else
- goto handle_close;
-
- case '\n':
- if (! (obscure_syntax & RE_NEWLINE_OR))
- goto normal_char;
- else
- goto handle_bar;
-
- case '|':
- if ((obscure_syntax & RE_CONTEXTUAL_INVALID_OPS)
- && (! laststart || p == pend))
- goto invalid_pattern;
- else if (! (obscure_syntax & RE_NO_BK_VBAR))
- goto normal_char;
- else
- goto handle_bar;
-
- case '{':
- if (! ((obscure_syntax & RE_NO_BK_CURLY_BRACES)
- && (obscure_syntax & RE_INTERVALS)))
- goto normal_char;
- else
- goto handle_interval;
-
- case '\\':
- if (p == pend) goto invalid_pattern;
- PATFETCH_RAW (c);
- switch (c)
- {
- case '(':
- if (obscure_syntax & RE_NO_BK_PARENS)
- goto normal_backsl;
- handle_open:
- if (stackp == stacke) goto nesting_too_deep;
-
- /* Laststart should point to the start_memory that we are about
- to push (unless the pattern has RE_NREGS or more ('s). */
- *stackp++ = b - bufp->buffer;
- if (regnum < RE_NREGS)
- {
- BUFPUSH (start_memory);
- BUFPUSH (regnum);
- }
- *stackp++ = fixup_jump ? fixup_jump - bufp->buffer + 1 : 0;
- *stackp++ = regnum++;
- *stackp++ = begalt - bufp->buffer;
- fixup_jump = 0;
- laststart = 0;
- begalt = b;
- break;
-
- case ')':
- if (obscure_syntax & RE_NO_BK_PARENS)
- goto normal_backsl;
- handle_close:
- if (stackp == stackb) goto unmatched_close;
- begalt = *--stackp + bufp->buffer;
- if (fixup_jump)
- store_jump (fixup_jump, jump, b);
- if (stackp[-1] < RE_NREGS)
- {
- BUFPUSH (stop_memory);
- BUFPUSH (stackp[-1]);
- }
- stackp -= 2;
- fixup_jump = *stackp ? *stackp + bufp->buffer - 1 : 0;
- laststart = *--stackp + bufp->buffer;
- break;
-
- case '|':
- if ((obscure_syntax & RE_LIMITED_OPS)
- || (obscure_syntax & RE_NO_BK_VBAR))
- goto normal_backsl;
- handle_bar:
- if (obscure_syntax & RE_LIMITED_OPS)
- goto normal_char;
- /* Insert before the previous alternative a jump which
- jumps to this alternative if the former fails. */
- GET_BUFFER_SPACE (6);
- insert_jump (on_failure_jump, begalt, b + 6, b);
- pending_exact = 0;
- b += 3;
- /* The alternative before the previous alternative has a
- jump after it which gets executed if it gets matched.
- Adjust that jump so it will jump to the previous
- alternative's analogous jump (put in below, which in
- turn will jump to the next (if any) alternative's such
- jump, etc.). The last such jump jumps to the correct
- final destination. */
- if (fixup_jump)
- store_jump (fixup_jump, jump, b);
-
- /* Leave space for a jump after previous alternative---to be
- filled in later. */
- fixup_jump = b;
- b += 3;
-
- laststart = 0;
- begalt = b;
- break;
-
- case '{':
- if (! (obscure_syntax & RE_INTERVALS)
- /* Let \{ be a literal. */
- || ((obscure_syntax & RE_INTERVALS)
- && (obscure_syntax & RE_NO_BK_CURLY_BRACES))
- /* If it's the string "\{". */
- || (p - 2 == pattern && p == pend))
- goto normal_backsl;
- handle_interval:
- beg_interval = p - 1; /* The {. */
- /* If there is no previous pattern, this isn't an interval. */
- if (!laststart)
- {
- if (obscure_syntax & RE_CONTEXTUAL_INVALID_OPS)
- goto invalid_pattern;
- else
- goto normal_backsl;
- }
- /* It also isn't an interval if not preceded by an re
- matching a single character or subexpression, or if
- the current type of intervals can't handle back
- references and the previous thing is a back reference. */
- if (! (*laststart == anychar
- || *laststart == charset
- || *laststart == charset_not
- || *laststart == start_memory
- || (*laststart == exactn && laststart[1] == 1)
- || (! (obscure_syntax & RE_NO_BK_REFS)
- && *laststart == duplicate)))
- {
- if (obscure_syntax & RE_NO_BK_CURLY_BRACES)
- goto normal_char;
-
- /* Posix extended syntax is handled in previous
- statement; this is for Posix basic syntax. */
- if (obscure_syntax & RE_INTERVALS)
- goto invalid_pattern;
-
- goto normal_backsl;
- }
- lower_bound = -1; /* So can see if are set. */
- upper_bound = -1;
- GET_UNSIGNED_NUMBER (lower_bound);
- if (c == ',')
- {
- GET_UNSIGNED_NUMBER (upper_bound);
- if (upper_bound < 0)
- upper_bound = RE_DUP_MAX;
- }
- if (upper_bound < 0)
- upper_bound = lower_bound;
- if (! (obscure_syntax & RE_NO_BK_CURLY_BRACES))
- {
- if (c != '\\')
- goto invalid_pattern;
- PATFETCH (c);
- }
- if (c != '}' || lower_bound < 0 || upper_bound > RE_DUP_MAX
- || lower_bound > upper_bound
- || ((obscure_syntax & RE_NO_BK_CURLY_BRACES)
- && p != pend && *p == '{'))
- {
- if (obscure_syntax & RE_NO_BK_CURLY_BRACES)
- goto unfetch_interval;
- else
- goto invalid_pattern;
- }
-
- /* If upper_bound is zero, don't want to succeed at all;
- jump from laststart to b + 3, which will be the end of
- the buffer after this jump is inserted. */
-
- if (upper_bound == 0)
- {
- GET_BUFFER_SPACE (3);
- insert_jump (jump, laststart, b + 3, b);
- b += 3;
- }
-
- /* Otherwise, after lower_bound number of succeeds, jump
- to after the jump_n which will be inserted at the end
- of the buffer, and insert that jump_n. */
- else
- { /* Set to 5 if only one repetition is allowed and
- hence no jump_n is inserted at the current end of
- the buffer; then only space for the succeed_n is
- needed. Otherwise, need space for both the
- succeed_n and the jump_n. */
-
- unsigned slots_needed = upper_bound == 1 ? 5 : 10;
-
- GET_BUFFER_SPACE ((int) slots_needed);
- /* Initialize the succeed_n to n, even though it will
- be set by its attendant set_number_at, because
- re_compile_fastmap will need to know it. Jump to
- what the end of buffer will be after inserting
- this succeed_n and possibly appending a jump_n. */
- insert_jump_n (succeed_n, laststart, b + slots_needed,
- b, lower_bound);
- b += 5; /* Just increment for the succeed_n here. */
-
- /* More than one repetition is allowed, so put in at
- the end of the buffer a backward jump from b to the
- succeed_n we put in above. By the time we've gotten
- to this jump when matching, we'll have matched once
- already, so jump back only upper_bound - 1 times. */
-
- if (upper_bound > 1)
- {
- store_jump_n (b, jump_n, laststart, upper_bound - 1);
- b += 5;
- /* When hit this when matching, reset the
- preceding jump_n's n to upper_bound - 1. */
- BUFPUSH (set_number_at);
- GET_BUFFER_SPACE (2);
- STORE_NUMBER_AND_INCR (b, -5);
- STORE_NUMBER_AND_INCR (b, upper_bound - 1);
- }
- /* When hit this when matching, set the succeed_n's n. */
- GET_BUFFER_SPACE (5);
- insert_op_2 (set_number_at, laststart, b, 5, lower_bound);
- b += 5;
- }
- pending_exact = 0;
- beg_interval = 0;
- break;
-
-
- unfetch_interval:
- /* If an invalid interval, match the characters as literals. */
- if (beg_interval)
- p = beg_interval;
- else
- {
- fprintf (stderr,
- "regex: no interval beginning to which to backtrack.\n");
- exit (1);
- }
-
- beg_interval = 0;
- PATFETCH (c); /* normal_char expects char in `c'. */
- goto normal_char;
- break;
-
-#ifdef emacs
- case '=':
- BUFPUSH (at_dot);
- break;
-
- case 's':
- laststart = b;
- BUFPUSH (syntaxspec);
- PATFETCH (c);
- BUFPUSH (syntax_spec_code[c]);
- break;
-
- case 'S':
- laststart = b;
- BUFPUSH (notsyntaxspec);
- PATFETCH (c);
- BUFPUSH (syntax_spec_code[c]);
- break;
-#endif /* emacs */
-
- case 'w':
- laststart = b;
- BUFPUSH (wordchar);
- break;
-
- case 'W':
- laststart = b;
- BUFPUSH (notwordchar);
- break;
-
- case '<':
- BUFPUSH (wordbeg);
- break;
-
- case '>':
- BUFPUSH (wordend);
- break;
-
- case 'b':
- BUFPUSH (wordbound);
- break;
-
- case 'B':
- BUFPUSH (notwordbound);
- break;
-
- case '`':
- BUFPUSH (begbuf);
- break;
-
- case '\'':
- BUFPUSH (endbuf);
- break;
-
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (obscure_syntax & RE_NO_BK_REFS)
- goto normal_char;
- c1 = c - '0';
- if (c1 >= regnum)
- {
- if (obscure_syntax & RE_NO_EMPTY_BK_REF)
- goto invalid_pattern;
- else
- goto normal_char;
- }
- /* Can't back reference to a subexpression if inside of it. */
- for (stackt = stackp - 2; stackt > stackb; stackt -= 4)
- if (*stackt == c1)
- goto normal_char;
- laststart = b;
- BUFPUSH (duplicate);
- BUFPUSH (c1);
- break;
-
- case '+':
- case '?':
- if (obscure_syntax & RE_BK_PLUS_QM)
- goto handle_plus;
- else
- goto normal_backsl;
- break;
-
- default:
- normal_backsl:
- /* You might think it would be useful for \ to mean
- not to translate; but if we don't translate it
- it will never match anything. */
- if (translate) c = translate[c];
- goto normal_char;
- }
- break;
-
- default:
- normal_char: /* Expects the character in `c'. */
- if (!pending_exact || pending_exact + *pending_exact + 1 != b
- || *pending_exact == 0177 || *p == '*' || *p == '^'
- || ((obscure_syntax & RE_BK_PLUS_QM)
- ? *p == '\\' && (p[1] == '+' || p[1] == '?')
- : (*p == '+' || *p == '?'))
- || ((obscure_syntax & RE_INTERVALS)
- && ((obscure_syntax & RE_NO_BK_CURLY_BRACES)
- ? *p == '{'
- : (p[0] == '\\' && p[1] == '{'))))
- {
- laststart = b;
- BUFPUSH (exactn);
- pending_exact = b;
- BUFPUSH (0);
- }
- BUFPUSH (c);
- (*pending_exact)++;
- }
- }
-
- if (fixup_jump)
- store_jump (fixup_jump, jump, b);
-
- if (stackp != stackb) goto unmatched_open;
-
- bufp->used = b - bufp->buffer;
- return 0;
-
- invalid_pattern:
- return "Invalid regular expression";
-
- unmatched_open:
- return "Unmatched \\(";
-
- unmatched_close:
- return "Unmatched \\)";
-
- end_of_pattern:
- return "Premature end of regular expression";
-
- nesting_too_deep:
- return "Nesting too deep";
-
- too_big:
- return "Regular expression too big";
-
- memory_exhausted:
- return "Memory exhausted";
-}
-
-
-/* Store a jump of the form <OPCODE> <relative address>.
- Store in the location FROM a jump operation to jump to relative
- address FROM - TO. OPCODE is the opcode to store. */
-
-static void
-store_jump (char *from, char opcode, char *to)
-{
- from[0] = opcode;
- STORE_NUMBER(from + 1, to - (from + 3));
-}
-
-
-/* Open up space before char FROM, and insert there a jump to TO.
- CURRENT_END gives the end of the storage not in use, so we know
- how much data to copy up. OP is the opcode of the jump to insert.
-
- If you call this function, you must zero out pending_exact. */
-
-static void
-insert_jump (char op, char *from, char *to, char *current_end)
-{
- register char *pfrom = current_end; /* Copy from here... */
- register char *pto = current_end + 3; /* ...to here. */
-
- while (pfrom != from)
- *--pto = *--pfrom;
- store_jump (from, op, to);
-}
-
-
-/* Store a jump of the form <opcode> <relative address> <n> .
-
- Store in the location FROM a jump operation to jump to relative
- address FROM - TO. OPCODE is the opcode to store, N is a number the
- jump uses, say, to decide how many times to jump.
-
- If you call this function, you must zero out pending_exact. */
-
-static void
-store_jump_n (char *from, char opcode, char *to, unsigned n)
-{
- from[0] = opcode;
- STORE_NUMBER (from + 1, to - (from + 3));
- STORE_NUMBER (from + 3, n);
-}
-
-
-/* Similar to insert_jump, but handles a jump which needs an extra
- number to handle minimum and maximum cases. Open up space at
- location FROM, and insert there a jump to TO. CURRENT_END gives the
- end of the storage in use, so we know how much data to copy up. OP is
- the opcode of the jump to insert.
-
- If you call this function, you must zero out pending_exact. */
-
-static void
-insert_jump_n (char op, char *from, char *to, char *current_end, unsigned n)
-{
- register char *pfrom = current_end; /* Copy from here... */
- register char *pto = current_end + 5; /* ...to here. */
-
- while (pfrom != from)
- *--pto = *--pfrom;
- store_jump_n (from, op, to, n);
-}
-
-
-/* Open up space at location THERE, and insert operation OP followed by
- NUM_1 and NUM_2. CURRENT_END gives the end of the storage in use, so
- we know how much data to copy up.
-
- If you call this function, you must zero out pending_exact. */
-
-static void
-insert_op_2 (char op, char *there, char *current_end, int num_1, int num_2)
-{
- register char *pfrom = current_end; /* Copy from here... */
- register char *pto = current_end + 5; /* ...to here. */
-
- while (pfrom != there)
- *--pto = *--pfrom;
-
- there[0] = op;
- STORE_NUMBER (there + 1, num_1);
- STORE_NUMBER (there + 3, num_2);
-}
-
-
-
-/* Given a pattern, compute a fastmap from it. The fastmap records
- which of the (1 << BYTEWIDTH) possible characters can start a string
- that matches the pattern. This fastmap is used by re_search to skip
- quickly over totally implausible text.
-
- The caller must supply the address of a (1 << BYTEWIDTH)-byte data
- area as bufp->fastmap.
- The other components of bufp describe the pattern to be used. */
-
-void
-re_compile_fastmap (struct re_pattern_buffer *bufp)
-{
- unsigned char *pattern = (unsigned char *) bufp->buffer;
- int size = bufp->used;
- register char *fastmap = bufp->fastmap;
- register unsigned char *p = pattern;
- register unsigned char *pend = pattern + size;
- register int j, k;
- unsigned char *translate = (unsigned char *) bufp->translate;
-
- unsigned char *stackb[NFAILURES];
- unsigned char **stackp = stackb;
-
- unsigned is_a_succeed_n;
-
- memset (fastmap, 0, (1 << BYTEWIDTH));
- bufp->fastmap_accurate = 1;
- bufp->can_be_null = 0;
-
- while (p)
- {
- is_a_succeed_n = 0;
- if (p == pend)
- {
- bufp->can_be_null = 1;
- break;
- }
-#ifdef SWITCH_ENUM_BUG
- switch ((int) ((enum regexpcode) *p++))
-#else
- switch ((enum regexpcode) *p++)
-#endif
- {
- case exactn:
- if (translate)
- fastmap[translate[p[1]]] = 1;
- else
- fastmap[p[1]] = 1;
- break;
-
- case unused:
- case begline:
-#ifdef emacs
- case before_dot:
- case at_dot:
- case after_dot:
-#endif
- case begbuf:
- case endbuf:
- case wordbound:
- case notwordbound:
- case wordbeg:
- case wordend:
- continue;
-
- case endline:
- if (translate)
- fastmap[translate['\n']] = 1;
- else
- fastmap['\n'] = 1;
-
- if (bufp->can_be_null != 1)
- bufp->can_be_null = 2;
- break;
-
- case jump_n:
- case finalize_jump:
- case maybe_finalize_jump:
- case jump:
- case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR (j, p);
- p += j;
- if (j > 0)
- continue;
- /* Jump backward reached implies we just went through
- the body of a loop and matched nothing.
- Opcode jumped to should be an on_failure_jump.
- Just treat it like an ordinary jump.
- For a * loop, it has pushed its failure point already;
- If so, discard that as redundant. */
-
- if ((enum regexpcode) *p != on_failure_jump
- && (enum regexpcode) *p != succeed_n)
- continue;
- p++;
- EXTRACT_NUMBER_AND_INCR (j, p);
- p += j;
- if (stackp != stackb && *stackp == p)
- stackp--;
- continue;
-
- case on_failure_jump:
- handle_on_failure_jump:
- EXTRACT_NUMBER_AND_INCR (j, p);
- *++stackp = p + j;
- if (is_a_succeed_n)
- EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
- continue;
-
- case succeed_n:
- is_a_succeed_n = 1;
- /* Get to the number of times to succeed. */
- p += 2;
- /* Increment p past the n for when k != 0. */
- EXTRACT_NUMBER_AND_INCR (k, p);
- if (k == 0)
- {
- p -= 4;
- goto handle_on_failure_jump;
- }
- continue;
-
- case set_number_at:
- p += 4;
- continue;
-
- case start_memory:
- case stop_memory:
- p++;
- continue;
-
- case duplicate:
- bufp->can_be_null = 1;
- fastmap['\n'] = 1;
- case anychar:
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (j != '\n')
- fastmap[j] = 1;
- if (bufp->can_be_null)
- return;
- /* Don't return; check the alternative paths
- so we can set can_be_null if appropriate. */
- break;
-
- case wordchar:
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) == Sword)
- fastmap[j] = 1;
- break;
-
- case notwordchar:
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) != Sword)
- fastmap[j] = 1;
- break;
-
-#ifdef emacs
- case syntaxspec:
- k = *p++;
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) == (enum syntaxcode) k)
- fastmap[j] = 1;
- break;
-
- case notsyntaxspec:
- k = *p++;
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) != (enum syntaxcode) k)
- fastmap[j] = 1;
- break;
-#endif /* not emacs */
-
- case charset:
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
- if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
- {
- if (translate)
- fastmap[translate[j]] = 1;
- else
- fastmap[j] = 1;
- }
- break;
-
- case charset_not:
- /* Chars beyond end of map must be allowed */
- for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
- if (translate)
- fastmap[translate[j]] = 1;
- else
- fastmap[j] = 1;
-
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
- if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
- {
- if (translate)
- fastmap[translate[j]] = 1;
- else
- fastmap[j] = 1;
- }
- break;
- }
-
- /* Get here means we have successfully found the possible starting
- characters of one path of the pattern. We need not follow this
- path any farther. Instead, look at the next alternative
- remembered in the stack. */
- if (stackp != stackb)
- p = *stackp--;
- else
- break;
- }
-}
-
-
-
-/* Like re_search_2, below, but only one string is specified, and
- doesn't let you say where to stop matching. */
-
-int
-re_search (struct re_pattern_buffer *pbufp,
- char *string,
- int size,
- int startpos,
- int range,
- struct re_registers *regs)
-{
- return re_search_2 (pbufp, (char *) 0, 0, string, size, startpos, range,
- regs, size);
-}
-
-
-/* Using the compiled pattern in PBUFP->buffer, first tries to match the
- virtual concatenation of STRING1 and STRING2, starting first at index
- STARTPOS, then at STARTPOS + 1, and so on. RANGE is the number of
- places to try before giving up. If RANGE is negative, it searches
- backwards, i.e., the starting positions tried are STARTPOS, STARTPOS
- - 1, etc. STRING1 and STRING2 are of SIZE1 and SIZE2, respectively.
- In REGS, return the indices of the virtual concatenation of STRING1
- and STRING2 that matched the entire PBUFP->buffer and its contained
- subexpressions. Do not consider matching one past the index MSTOP in
- the virtual concatenation of STRING1 and STRING2.
-
- The value returned is the position in the strings at which the match
- was found, or -1 if no match was found, or -2 if error (such as
- failure stack overflow). */
-
-int
-re_search_2 (struct re_pattern_buffer *pbufp,
- char *string1, int size1,
- char *string2, int size2,
- int startpos,
- register int range,
- struct re_registers *regs,
- int mstop)
-{
- register char *fastmap = pbufp->fastmap;
- register unsigned char *translate = (unsigned char *) pbufp->translate;
- int total_size = size1 + size2;
- int endpos = startpos + range;
- int val;
-
- /* Check for out-of-range starting position. */
- if (startpos < 0 || startpos > total_size)
- return -1;
-
- /* Fix up range if it would eventually take startpos outside of the
- virtual concatenation of string1 and string2. */
- if (endpos < -1)
- range = -1 - startpos;
- else if (endpos > total_size)
- range = total_size - startpos;
-
- /* Update the fastmap now if not correct already. */
- if (fastmap && !pbufp->fastmap_accurate)
- re_compile_fastmap (pbufp);
-
- /* If the search isn't to be a backwards one, don't waste time in a
- long search for a pattern that says it is anchored. */
- if (pbufp->used > 0 && (enum regexpcode) pbufp->buffer[0] == begbuf
- && range > 0)
- {
- if (startpos > 0)
- return -1;
- else
- range = 1;
- }
-
- while (1)
- {
- /* If a fastmap is supplied, skip quickly over characters that
- cannot possibly be the start of a match. Note, however, that
- if the pattern can possibly match the null string, we must
- test it at each starting point so that we take the first null
- string we get. */
-
- if (fastmap && startpos < total_size && pbufp->can_be_null != 1)
- {
- if (range > 0) /* Searching forwards. */
- {
- register int lim = 0;
- register unsigned char *p;
- int irange = range;
- if (startpos < size1 && startpos + range >= size1)
- lim = range - (size1 - startpos);
-
- p = ((unsigned char *)
- &(startpos >= size1 ? string2 - size1 : string1)[startpos]);
-
- while (range > lim && !fastmap[translate
- ? translate[*p++]
- : *p++])
- range--;
- startpos += irange - range;
- }
- else /* Searching backwards. */
- {
- register unsigned char c;
-
- if (string1 == 0 || startpos >= size1)
- c = string2[startpos - size1];
- else
- c = string1[startpos];
-
- c &= 0xff;
- if (translate ? !fastmap[translate[c]] : !fastmap[c])
- goto advance;
- }
- }
-
- if (range >= 0 && startpos == total_size
- && fastmap && pbufp->can_be_null == 0)
- return -1;
-
- val = re_match_2 (pbufp, string1, size1, string2, size2, startpos,
- regs, mstop);
- if (val >= 0)
- return startpos;
- if (val == -2)
- return -2;
-
-#ifdef C_ALLOCA
- alloca (0);
-#endif /* C_ALLOCA */
-
- advance:
- if (!range)
- break;
- else if (range > 0)
- {
- range--;
- startpos++;
- }
- else
- {
- range++;
- startpos--;
- }
- }
- return -1;
-}
-
-
-
-#ifndef emacs /* emacs never uses this. */
-int
-re_match (struct re_pattern_buffer *pbufp,
- char *string,
- int size,
- int pos,
- struct re_registers *regs)
-{
- return re_match_2 (pbufp, (char *) 0, 0, string, size, pos, regs, size);
-}
-#endif /* not emacs */
-
-
-/* The following are used for re_match_2, defined below: */
-
-/* Roughly the maximum number of failure points on the stack. Would be
- exactly that if always pushed MAX_NUM_FAILURE_ITEMS each time we failed. */
-
-int re_max_failures = 2000;
-
-/* Routine used by re_match_2. */
-static int bcmp_translate (char *, char *, int, unsigned char *);
-
-
-/* Structure and accessing macros used in re_match_2: */
-
-struct register_info
-{
- unsigned is_active : 1;
- unsigned matched_something : 1;
-};
-
-#define IS_ACTIVE(R) ((R).is_active)
-#define MATCHED_SOMETHING(R) ((R).matched_something)
-
-
-/* Macros used by re_match_2: */
-
-
-/* I.e., regstart, regend, and reg_info. */
-
-#define NUM_REG_ITEMS 3
-
-/* We push at most this many things on the stack whenever we
- fail. The `+ 2' refers to PATTERN_PLACE and STRING_PLACE, which are
- arguments to the PUSH_FAILURE_POINT macro. */
-
-#define MAX_NUM_FAILURE_ITEMS (RE_NREGS * NUM_REG_ITEMS + 2)
-
-
-/* We push this many things on the stack whenever we fail. */
-
-#define NUM_FAILURE_ITEMS (last_used_reg * NUM_REG_ITEMS + 2)
-
-
-/* This pushes most of the information about the current state we will want
- if we ever fail back to it. */
-
-#define PUSH_FAILURE_POINT(pattern_place, string_place) \
- { \
- short last_used_reg, this_reg; \
- \
- /* Find out how many registers are active or have been matched. \
- (Aside from register zero, which is only set at the end.) */ \
- for (last_used_reg = RE_NREGS - 1; last_used_reg > 0; last_used_reg--)\
- if (regstart[last_used_reg] != (unsigned char *) -1) \
- break; \
- \
- if (stacke - stackp < NUM_FAILURE_ITEMS) \
- { \
- unsigned char **stackx; \
- int len = stacke - stackb; \
- if (len > re_max_failures * MAX_NUM_FAILURE_ITEMS) \
- return -2; \
- \
- /* Roughly double the size of the stack. */ \
- stackx = (unsigned char **) alloca (2 * len \
- * sizeof (unsigned char *));\
- /* Only copy what is in use. */ \
- memcpy (stackx, stackb, len * sizeof (char *)); \
- stackp = stackx + (stackp - stackb); \
- stackb = stackx; \
- stacke = stackb + 2 * len; \
- } \
- \
- /* Now push the info for each of those registers. */ \
- for (this_reg = 1; this_reg <= last_used_reg; this_reg++) \
- { \
- *stackp++ = regstart[this_reg]; \
- *stackp++ = regend[this_reg]; \
- *stackp++ = (unsigned char *) &reg_info[this_reg]; \
- } \
- \
- /* Push how many registers we saved. */ \
- *stackp++ = (unsigned char *) last_used_reg; \
- \
- *stackp++ = pattern_place; \
- *stackp++ = string_place; \
- }
-
-
-/* This pops what PUSH_FAILURE_POINT pushes. */
-
-#define POP_FAILURE_POINT() \
- { \
- int temp; \
- stackp -= 2; /* Remove failure points. */ \
- temp = (int) *--stackp; /* How many regs pushed. */ \
- temp *= NUM_REG_ITEMS; /* How much to take off the stack. */ \
- stackp -= temp; /* Remove the register info. */ \
- }
-
-
-#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
-
-/* Is true if there is a first string and if PTR is pointing anywhere
- inside it or just past the end. */
-
-#define IS_IN_FIRST_STRING(ptr) \
- (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
-
-/* Call before fetching a character with *d. This switches over to
- string2 if necessary. */
-
-#define PREFETCH \
- while (d == dend) \
- { \
- /* end of string2 => fail. */ \
- if (dend == end_match_2) \
- goto fail; \
- /* end of string1 => advance to string2. */ \
- d = string2; \
- dend = end_match_2; \
- }
-
-
-/* Call this when have matched something; it sets `matched' flags for the
- registers corresponding to the subexpressions of which we currently
- are inside. */
-#define SET_REGS_MATCHED \
- { unsigned this_reg; \
- for (this_reg = 0; this_reg < RE_NREGS; this_reg++) \
- { \
- if (IS_ACTIVE(reg_info[this_reg])) \
- MATCHED_SOMETHING(reg_info[this_reg]) = 1; \
- else \
- MATCHED_SOMETHING(reg_info[this_reg]) = 0; \
- } \
- }
-
-/* Test if at very beginning or at very end of the virtual concatenation
- of string1 and string2. If there is only one string, we've put it in
- string2. */
-
-#define AT_STRINGS_BEG (d == (size1 ? string1 : string2) || !size2)
-#define AT_STRINGS_END (d == end2)
-
-#define AT_WORD_BOUNDARY \
- (AT_STRINGS_BEG || AT_STRINGS_END || IS_A_LETTER (d - 1) != IS_A_LETTER (d))
-
-/* We have two special cases to check for:
- 1) if we're past the end of string1, we have to look at the first
- character in string2;
- 2) if we're before the beginning of string2, we have to look at the
- last character in string1; we assume there is a string1, so use
- this in conjunction with AT_STRINGS_BEG. */
-#define IS_A_LETTER(d) \
- (SYNTAX ((d) == end1 ? *string2 : (d) == string2 - 1 ? *(end1 - 1) : *(d))\
- == Sword)
-
-
-/* Match the pattern described by PBUFP against the virtual
- concatenation of STRING1 and STRING2, which are of SIZE1 and SIZE2,
- respectively. Start the match at index POS in the virtual
- concatenation of STRING1 and STRING2. In REGS, return the indices of
- the virtual concatenation of STRING1 and STRING2 that matched the
- entire PBUFP->buffer and its contained subexpressions. Do not
- consider matching one past the index MSTOP in the virtual
- concatenation of STRING1 and STRING2.
-
- If pbufp->fastmap is nonzero, then it had better be up to date.
-
- The reason that the data to match are specified as two components
- which are to be regarded as concatenated is so this function can be
- used directly on the contents of an Emacs buffer.
-
- -1 is returned if there is no match. -2 is returned if there is an
- error (such as match stack overflow). Otherwise the value is the
- length of the substring which was matched. */
-
-int
-re_match_2 (struct re_pattern_buffer *pbufp,
- char *string1_arg, int size1,
- char *string2_arg, int size2,
- int pos,
- struct re_registers *regs,
- int mstop)
-{
- register unsigned char *p = (unsigned char *) pbufp->buffer;
-
- /* Pointer to beyond end of buffer. */
- register unsigned char *pend = p + pbufp->used;
-
- unsigned char *string1 = (unsigned char *) string1_arg;
- unsigned char *string2 = (unsigned char *) string2_arg;
- unsigned char *end1; /* Just past end of first string. */
- unsigned char *end2; /* Just past end of second string. */
-
- /* Pointers into string1 and string2, just past the last characters in
- each to consider matching. */
- unsigned char *end_match_1, *end_match_2;
-
- register unsigned char *d, *dend;
- register int mcnt; /* Multipurpose. */
- unsigned char *translate = (unsigned char *) pbufp->translate;
- unsigned is_a_jump_n = 0;
-
- /* Failure point stack. Each place that can handle a failure further
- down the line pushes a failure point on this stack. It consists of
- restart, regend, and reg_info for all registers corresponding to the
- subexpressions we're currently inside, plus the number of such
- registers, and, finally, two char *'s. The first char * is where to
- resume scanning the pattern; the second one is where to resume
- scanning the strings. If the latter is zero, the failure point is a
- ``dummy''; if a failure happens and the failure point is a dummy, it
- gets discarded and the next next one is tried. */
-
- unsigned char *initial_stack[MAX_NUM_FAILURE_ITEMS * NFAILURES];
- unsigned char **stackb = initial_stack;
- unsigned char **stackp = stackb;
- unsigned char **stacke = &stackb[MAX_NUM_FAILURE_ITEMS * NFAILURES];
-
-
- /* Information on the contents of registers. These are pointers into
- the input strings; they record just what was matched (on this
- attempt) by a subexpression part of the pattern, that is, the
- regnum-th regstart pointer points to where in the pattern we began
- matching and the regnum-th regend points to right after where we
- stopped matching the regnum-th subexpression. (The zeroth register
- keeps track of what the whole pattern matches.) */
-
- unsigned char *regstart[RE_NREGS];
- unsigned char *regend[RE_NREGS];
-
- /* The is_active field of reg_info helps us keep track of which (possibly
- nested) subexpressions we are currently in. The matched_something
- field of reg_info[reg_num] helps us tell whether or not we have
- matched any of the pattern so far this time through the reg_num-th
- subexpression. These two fields get reset each time through any
- loop their register is in. */
-
- struct register_info reg_info[RE_NREGS];
-
-
- /* The following record the register info as found in the above
- variables when we find a match better than any we've seen before.
- This happens as we backtrack through the failure points, which in
- turn happens only if we have not yet matched the entire string. */
-
- unsigned best_regs_set = 0;
- unsigned char *best_regstart[RE_NREGS];
- unsigned char *best_regend[RE_NREGS];
-
- /* Initialize subexpression text positions to -1 to mark ones that no
- \( or ( and \) or ) has been seen for. Also set all registers to
- inactive and mark them as not having matched anything or ever
- failed. */
- for (mcnt = 0; mcnt < RE_NREGS; mcnt++)
- {
- regstart[mcnt] = regend[mcnt] = (unsigned char *) -1;
- IS_ACTIVE (reg_info[mcnt]) = 0;
- MATCHED_SOMETHING (reg_info[mcnt]) = 0;
- }
-
- if (regs)
- for (mcnt = 0; mcnt < RE_NREGS; mcnt++)
- regs->start[mcnt] = regs->end[mcnt] = -1;
-
- /* Set up pointers to ends of strings.
- Don't allow the second string to be empty unless both are empty. */
- if (size2 == 0)
- {
- string2 = string1;
- size2 = size1;
- string1 = 0;
- size1 = 0;
- }
- end1 = string1 + size1;
- end2 = string2 + size2;
-
- /* Compute where to stop matching, within the two strings. */
- if (mstop <= size1)
- {
- end_match_1 = string1 + mstop;
- end_match_2 = string2;
- }
- else
- {
- end_match_1 = end1;
- end_match_2 = string2 + mstop - size1;
- }
-
- /* `p' scans through the pattern as `d' scans through the data. `dend'
- is the end of the input string that `d' points within. `d' is
- advanced into the following input string whenever necessary, but
- this happens before fetching; therefore, at the beginning of the
- loop, `d' can be pointing at the end of a string, but it cannot
- equal string2. */
-
- if (size1 != 0 && pos <= size1)
- d = string1 + pos, dend = end_match_1;
- else
- d = string2 + pos - size1, dend = end_match_2;
-
-
- /* This loops over pattern commands. It exits by returning from the
- function if match is complete, or it drops through if match fails
- at this starting point in the input data. */
-
- while (1)
- {
- is_a_jump_n = 0;
- /* End of pattern means we might have succeeded. */
- if (p == pend)
- {
- /* If not end of string, try backtracking. Otherwise done. */
- if (d != end_match_2)
- {
- if (stackp != stackb)
- {
- /* More failure points to try. */
-
- unsigned in_same_string =
- IS_IN_FIRST_STRING (best_regend[0])
- == MATCHING_IN_FIRST_STRING;
-
- /* If exceeds best match so far, save it. */
- if (! best_regs_set
- || (in_same_string && d > best_regend[0])
- || (! in_same_string && ! MATCHING_IN_FIRST_STRING))
- {
- best_regs_set = 1;
- best_regend[0] = d; /* Never use regstart[0]. */
-
- for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
- {
- best_regstart[mcnt] = regstart[mcnt];
- best_regend[mcnt] = regend[mcnt];
- }
- }
- goto fail;
- }
- /* If no failure points, don't restore garbage. */
- else if (best_regs_set)
- {
- restore_best_regs:
- /* Restore best match. */
- d = best_regend[0];
-
- for (mcnt = 0; mcnt < RE_NREGS; mcnt++)
- {
- regstart[mcnt] = best_regstart[mcnt];
- regend[mcnt] = best_regend[mcnt];
- }
- }
- }
-
- /* If caller wants register contents data back, convert it
- to indices. */
- if (regs)
- {
- regs->start[0] = pos;
- if (MATCHING_IN_FIRST_STRING)
- regs->end[0] = d - string1;
- else
- regs->end[0] = d - string2 + size1;
- for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
- {
- if (regend[mcnt] == (unsigned char *) -1)
- {
- regs->start[mcnt] = -1;
- regs->end[mcnt] = -1;
- continue;
- }
- if (IS_IN_FIRST_STRING (regstart[mcnt]))
- regs->start[mcnt] = regstart[mcnt] - string1;
- else
- regs->start[mcnt] = regstart[mcnt] - string2 + size1;
-
- if (IS_IN_FIRST_STRING (regend[mcnt]))
- regs->end[mcnt] = regend[mcnt] - string1;
- else
- regs->end[mcnt] = regend[mcnt] - string2 + size1;
- }
- }
- return d - pos - (MATCHING_IN_FIRST_STRING
- ? string1
- : string2 - size1);
- }
-
- /* Otherwise match next pattern command. */
-#ifdef SWITCH_ENUM_BUG
- switch ((int) ((enum regexpcode) *p++))
-#else
- switch ((enum regexpcode) *p++)
-#endif
- {
-
- /* \( [or `(', as appropriate] is represented by start_memory,
- \) by stop_memory. Both of those commands are followed by
- a register number in the next byte. The text matched
- within the \( and \) is recorded under that number. */
- case start_memory:
- regstart[*p] = d;
- IS_ACTIVE (reg_info[*p]) = 1;
- MATCHED_SOMETHING (reg_info[*p]) = 0;
- p++;
- break;
-
- case stop_memory:
- regend[*p] = d;
- IS_ACTIVE (reg_info[*p]) = 0;
-
- /* If just failed to match something this time around with a sub-
- expression that's in a loop, try to force exit from the loop. */
- if ((! MATCHED_SOMETHING (reg_info[*p])
- || (enum regexpcode) p[-3] == start_memory)
- && (p + 1) != pend)
- {
- register unsigned char *p2 = p + 1;
- mcnt = 0;
- switch (*p2++)
- {
- case jump_n:
- is_a_jump_n = 1;
- case finalize_jump:
- case maybe_finalize_jump:
- case jump:
- case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p2);
- if (is_a_jump_n)
- p2 += 2;
- break;
- }
- p2 += mcnt;
-
- /* If the next operation is a jump backwards in the pattern
- to an on_failure_jump, exit from the loop by forcing a
- failure after pushing on the stack the on_failure_jump's
- jump in the pattern, and d. */
- if (mcnt < 0 && (enum regexpcode) *p2++ == on_failure_jump)
- {
- EXTRACT_NUMBER_AND_INCR (mcnt, p2);
- PUSH_FAILURE_POINT (p2 + mcnt, d);
- goto fail;
- }
- }
- p++;
- break;
-
- /* \<digit> has been turned into a `duplicate' command which is
- followed by the numeric value of <digit> as the register number. */
- case duplicate:
- {
- int regno = *p++; /* Get which register to match against */
- register unsigned char *d2, *dend2;
-
- /* Where in input to try to start matching. */
- d2 = regstart[regno];
-
- /* Where to stop matching; if both the place to start and
- the place to stop matching are in the same string, then
- set to the place to stop, otherwise, for now have to use
- the end of the first string. */
-
- dend2 = ((IS_IN_FIRST_STRING (regstart[regno])
- == IS_IN_FIRST_STRING (regend[regno]))
- ? regend[regno] : end_match_1);
- while (1)
- {
- /* If necessary, advance to next segment in register
- contents. */
- while (d2 == dend2)
- {
- if (dend2 == end_match_2) break;
- if (dend2 == regend[regno]) break;
- d2 = string2, dend2 = regend[regno]; /* end of string1 => advance to string2. */
- }
- /* At end of register contents => success */
- if (d2 == dend2) break;
-
- /* If necessary, advance to next segment in data. */
- PREFETCH;
-
- /* How many characters left in this segment to match. */
- mcnt = dend - d;
-
- /* Want how many consecutive characters we can match in
- one shot, so, if necessary, adjust the count. */
- if (mcnt > dend2 - d2)
- mcnt = dend2 - d2;
-
- /* Compare that many; failure if mismatch, else move
- past them. */
- if (translate
- ? bcmp_translate ((char*)d, (char*)d2, mcnt, translate)
- : memcmp (d, d2, mcnt))
- goto fail;
- d += mcnt, d2 += mcnt;
- }
- }
- break;
-
- case anychar:
- PREFETCH; /* Fetch a data character. */
- /* Match anything but a newline, maybe even a null. */
- if ((translate ? translate[*d] : *d) == '\n'
- || ((obscure_syntax & RE_DOT_NOT_NULL)
- && (translate ? translate[*d] : *d) == '\000'))
- goto fail;
- SET_REGS_MATCHED;
- d++;
- break;
-
- case charset:
- case charset_not:
- {
- int not = 0; /* Nonzero for charset_not. */
- register int c;
- if (*(p - 1) == (unsigned char) charset_not)
- not = 1;
-
- PREFETCH; /* Fetch a data character. */
-
- if (translate)
- c = translate[*d];
- else
- c = *d;
-
- if (c < *p * BYTEWIDTH
- && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
- not = !not;
-
- p += 1 + *p;
-
- if (!not) goto fail;
- SET_REGS_MATCHED;
- d++;
- break;
- }
-
- case begline:
- if ((size1 != 0 && d == string1)
- || (size1 == 0 && size2 != 0 && d == string2)
- || (d && d[-1] == '\n')
- || (size1 == 0 && size2 == 0))
- break;
- else
- goto fail;
-
- case endline:
- if (d == end2
- || (d == end1 ? (size2 == 0 || *string2 == '\n') : *d == '\n'))
- break;
- goto fail;
-
- /* `or' constructs are handled by starting each alternative with
- an on_failure_jump that points to the start of the next
- alternative. Each alternative except the last ends with a
- jump to the joining point. (Actually, each jump except for
- the last one really jumps to the following jump, because
- tensioning the jumps is a hassle.) */
-
- /* The start of a stupid repeat has an on_failure_jump that points
- past the end of the repeat text. This makes a failure point so
- that on failure to match a repetition, matching restarts past
- as many repetitions have been found with no way to fail and
- look for another one. */
-
- /* A smart repeat is similar but loops back to the on_failure_jump
- so that each repetition makes another failure point. */
-
- case on_failure_jump:
- on_failure:
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- PUSH_FAILURE_POINT (p + mcnt, d);
- break;
-
- /* The end of a smart repeat has a maybe_finalize_jump back.
- Change it either to a finalize_jump or an ordinary jump. */
- case maybe_finalize_jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- {
- register unsigned char *p2 = p;
- /* Compare what follows with the beginning of the repeat.
- If we can establish that there is nothing that they would
- both match, we can change to finalize_jump. */
- while (p2 + 1 != pend
- && (*p2 == (unsigned char) stop_memory
- || *p2 == (unsigned char) start_memory))
- p2 += 2; /* Skip over reg number. */
- if (p2 == pend)
- p[-3] = (unsigned char) finalize_jump;
- else if (*p2 == (unsigned char) exactn
- || *p2 == (unsigned char) endline)
- {
- register int c = *p2 == (unsigned char) endline ? '\n' : p2[2];
- register unsigned char *p1 = p + mcnt;
- /* p1[0] ... p1[2] are an on_failure_jump.
- Examine what follows that. */
- if (p1[3] == (unsigned char) exactn && p1[5] != c)
- p[-3] = (unsigned char) finalize_jump;
- else if (p1[3] == (unsigned char) charset
- || p1[3] == (unsigned char) charset_not)
- {
- int not = p1[3] == (unsigned char) charset_not;
- if (c < p1[4] * BYTEWIDTH
- && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
- not = !not;
- /* `not' is 1 if c would match. */
- /* That means it is not safe to finalize. */
- if (!not)
- p[-3] = (unsigned char) finalize_jump;
- }
- }
- }
- p -= 2; /* Point at relative address again. */
- if (p[-1] != (unsigned char) finalize_jump)
- {
- p[-1] = (unsigned char) jump;
- goto nofinalize;
- }
- /* Note fall through. */
-
- /* The end of a stupid repeat has a finalize_jump back to the
- start, where another failure point will be made which will
- point to after all the repetitions found so far. */
-
- /* Take off failure points put on by matching on_failure_jump
- because didn't fail. Also remove the register information
- put on by the on_failure_jump. */
- case finalize_jump:
- POP_FAILURE_POINT ();
- /* Note fall through. */
-
- /* Jump without taking off any failure points. */
- case jump:
- nofinalize:
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- p += mcnt;
- break;
-
- case dummy_failure_jump:
- /* Normally, the on_failure_jump pushes a failure point, which
- then gets popped at finalize_jump. We will end up at
- finalize_jump, also, and with a pattern of, say, `a+', we
- are skipping over the on_failure_jump, so we have to push
- something meaningless for finalize_jump to pop. */
- PUSH_FAILURE_POINT (0, 0);
- goto nofinalize;
-
-
- /* Have to succeed matching what follows at least n times. Then
- just handle like an on_failure_jump. */
- case succeed_n:
- EXTRACT_NUMBER (mcnt, p + 2);
- /* Originally, this is how many times we HAVE to succeed. */
- if (mcnt)
- {
- mcnt--;
- p += 2;
- STORE_NUMBER_AND_INCR (p, mcnt);
- }
- else if (mcnt == 0)
- {
- p[2] = unused;
- p[3] = unused;
- goto on_failure;
- }
- else
- {
- fprintf (stderr, "regex: the succeed_n's n is not set.\n");
- exit (1);
- }
- break;
-
- case jump_n:
- EXTRACT_NUMBER (mcnt, p + 2);
- /* Originally, this is how many times we CAN jump. */
- if (mcnt)
- {
- mcnt--;
- STORE_NUMBER(p + 2, mcnt);
- goto nofinalize; /* Do the jump without taking off
- any failure points. */
- }
- /* If don't have to jump any more, skip over the rest of command. */
- else
- p += 4;
- break;
-
- case set_number_at:
- {
- register unsigned char *p1;
-
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- p1 = p + mcnt;
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- STORE_NUMBER (p1, mcnt);
- break;
- }
-
- /* Ignore these. Used to ignore the n of succeed_n's which
- currently have n == 0. */
- case unused:
- break;
-
- case wordbound:
- if (AT_WORD_BOUNDARY)
- break;
- goto fail;
-
- case notwordbound:
- if (AT_WORD_BOUNDARY)
- goto fail;
- break;
-
- case wordbeg:
- /* Have to check if AT_STRINGS_BEG before looking at d - 1. */
- if (IS_A_LETTER (d) && (AT_STRINGS_BEG || !IS_A_LETTER (d - 1)))
- break;
- goto fail;
-
- case wordend:
- /* Have to check if AT_STRINGS_BEG before looking at d - 1. */
- if (!AT_STRINGS_BEG && IS_A_LETTER (d - 1)
- && (!IS_A_LETTER (d) || AT_STRINGS_END))
- break;
- goto fail;
-
-#ifdef emacs
- case before_dot:
- if (PTR_CHAR_POS (d) >= point)
- goto fail;
- break;
-
- case at_dot:
- if (PTR_CHAR_POS (d) != point)
- goto fail;
- break;
-
- case after_dot:
- if (PTR_CHAR_POS (d) <= point)
- goto fail;
- break;
-
- case wordchar:
- mcnt = (int) Sword;
- goto matchsyntax;
-
- case syntaxspec:
- mcnt = *p++;
- matchsyntax:
- PREFETCH;
- if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail;
- SET_REGS_MATCHED;
- break;
-
- case notwordchar:
- mcnt = (int) Sword;
- goto matchnotsyntax;
-
- case notsyntaxspec:
- mcnt = *p++;
- matchnotsyntax:
- PREFETCH;
- if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail;
- SET_REGS_MATCHED;
- break;
-
-#else /* not emacs */
-
- case wordchar:
- PREFETCH;
- if (!IS_A_LETTER (d))
- goto fail;
- SET_REGS_MATCHED;
- break;
-
- case notwordchar:
- PREFETCH;
- if (IS_A_LETTER (d))
- goto fail;
- SET_REGS_MATCHED;
- break;
-
-#endif /* not emacs */
-
- case begbuf:
- if (AT_STRINGS_BEG)
- break;
- goto fail;
-
- case endbuf:
- if (AT_STRINGS_END)
- break;
- goto fail;
-
- case exactn:
- /* Match the next few pattern characters exactly.
- mcnt is how many characters to match. */
- mcnt = *p++;
- /* This is written out as an if-else so we don't waste time
- testing `translate' inside the loop. */
- if (translate)
- {
- do
- {
- PREFETCH;
- if (translate[*d++] != *p++) goto fail;
- }
- while (--mcnt);
- }
- else
- {
- do
- {
- PREFETCH;
- if (*d++ != *p++) goto fail;
- }
- while (--mcnt);
- }
- SET_REGS_MATCHED;
- break;
- }
- continue; /* Successfully executed one pattern command; keep going. */
-
- /* Jump here if any matching operation fails. */
- fail:
- if (stackp != stackb)
- /* A restart point is known. Restart there and pop it. */
- {
- short last_used_reg, this_reg;
-
- /* If this failure point is from a dummy_failure_point, just
- skip it. */
- if (!stackp[-2])
- {
- POP_FAILURE_POINT ();
- goto fail;
- }
-
- d = *--stackp;
- p = *--stackp;
- if (d >= string1 && d <= end1)
- dend = end_match_1;
- /* Restore register info. */
- last_used_reg = (short) (int) *--stackp;
-
- /* Make the ones that weren't saved -1 or 0 again. */
- for (this_reg = RE_NREGS - 1; this_reg > last_used_reg; this_reg--)
- {
- regend[this_reg] = (unsigned char *) -1;
- regstart[this_reg] = (unsigned char *) -1;
- IS_ACTIVE (reg_info[this_reg]) = 0;
- MATCHED_SOMETHING (reg_info[this_reg]) = 0;
- }
-
- /* And restore the rest from the stack. */
- for ( ; this_reg > 0; this_reg--)
- {
- reg_info[this_reg] = *(struct register_info *) *--stackp;
- regend[this_reg] = *--stackp;
- regstart[this_reg] = *--stackp;
- }
- }
- else
- break; /* Matching at this starting point really fails. */
- }
-
- if (best_regs_set)
- goto restore_best_regs;
- return -1; /* Failure to match. */
-}
-
-
-static int
-bcmp_translate (char *s1, char *s2, int len, unsigned char *translate)
-{
- register unsigned char *p1 = (unsigned char*)s1;
- register unsigned char *p2 = (unsigned char*)s2;
- while (len)
- {
- if (translate [*p1++] != translate [*p2++]) return 1;
- len--;
- }
- return 0;
-}
-
-
-
-/* Entry points compatible with 4.2 BSD regex library. */
-
-#if 0
-
-static struct re_pattern_buffer re_comp_buf;
-
-char *
-re_comp (char *s)
-{
- if (!s)
- {
- if (!re_comp_buf.buffer)
- return "No previous regular expression";
- return 0;
- }
-
- if (!re_comp_buf.buffer)
- {
- if (!(re_comp_buf.buffer = (char *) malloc (200)))
- return "Memory exhausted";
- re_comp_buf.allocated = 200;
- if (!(re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH)))
- return "Memory exhausted";
- }
- return re_compile_pattern (s, strlen (s), &re_comp_buf);
-}
-
-int
-re_exec (char *s)
-{
- int len = strlen (s);
- return 0 <= re_search (&re_comp_buf, s, len, 0, len,
- (struct re_registers *) 0);
-}
-#endif /* not emacs */
-
-
-
-#ifdef test
-
-#include <stdio.h>
-
-/* Indexed by a character, gives the upper case equivalent of the
- character. */
-
-char upcase[0400] =
- { 000, 001, 002, 003, 004, 005, 006, 007,
- 010, 011, 012, 013, 014, 015, 016, 017,
- 020, 021, 022, 023, 024, 025, 026, 027,
- 030, 031, 032, 033, 034, 035, 036, 037,
- 040, 041, 042, 043, 044, 045, 046, 047,
- 050, 051, 052, 053, 054, 055, 056, 057,
- 060, 061, 062, 063, 064, 065, 066, 067,
- 070, 071, 072, 073, 074, 075, 076, 077,
- 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
- 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
- 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
- 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
- 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
- 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
- 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
- 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
- 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
- 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
- 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
- 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
- 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
- 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
- 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
- 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
- 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
- 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
- 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
- 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
- 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
- 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
- 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
- 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
- };
-
-#ifdef canned
-
-#include "tests.h"
-
-typedef enum { extended_test, basic_test } test_type;
-
-/* Use this to run the tests we've thought of. */
-
-void
-main ()
-{
- test_type t = extended_test;
-
- if (t == basic_test)
- {
- printf ("Running basic tests:\n\n");
- test_posix_basic ();
- }
- else if (t == extended_test)
- {
- printf ("Running extended tests:\n\n");
- test_posix_extended ();
- }
-}
-
-#else /* not canned */
-
-/* Use this to run interactive tests. */
-
-void
-main (int argc, char **argv)
-{
- char pat[80];
- struct re_pattern_buffer buf;
- int i;
- char c;
- char fastmap[(1 << BYTEWIDTH)];
-
- /* Allow a command argument to specify the style of syntax. */
- if (argc > 1)
- obscure_syntax = atoi (argv[1]);
-
- buf.allocated = 40;
- buf.buffer = (char *) malloc (buf.allocated);
- buf.fastmap = fastmap;
- buf.translate = upcase;
-
- while (1)
- {
- gets (pat);
-
- if (*pat)
- {
- re_compile_pattern (pat, strlen(pat), &buf);
-
- for (i = 0; i < buf.used; i++)
- printchar (buf.buffer[i]);
-
- putchar ('\n');
-
- printf ("%d allocated, %d used.\n", buf.allocated, buf.used);
-
- re_compile_fastmap (&buf);
- printf ("Allowed by fastmap: ");
- for (i = 0; i < (1 << BYTEWIDTH); i++)
- if (fastmap[i]) printchar (i);
- putchar ('\n');
- }
-
- gets (pat); /* Now read the string to match against */
-
- i = re_match (&buf, pat, strlen (pat), 0, 0);
- printf ("Match value %d.\n", i);
- }
-}
-
-#endif
-
-
-#ifdef NOTDEF
-void
-print_buf (struct re_pattern_buffer *bufpbufp)
-{
- int i;
-
- printf ("buf is :\n----------------\n");
- for (i = 0; i < bufp->used; i++)
- printchar (bufp->buffer[i]);
-
- printf ("\n%d allocated, %d used.\n", bufp->allocated, bufp->used);
-
- printf ("Allowed by fastmap: ");
- for (i = 0; i < (1 << BYTEWIDTH); i++)
- if (bufp->fastmap[i])
- printchar (i);
- printf ("\nAllowed by translate: ");
- if (bufp->translate)
- for (i = 0; i < (1 << BYTEWIDTH); i++)
- if (bufp->translate[i])
- printchar (i);
- printf ("\nfastmap is%s accurate\n", bufp->fastmap_accurate ? "" : "n't");
- printf ("can %s be null\n----------", bufp->can_be_null ? "" : "not");
-}
-#endif /* NOTDEF */
-
-void
-printchar (char c)
-{
- if (c < 040 || c >= 0177)
- {
- putchar ('\\');
- putchar (((c >> 6) & 3) + '0');
- putchar (((c >> 3) & 7) + '0');
- putchar ((c & 7) + '0');
- }
- else
- putchar (c);
-}
-
-void
-error (char *string)
-{
- puts (string);
- exit (1);
-}
-#endif /* test */
diff --git a/gnu/lib/libg++/libg++/timer.c b/gnu/lib/libg++/libg++/timer.c
index 73a856af3a19..6e3432bf5b42 100644
--- a/gnu/lib/libg++/libg++/timer.c
+++ b/gnu/lib/libg++/libg++/timer.c
@@ -37,6 +37,7 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#if !_G_HAVE_SYS_RESOURCE || !defined(RUSAGE_SELF)
#define USE_TIMES
#include <sys/param.h>
+#include <sys/types.h>
#include <sys/times.h>
#if !defined (HZ) && defined(CLK_TCK)
#define HZ CLK_TCK
diff --git a/gnu/lib/libg++/libio/fileops.c b/gnu/lib/libg++/libio/fileops.c
index 47398a82b1ef..2bd7c2410990 100644
--- a/gnu/lib/libg++/libio/fileops.c
+++ b/gnu/lib/libg++/libio/fileops.c
@@ -44,7 +44,8 @@ extern int errno;
The position in the buffer that corresponds to the position
in external file system is file_ptr().
- This is normally egptr(), except in putback mode, when it is _save_egptr.
+ This is normally _IO_read_end, except in putback mode,
+ when it is _IO_save_end.
If the field _fb._offset is >= 0, it gives the offset in
the file as a whole corresponding to eGptr(). (???)
@@ -238,7 +239,7 @@ _IO_do_write(fp, data, to_do)
fp->_cur_column = _IO_adjust_column(fp->_cur_column - 1, data, to_do) + 1;
_IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
- fp->_IO_write_end = (fp->_flags & _IO_LINE_BUF+_IO_UNBUFFERED) ? fp->_IO_buf_base
+ fp->_IO_write_end = (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) ? fp->_IO_buf_base
: fp->_IO_buf_end;
return count != to_do ? EOF : 0;
}
@@ -311,7 +312,7 @@ int _IO_file_overflow (f, ch)
f->_IO_write_end = f->_IO_buf_end;
f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
- if (f->_flags & _IO_LINE_BUF+_IO_UNBUFFERED)
+ if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
f->_IO_write_end = f->_IO_write_ptr;
f->_flags |= _IO_CURRENTLY_PUTTING;
}
@@ -389,10 +390,10 @@ _IO_file_seekoff(fp, offset, mode)
switch (dir)
{
case _IO_seek_cur:
- if (fp->_offset == _IO_pos_BAD)
- goto dumb;
/* Adjust for read-ahead (bytes is buffer). */
offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ if (fp->_offset == _IO_pos_BAD)
+ goto dumb;
/* Make offset absolute, assuming current pointer is file_ptr(). */
offset += _IO_pos_as_off(fp->_offset);
@@ -414,24 +415,27 @@ _IO_file_seekoff(fp, offset, mode)
}
/* At this point, dir==_IO_seek_set. */
-#ifdef TODO
/* If destination is within current buffer, optimize: */
- if (fp->_offset != IO_pos_BAD && fp->_IO_read_base != NULL)
+ if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
+ && !_IO_in_backup (fp))
{
/* Offset relative to start of main get area. */
- _IO_pos_t rel_offset = offset - _fb._offset
- + (eGptr()-Gbase());
+ _IO_pos_t rel_offset = offset - fp->_offset
+ + (fp->_IO_read_end - fp->_IO_read_base);
if (rel_offset >= 0)
{
+#if 0
if (_IO_in_backup(fp))
_IO_switch_to_main_get_area(fp);
- if (rel_offset <= _IO_read_end - _IO_read_base)
+#endif
+ if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
{
- _IO_setg(fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
+ _IO_setg(fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
fp->_IO_read_end);
- _IO_setp(fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_setp(fp, fp->_IO_buf_base, fp->_IO_buf_base);
return offset;
}
+#ifdef TODO
/* If we have streammarkers, seek forward by reading ahead. */
if (_IO_have_markers(fp))
{
@@ -441,7 +445,9 @@ _IO_file_seekoff(fp, offset, mode)
goto dumb;
return offset;
}
+#endif
}
+#ifdef TODO
if (rel_offset < 0 && rel_offset >= Bbase() - Bptr())
{
if (!_IO_in_backup(fp))
@@ -449,8 +455,10 @@ _IO_file_seekoff(fp, offset, mode)
gbump(fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
return offset;
}
+#endif
}
+#ifdef TODO
_IO_unsave_markers(fp);
#endif
diff --git a/gnu/lib/libg++/libio/floatconv.c b/gnu/lib/libg++/libio/floatconv.c
index 84eb8487aa15..ff300bbbefca 100644
--- a/gnu/lib/libg++/libio/floatconv.c
+++ b/gnu/lib/libg++/libio/floatconv.c
@@ -23,7 +23,7 @@ This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#include <libioP.h>
-#ifdef USE_DTOA
+#ifdef _IO_USE_DTOA
/****************************************************************
*
* The author of this software is David M. Gay.
@@ -489,7 +489,7 @@ s2b
#endif
{
int i, k;
- long x, y;
+ _G_int32_t x, y;
x = (nd + 8) / 9;
for(k = 0, y = 1; x > y; y <<= 1, k++) ;
@@ -643,7 +643,7 @@ mult
xbe = xb + wb;
xc0 = c->x;
for(; xb < xbe; xb++, xc0++) {
- if (y = *xb & 0xffff) {
+ if ((y = *xb & 0xffff)) {
x = xa;
xc = xc0;
carry = 0;
@@ -657,7 +657,7 @@ mult
while(x < xae);
*xc = carry;
}
- if (y = *xb >> 16) {
+ if ((y = *xb >> 16)) {
x = xa;
xc = xc0;
carry = 0;
@@ -794,9 +794,9 @@ diff
#endif
{
int i, wa, wb;
- long borrow, y; /* We need signed shifts here. */
+ _G_int32_t borrow, y; /* We need signed shifts here. */
unsigned32 *xa, *xae, *xb, *xbe, *xc;
- long z;
+ _G_int32_t z;
i = cmp(a,b);
if (!i) {
@@ -856,7 +856,7 @@ ulp
(double x)
#endif
{
- register long L;
+ register _G_int32_t L;
double a;
L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
@@ -879,7 +879,7 @@ ulp
else {
word0(a) = 0;
L -= Exp_shift;
- word1(a) = L >= 31 ? 1 : 1 << 31 - L;
+ word1(a) = L >= 31 ? 1 : 1 << (31 - L);
}
}
#endif
@@ -913,16 +913,16 @@ b2d
k = hi0bits(y);
*e = 32 - k;
if (k < Ebits) {
- d0 = Exp_1 | y >> Ebits - k;
+ d0 = Exp_1 | y >> (Ebits - k);
w = xa > xa0 ? *--xa : 0;
- d1 = y << (32-Ebits) + k | w >> Ebits - k;
+ d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
goto ret_d;
}
z = xa > xa0 ? *--xa : 0;
if (k -= Ebits) {
- d0 = Exp_1 | y << k | z >> 32 - k;
+ d0 = Exp_1 | y << k | z >> (32 - k);
y = xa > xa0 ? *--xa : 0;
- d1 = z << k | y >> 32 - k;
+ d1 = z << k | y >> (32 - k);
}
else {
d0 = Exp_1 | y;
@@ -974,9 +974,9 @@ d2b
z |= Exp_msk11;
#endif
- if (y = d1) {
- if (k = lo0bits(&y)) {
- x[0] = y | z << 32 - k;
+ if ((y = d1)) {
+ if ((k = lo0bits(&y))) {
+ x[0] = y | z << (32 - k);
z >>= k;
}
else
@@ -1091,7 +1091,7 @@ _IO_strtod
e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
CONST char *s, *s0, *s1;
double aadj, aadj1, adj, rv, rv0;
- long L;
+ _G_int32_t L;
unsigned32 y, z;
Bigint _bb, _b_avail, _bd, _bd0, _bs, _delta;
Bigint *bb = Binit(&_bb);
@@ -1280,7 +1280,7 @@ _IO_strtod
/* Get starting approximation = rv * 10**e1 */
if (e1 > 0) {
- if (i = e1 & 15)
+ if ((i = e1 & 15))
rv *= tens[i];
if (e1 &= ~15) {
if (e1 > DBL_MAX_10_EXP) {
@@ -1320,7 +1320,7 @@ _IO_strtod
}
else if (e1 < 0) {
e1 = -e1;
- if (i = e1 & 15)
+ if ((i = e1 & 15))
rv /= tens[i];
if (e1 &= ~15) {
e1 >>= 4;
@@ -1588,7 +1588,7 @@ _IO_strtod
z = word0(rv) & Exp_mask;
if (y == z) {
/* Can we stop now? */
- L = (long)aadj;
+ L = (_G_int32_t)aadj;
aadj -= L;
/* The tolerances below are conservative. */
if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
@@ -1620,10 +1620,10 @@ quorem
#endif
{
int n;
- long borrow, y;
+ _G_int32_t borrow, y;
unsigned32 carry, q, ys;
unsigned32 *bx, *bxe, *sx, *sxe;
- long z;
+ _G_int32_t z;
unsigned32 si, zs;
n = S->wds;
@@ -1777,7 +1777,7 @@ _IO_dtoa
int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
spec_case, try_quick;
- long L;
+ _G_int32_t L;
#ifndef Sudden_Underflow
int denorm;
#endif
@@ -1874,8 +1874,8 @@ _IO_dtoa
unsigned32 x;
i = bbits + be + (Bias + (P-1) - 1);
- x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
- : word1(d) << 32 - i;
+ x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
+ : word1(d) << (32 - i);
d2 = x;
word0(d2) -= 31*Exp_msk1; /* adjust exponent */
i -= (Bias + (P-1) - 1) + 1;
@@ -2006,7 +2006,7 @@ _IO_dtoa
}
d /= ds;
}
- else if (j1 = -k) {
+ else if ((j1 = -k)) {
d *= tens[j1 & 0xf];
for(j = j1 >> 4; j; j >>= 1, i++)
if (j & 1) {
@@ -2039,7 +2039,7 @@ _IO_dtoa
*/
eps = 0.5/tens[ilim-1] - eps;
for(i = 0;;) {
- L = (long)d;
+ L = (_G_int32_t)d;
d -= L;
*s++ = '0' + (int)L;
if (d < eps)
@@ -2057,7 +2057,7 @@ _IO_dtoa
/* Generate ilim digits, then fix them up. */
eps *= tens[ilim-1];
for(i = 1;; i++, d *= 10.) {
- L = (long)d;
+ L = (_G_int32_t)d;
d -= L;
*s++ = '0' + (int)L;
if (i == ilim) {
@@ -2092,7 +2092,7 @@ _IO_dtoa
goto one_digit;
}
for(i = 1;; i++) {
- L = (long)(d / ds);
+ L = (_G_int32_t)(d / ds);
d -= L*ds;
#ifdef Check_FLT_ROUNDS
/* If FLT_ROUNDS == 2, L will usually be high by 1 */
@@ -2104,7 +2104,7 @@ _IO_dtoa
*s++ = '0' + (int)L;
if (i == ilim) {
d += d;
- if (d > ds || d == ds && L & 1) {
+ if (d > ds || (d == ds && L & 1)) {
bump_up:
while(*--s == '9')
if (s == s0) {
@@ -2169,7 +2169,7 @@ _IO_dtoa
b_avail = b;
b = b_tmp;
}
- if (j = b5 - m5)
+ if ((j = b5 - m5))
b = pow5mult(b, j);
}
else
@@ -2203,7 +2203,7 @@ _IO_dtoa
* and for all and pass them and a shift to quorem, so it
* can do shifts and ors to compute the numerator for q.
*/
- if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f))
i = 32 - i;
if (i > 4) {
i -= 4;
@@ -2276,15 +2276,15 @@ _IO_dtoa
goto ret;
}
#endif
- if (j < 0 || j == 0 && !mode
+ if (j < 0 || (j == 0 && !mode
#ifndef ROUND_BIASED
&& !(word1(d) & 1)
#endif
- ) {
+ )) {
if (j1 > 0) {
b = lshift(b, 1);
j1 = cmp(b, S);
- if ((j1 > 0 || j1 == 0 && dig & 1)
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
&& dig++ == '9')
goto round_9_up;
}
@@ -2324,7 +2324,7 @@ _IO_dtoa
b = lshift(b, 1);
j = cmp(b, S);
- if (j > 0 || j == 0 && dig & 1) {
+ if (j > 0 || (j == 0 && dig & 1)) {
roundoff:
while(*--s == '9')
if (s == s0) {
@@ -2354,4 +2354,4 @@ _IO_dtoa
*rve = s;
return s0;
}
-#endif /* USE_DTOA */
+#endif /* _IO_USE_DTOA */
diff --git a/gnu/lib/libg++/libio/ioassign.cc b/gnu/lib/libg++/libio/ioassign.cc
new file mode 100644
index 000000000000..5441ae79b393
--- /dev/null
+++ b/gnu/lib/libg++/libio/ioassign.cc
@@ -0,0 +1,55 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#include <iostream.h>
+#include "libioP.h"
+
+// These method are provided for backward compatibility reasons.
+// It's generally poor style to use them.
+// They are not supported by the ANSI/ISO working paper.
+
+_IO_istream_withassign& _IO_istream_withassign::operator=(istream& rhs)
+{
+ if (&rhs != (istream*)this)
+ {
+ if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf();
+ init (rhs.rdbuf ());
+ _flags |= ios::dont_close;
+ _gcount = 0;
+ }
+ return *this;
+}
+
+_IO_ostream_withassign& _IO_ostream_withassign::operator=(ostream& rhs)
+{
+ if (&rhs != (ostream*)this)
+ {
+ if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf();
+ init (rhs.rdbuf ());
+ _flags |= ios::dont_close;
+ }
+ return *this;
+}
diff --git a/gnu/lib/libg++/libio/iofclose.c b/gnu/lib/libg++/libio/iofclose.c
index 44664d92fb58..03be4518b4db 100644
--- a/gnu/lib/libg++/libio/iofclose.c
+++ b/gnu/lib/libg++/libio/iofclose.c
@@ -32,9 +32,7 @@ _IO_fclose(fp)
register _IO_FILE *fp;
{
int status = 0;
- COERCE_FILE(fp);
- if ((fp->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC)
- return EOF;
+ CHECK_FILE(fp, EOF);
if (fp->_IO_file_flags & _IO_IS_FILEBUF)
status = _IO_file_close_it(fp);
fp->_jumps->__finish(fp);
diff --git a/gnu/lib/libg++/libio/iofgetpos.c b/gnu/lib/libg++/libio/iofgetpos.c
index 16ecec04c598..ac417f5dbc1c 100644
--- a/gnu/lib/libg++/libio/iofgetpos.c
+++ b/gnu/lib/libg++/libio/iofgetpos.c
@@ -32,7 +32,7 @@ _IO_fgetpos(fp, posp)
_IO_fpos_t *posp;
{
_IO_fpos_t pos;
- COERCE_FILE(fp);
+ CHECK_FILE(fp, EOF);
pos = _IO_seekoff(fp, 0, _IO_seek_cur|_IO_seek_not_in|_IO_seek_not_out);
if (pos == _IO_pos_BAD)
{
diff --git a/gnu/lib/libg++/libio/iofread.c b/gnu/lib/libg++/libio/iofread.c
index c72c70fbc552..4bfe717c029d 100644
--- a/gnu/lib/libg++/libio/iofread.c
+++ b/gnu/lib/libg++/libio/iofread.c
@@ -33,7 +33,7 @@ _IO_fread(buf, size, count, fp)
{
_IO_size_t bytes_requested = size*count;
_IO_size_t bytes_read;
- COERCE_FILE(fp);
+ CHECK_FILE(fp, 0);
if (bytes_requested == 0)
return 0;
bytes_read = _IO_sgetn(fp, (char *)buf, bytes_requested);
diff --git a/gnu/lib/libg++/libio/iofscanf.c b/gnu/lib/libg++/libio/iofscanf.c
index 7110401b786e..5daef91741aa 100644
--- a/gnu/lib/libg++/libio/iofscanf.c
+++ b/gnu/lib/libg++/libio/iofscanf.c
@@ -40,7 +40,7 @@ _IO_fscanf
{
int ret;
va_list args;
- COERCE_FILE(fp);
+ CHECK_FILE(fp, EOF);
_IO_va_start(args, format);
ret = _IO_vfscanf(fp, format, args, NULL);
va_end(args);
diff --git a/gnu/lib/libg++/libio/iofsetpos.c b/gnu/lib/libg++/libio/iofsetpos.c
index 763fbe69fdaf..0a6fff2f02f2 100644
--- a/gnu/lib/libg++/libio/iofsetpos.c
+++ b/gnu/lib/libg++/libio/iofsetpos.c
@@ -30,7 +30,7 @@ _IO_fsetpos(fp, posp)
_IO_FILE* fp;
const _IO_fpos_t *posp;
{
- COERCE_FILE(fp);
+ CHECK_FILE(fp, EOF);
if (_IO_seekpos(fp, *posp, 0) == _IO_pos_BAD)
{
/*ANSI explicily requires setting errno to a positive value on failure.*/
diff --git a/gnu/lib/libg++/libio/iogetdelim.c b/gnu/lib/libg++/libio/iogetdelim.c
new file mode 100644
index 000000000000..3dc5cd1ca77b
--- /dev/null
+++ b/gnu/lib/libg++/libio/iogetdelim.c
@@ -0,0 +1,102 @@
+/*
+Copyright (C) 1994 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include "libioP.h"
+#include <string.h>
+#include <errno.h>
+
+/* Read up to (and including) a TERMINATOR from FP into *LINEPTR
+ (and null-terminate it). *LINEPTR is a pointer returned from malloc (or
+ NULL), pointing to *N characters of space. It is realloc'ed as
+ necessary. Returns the number of characters read (not including the
+ null terminator), or -1 on error or EOF. */
+
+_IO_ssize_t
+_IO_getdelim (lineptr, n, delimiter, fp)
+ char **lineptr;
+ _IO_size_t *n;
+ int delimiter;
+ _IO_FILE *fp;
+{
+ register _IO_ssize_t cur_len = 0;
+ _IO_ssize_t len;
+
+ if (lineptr == NULL || n == NULL)
+ {
+#ifdef EINVAL
+ errno = EINVAL;
+#endif
+ return -1;
+ }
+ CHECK_FILE (fp, -1);
+ if (_IO_ferror (fp))
+ return -1;
+
+ if (*lineptr == NULL || *n == 0)
+ {
+ *n = 120;
+ *lineptr = (char *) malloc (*n);
+ if (*lineptr == NULL)
+ return -1;
+ }
+
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ if (len <= 0)
+ {
+ if (__underflow (fp) == EOF)
+ return -1;
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ }
+
+ for (;;)
+ {
+ _IO_size_t needed;
+ char *t;
+ t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len);
+ if (t != NULL)
+ len = (t - fp->_IO_read_ptr) + 1;
+ /* make enough space for len+1 (for final NUL) bytes. */
+ needed = cur_len + len + 1;
+ if (needed > *n)
+ {
+ if (t == NULL && needed < 2 * *n)
+ needed = 2 * *n; /* Be generous. */
+ *n = needed;
+ *lineptr = (char *) realloc (*lineptr, needed);
+ if (*lineptr == NULL)
+ return -1;
+ }
+ memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len);
+ fp->_IO_read_ptr += len;
+ cur_len += len;
+ if (t != NULL || __underflow (fp) == EOF)
+ break;
+ len = fp->_IO_read_end - fp->_IO_read_ptr;
+ }
+ lineptr[cur_len] = '\0';
+ return cur_len;
+}
diff --git a/gnu/lib/libg++/libio/iostream.cc b/gnu/lib/libg++/libio/iostream.cc
index db953d488169..0c241f81c0ea 100644
--- a/gnu/lib/libg++/libio/iostream.cc
+++ b/gnu/lib/libg++/libio/iostream.cc
@@ -70,6 +70,8 @@ istream& istream::get(char& c)
_gcount = 1;
}
}
+ else
+ _gcount = 0;
return *this;
}
@@ -87,13 +89,13 @@ int istream::peek()
istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
{
+ _gcount = 0;
if (ipfx1()) {
register streambuf* sb = _strbuf;
if (delim == EOF) {
_gcount = sb->ignore(n);
return *this;
}
- _gcount = 0;
for (;;) {
#if 0
if (n != MAXINT) // FIXME
@@ -120,6 +122,8 @@ istream& istream::read(char *s, int n)
if (_gcount != n)
set(ios::failbit|ios::eofbit);
}
+ else
+ _gcount = 0;
return *this;
}
@@ -307,6 +311,13 @@ READ_INT(unsigned long long)
READ_INT(bool)
#endif
+istream& istream::operator>>(long double& x)
+{
+ if (ipfx0())
+ scan("%lg", &x);
+ return *this;
+}
+
istream& istream::operator>>(double& x)
{
if (ipfx0())
@@ -552,7 +563,7 @@ ostream& ostream::operator<<(double n)
prec = 6; /* default */
// Do actual conversion.
-#ifdef USE_DTOA
+#ifdef _IO_USE_DTOA
if (_IO_outfloat(n, rdbuf(), format_char, width(0),
prec, flags(),
flags() & ios::showpos ? '+' : 0,
@@ -710,7 +721,7 @@ streampos ostream::tellp()
ostream& ostream::flush()
{
- if (_strbuf->_jumps->__sync(_strbuf))
+ if (_strbuf->sync())
set(ios::badbit);
return *this;
}
diff --git a/gnu/lib/libg++/libio/ioungetc.c b/gnu/lib/libg++/libio/ioungetc.c
index 7b983edcd54a..b52e4a27e92f 100644
--- a/gnu/lib/libg++/libio/ioungetc.c
+++ b/gnu/lib/libg++/libio/ioungetc.c
@@ -29,7 +29,7 @@ _IO_ungetc(c, fp)
int c;
_IO_FILE *fp;
{
- COERCE_FILE(fp);
+ CHECK_FILE(fp, EOF);
if (c == EOF)
return EOF;
return _IO_sputbackc(fp, (unsigned char)c);
diff --git a/gnu/lib/libg++/libio/iovfprintf.c b/gnu/lib/libg++/libio/iovfprintf.c
index feda569f6fb9..e3fb2da0c1fe 100644
--- a/gnu/lib/libg++/libio/iovfprintf.c
+++ b/gnu/lib/libg++/libio/iovfprintf.c
@@ -196,7 +196,7 @@ _IO_vfprintf(fp, fmt0, ap)
#ifdef FLOATING_POINT
int softsign; /* temporary negative sign for floats */
double _double; /* double precision arguments %[eEfgG] */
-#ifndef USE_DTOA
+#ifndef _IO_USE_DTOA
int fpprec; /* `extra' floating precision in [eEfgG] */
#endif
#endif
@@ -256,7 +256,7 @@ _IO_vfprintf(fp, fmt0, ap)
flags = 0;
dprec = 0;
-#if defined(FLOATING_POINT) && !defined (USE_DTOA)
+#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)
fpprec = 0;
#endif
width = 0;
@@ -362,7 +362,7 @@ reswitch: switch (ch) {
case 'g':
case 'G':
_double = va_arg(ap, double);
-#ifdef USE_DTOA
+#ifdef _IO_USE_DTOA
{
int fmt_flags = 0;
int fill = ' ';
@@ -564,7 +564,7 @@ number: if ((dprec = prec) >= 0)
/*
* compute actual size, so we know how much to pad.
*/
-#if defined(FLOATING_POINT) && !defined (USE_DTOA)
+#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)
fieldsz = size + fpprec;
#else
fieldsz = size;
@@ -602,7 +602,7 @@ number: if ((dprec = prec) >= 0)
/* the string or number proper */
PRINT(cp, size);
-#if defined(FLOATING_POINT) && !defined (USE_DTOA)
+#if defined(FLOATING_POINT) && !defined (_IO_USE_DTOA)
/* trailing f.p. zeroes */
PAD_0(fpprec);
#endif
@@ -622,7 +622,7 @@ error:
/* NOTREACHED */
}
-#if defined(FLOATING_POINT) && !defined(USE_DTOA)
+#if defined(FLOATING_POINT) && !defined(_IO_USE_DTOA)
static char *exponent(register char *p, register int exp, int fmtch)
{
@@ -882,4 +882,4 @@ eformat: if (expcnt) {
return (t - startp);
}
-#endif /* defined(FLOATING_POINT) && !defined(USE_DTOA) */
+#endif /* defined(FLOATING_POINT) && !defined(_IO_USE_DTOA) */
diff --git a/gnu/lib/libg++/libio/iovfscanf.c b/gnu/lib/libg++/libio/iovfscanf.c
index abf1e586195b..85168afdbd78 100644
--- a/gnu/lib/libg++/libio/iovfscanf.c
+++ b/gnu/lib/libg++/libio/iovfscanf.c
@@ -105,7 +105,7 @@ static char sccsid[] = "%W% (Berkeley) %G%";
extern u_long strtoul __P((const char*, char**, int));
extern long strtol __P((const char*, char**, int));
static const u_char *__sccl __P((char *tab, const u_char *fmt));
-#ifndef USE_DTOA
+#ifndef _IO_USE_DTOA
extern double atof();
#endif
@@ -655,7 +655,7 @@ literal:
if ((flags & SUPPRESS) == 0) {
double res;
*p = 0;
-#ifdef USE_DTOA
+#ifdef _IO_USE_DTOA
res = _IO_strtod(buf, NULL);
#else
res = atof(buf);
diff --git a/gnu/lib/libg++/libio/stdiostream.cc b/gnu/lib/libg++/libio/stdiostream.cc
index eb3dd16eb735..f6de524424a6 100644
--- a/gnu/lib/libg++/libio/stdiostream.cc
+++ b/gnu/lib/libg++/libio/stdiostream.cc
@@ -68,6 +68,19 @@ stdiobuf::~stdiobuf()
streamsize stdiobuf::sys_read(char* buf, streamsize size)
{
+ // A minor optimization, but it makes a noticable difference.
+ // A bigger optimization would be to write stdiobuf::underflow,
+ // but that has some modularity disadvantages. Re-evaluate that
+ // after we have gotten rid of the double indirection. FIXME
+ if (size == 1)
+ {
+ register ch = getc(_file);
+ if (ch == EOF)
+ return 0;
+ *buf = (char)ch;
+ return 1;
+ }
+ else
return fread(buf, 1, size, _file);
}
diff --git a/gnu/lib/libg++/libio/strstream.cc b/gnu/lib/libg++/libio/strstream.cc
index c17d6837dfef..e5917f0941a7 100644
--- a/gnu/lib/libg++/libio/strstream.cc
+++ b/gnu/lib/libg++/libio/strstream.cc
@@ -76,7 +76,7 @@ char *strstreambuf::str()
return base();
}
-_IO_ssize_t strstreambuf::pcount() { return _IO_str_count (this); }
+_IO_ssize_t strstreambuf::pcount () { return _IO_write_ptr - _IO_write_base; }
int strstreambuf::overflow(int c /* = EOF */)
{
diff --git a/gnu/lib/libg++/librx/rx.c b/gnu/lib/libg++/librx/rx.c
new file mode 100644
index 000000000000..8671edec3d59
--- /dev/null
+++ b/gnu/lib/libg++/librx/rx.c
@@ -0,0 +1,7159 @@
+/* Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of the librx library.
+
+Librx is free software; you can redistribute it and/or modify it under
+the terms of the GNU Library General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+Librx 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 Library General Public
+License along with this software; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA
+02139, USA. */
+
+/* NOTE!!! AIX is so losing it requires this to be the first thing in the
+ * file.
+ * Do not put ANYTHING before it!
+ */
+#if !defined (__GNUC__) && defined (_AIX)
+ #pragma alloca
+#endif
+
+char rx_version_string[] = "GNU Rx version 0.06";
+
+ /* ``Too hard!''
+ * -- anon.
+ */
+
+
+#include <stdio.h>
+#include <ctype.h>
+#ifndef isgraph
+#define isgraph(c) (isprint (c) && !isspace (c))
+#endif
+#ifndef isblank
+#define isblank(c) ((c) == ' ' || (c) == '\t')
+#endif
+
+#include <sys/types.h>
+
+#undef MAX
+#undef MIN
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+typedef char boolean;
+#define false 0
+#define true 1
+
+#ifndef RX_DECL
+#define RX_DECL static
+#endif
+
+#ifndef __GCC__
+#undef __inline__
+#define __inline__
+#endif
+
+/* Emacs already defines alloca, sometimes. */
+#ifndef alloca
+
+/* Make alloca work the best possible way. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* not __GNUC__ or HAVE_ALLOCA_H */
+#ifndef _AIX /* Already did AIX, up at the top. */
+char *alloca ();
+#endif /* not _AIX */
+#endif /* not HAVE_ALLOCA_H */
+#endif /* not __GNUC__ */
+
+#endif /* not alloca */
+
+/* Memory management and stuff for emacs. */
+
+#define CHARBITS 8
+#define remalloc(M, S) (M ? realloc (M, S) : malloc (S))
+
+
+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
+ * use `alloca' instead of `malloc' for the backtracking stack.
+ *
+ * Emacs will die miserably if we don't do this.
+ */
+
+#ifdef REGEX_MALLOC
+#define REGEX_ALLOCATE malloc
+#else /* not REGEX_MALLOC */
+#define REGEX_ALLOCATE alloca
+#endif /* not REGEX_MALLOC */
+
+#ifdef RX_WANT_RX_DEFS
+#define RX_DECL extern
+#define RX_DEF_QUAL
+#else
+#define RX_WANT_RX_DEFS
+#define RX_DECL static
+#define RX_DEF_QUAL static
+#endif
+#include "rx.h"
+#undef RX_DECL
+#define RX_DECL RX_DEF_QUAL
+
+
+#ifndef emacs
+
+#ifdef SYNTAX_TABLE
+extern char *re_syntax_table;
+#else /* not SYNTAX_TABLE */
+
+/* RX_DECL char re_syntax_table[CHAR_SET_SIZE]; */
+
+#ifdef __STDC__
+static void
+init_syntax_once (void)
+#else
+static void
+init_syntax_once ()
+#endif
+{
+ register int c;
+ static int done = 0;
+
+ if (done)
+ return;
+
+ bzero (re_syntax_table, sizeof re_syntax_table);
+
+ for (c = 'a'; c <= 'z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = 'A'; c <= 'Z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = '0'; c <= '9'; c++)
+ re_syntax_table[c] = Sword;
+
+ re_syntax_table['_'] = Sword;
+
+ done = 1;
+}
+#endif /* not SYNTAX_TABLE */
+#endif /* not emacs */
+
+/* Compile with `-DRX_DEBUG' and use the following flags.
+ *
+ * Debugging flags:
+ * rx_debug - print information as a regexp is compiled
+ * rx_debug_trace - print information as a regexp is executed
+ */
+
+#ifdef RX_DEBUG
+
+int rx_debug_compile = 0;
+int rx_debug_trace = 0;
+static struct re_pattern_buffer * dbug_rxb = 0;
+
+#ifdef __STDC__
+typedef void (*side_effect_printer) (struct rx *, void *, FILE *);
+#else
+typedef void (*side_effect_printer) ();
+#endif
+
+#ifdef __STDC__
+static void print_cset (struct rx *rx, rx_Bitset cset, FILE * fp);
+#else
+static void print_cset ();
+#endif
+
+#ifdef __STDC__
+static void
+print_rexp (struct rx *rx,
+ struct rexp_node *node, int depth,
+ side_effect_printer seprint, FILE * fp)
+#else
+static void
+print_rexp (rx, node, depth, seprint, fp)
+ struct rx *rx;
+ struct rexp_node *node;
+ int depth;
+ side_effect_printer seprint;
+ FILE * fp;
+#endif
+{
+ if (!node)
+ return;
+ else
+ {
+ switch (node->type)
+ {
+ case r_cset:
+ {
+ fprintf (fp, "%*s", depth, "");
+ print_cset (rx, node->params.cset, fp);
+ fputc ('\n', fp);
+ break;
+ }
+
+ case r_opt:
+ case r_star:
+ fprintf (fp, "%*s%s\n", depth, "",
+ node->type == r_opt ? "opt" : "star");
+ print_rexp (rx, node->params.pair.left, depth + 3, seprint, fp);
+ break;
+
+ case r_2phase_star:
+ fprintf (fp, "%*s2phase star\n", depth, "");
+ print_rexp (rx, node->params.pair.right, depth + 3, seprint, fp);
+ print_rexp (rx, node->params.pair.left, depth + 3, seprint, fp);
+ break;
+
+
+ case r_alternate:
+ case r_concat:
+ fprintf (fp, "%*s%s\n", depth, "",
+ node->type == r_alternate ? "alt" : "concat");
+ print_rexp (rx, node->params.pair.left, depth + 3, seprint, fp);
+ print_rexp (rx, node->params.pair.right, depth + 3, seprint, fp);
+ break;
+ case r_side_effect:
+ fprintf (fp, "%*sSide effect: ", depth, "");
+ seprint (rx, node->params.side_effect, fp);
+ fputc ('\n', fp);
+ }
+ }
+}
+
+#ifdef __STDC__
+static void
+print_nfa (struct rx * rx,
+ struct rx_nfa_state * n,
+ side_effect_printer seprint, FILE * fp)
+#else
+static void
+print_nfa (rx, n, seprint, fp)
+ struct rx * rx;
+ struct rx_nfa_state * n;
+ side_effect_printer seprint;
+ FILE * fp;
+#endif
+{
+ while (n)
+ {
+ struct rx_nfa_edge *e = n->edges;
+ struct rx_possible_future *ec = n->futures;
+ fprintf (fp, "node %d %s\n", n->id,
+ n->is_final ? "final" : (n->is_start ? "start" : ""));
+ while (e)
+ {
+ fprintf (fp, " edge to %d, ", e->dest->id);
+ switch (e->type)
+ {
+ case ne_epsilon:
+ fprintf (fp, "epsilon\n");
+ break;
+ case ne_side_effect:
+ fprintf (fp, "side effect ");
+ seprint (rx, e->params.side_effect, fp);
+ fputc ('\n', fp);
+ break;
+ case ne_cset:
+ fprintf (fp, "cset ");
+ print_cset (rx, e->params.cset, fp);
+ fputc ('\n', fp);
+ break;
+ }
+ e = e->next;
+ }
+
+ while (ec)
+ {
+ int x;
+ struct rx_nfa_state_set * s;
+ struct rx_se_list * l;
+ fprintf (fp, " eclosure to {");
+ for (s = ec->destset; s; s = s->cdr)
+ fprintf (fp, "%d ", s->car->id);
+ fprintf (fp, "} (");
+ for (l = ec->effects; l; l = l->cdr)
+ {
+ seprint (rx, l->car, fp);
+ fputc (' ', fp);
+ }
+ fprintf (fp, ")\n");
+ ec = ec->next;
+ }
+ n = n->next;
+ }
+}
+
+static char * efnames [] =
+{
+ "bogon",
+ "re_se_try",
+ "re_se_pushback",
+ "re_se_push0",
+ "re_se_pushpos",
+ "re_se_chkpos",
+ "re_se_poppos",
+ "re_se_at_dot",
+ "re_se_syntax",
+ "re_se_not_syntax",
+ "re_se_begbuf",
+ "re_se_hat",
+ "re_se_wordbeg",
+ "re_se_wordbound",
+ "re_se_notwordbound",
+ "re_se_wordend",
+ "re_se_endbuf",
+ "re_se_dollar",
+ "re_se_fail",
+};
+
+static char * efnames2[] =
+{
+ "re_se_win"
+ "re_se_lparen",
+ "re_se_rparen",
+ "re_se_backref",
+ "re_se_iter",
+ "re_se_end_iter",
+ "re_se_tv"
+};
+
+static char * inx_names[] =
+{
+ "rx_backtrack_point",
+ "rx_do_side_effects",
+ "rx_cache_miss",
+ "rx_next_char",
+ "rx_backtrack",
+ "rx_error_inx",
+ "rx_num_instructions"
+};
+
+
+#ifdef __STDC__
+static void
+re_seprint (struct rx * rx, void * effect, FILE * fp)
+#else
+static void
+re_seprint (rx, effect, fp)
+ struct rx * rx;
+ void * effect;
+ FILE * fp;
+#endif
+{
+ if ((int)effect < 0)
+ fputs (efnames[-(int)effect], fp);
+ else if (dbug_rxb)
+ {
+ struct re_se_params * p = &dbug_rxb->se_params[(int)effect];
+ fprintf (fp, "%s(%d,%d)", efnames2[p->se], p->op1, p->op2);
+ }
+ else
+ fprintf (fp, "[complex op # %d]", (int)effect);
+}
+
+
+/* These are so the regex.c regression tests will compile. */
+void
+print_compiled_pattern (rxb)
+ struct re_pattern_buffer * rxb;
+{
+}
+
+void
+print_fastmap (fm)
+ char * fm;
+{
+}
+
+#endif /* RX_DEBUG */
+
+
+
+/* This page: Bitsets. Completely unintersting. */
+
+#ifdef __STDC__
+RX_DECL int
+rx_bitset_is_equal (int size, rx_Bitset a, rx_Bitset b)
+#else
+RX_DECL int
+rx_bitset_is_equal (size, a, b)
+ int size;
+ rx_Bitset a;
+ rx_Bitset b;
+#endif
+{
+ int x;
+ RX_subset s = b[0];
+ b[0] = ~a[0];
+
+ for (x = rx_bitset_numb_subsets(size) - 1; a[x] == b[x]; --x)
+ ;
+
+ b[0] = s;
+ return !x && s == a[0];
+}
+
+#ifdef __STDC__
+RX_DECL int
+rx_bitset_is_subset (int size, rx_Bitset a, rx_Bitset b)
+#else
+RX_DECL int
+rx_bitset_is_subset (size, a, b)
+ int size;
+ rx_Bitset a;
+ rx_Bitset b;
+#endif
+{
+ int x = rx_bitset_numb_subsets(size) - 1;
+ while (x-- && (a[x] & b[x]) == a[x]);
+ return x == -1;
+}
+
+
+#ifdef __STDC__
+RX_DECL int
+rx_bitset_empty (int size, rx_Bitset set)
+#else
+RX_DECL int
+rx_bitset_empty (size, set)
+ int size;
+ rx_Bitset set;
+#endif
+{
+ int x;
+ RX_subset s = set[0];
+ set[0] = 1;
+ for (x = rx_bitset_numb_subsets(size) - 1; !set[x]; --x)
+ ;
+ set[0] = s;
+ return !s;
+}
+
+#ifdef __STDC__
+RX_DECL void
+rx_bitset_null (int size, rx_Bitset b)
+#else
+RX_DECL void
+rx_bitset_null (size, b)
+ int size;
+ rx_Bitset b;
+#endif
+{
+ bzero (b, rx_sizeof_bitset(size));
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_bitset_universe (int size, rx_Bitset b)
+#else
+RX_DECL void
+rx_bitset_universe (size, b)
+ int size;
+ rx_Bitset b;
+#endif
+{
+ int x = rx_bitset_numb_subsets (size);
+ while (x--)
+ *b++ = ~(RX_subset)0;
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_bitset_complement (int size, rx_Bitset b)
+#else
+RX_DECL void
+rx_bitset_complement (size, b)
+ int size;
+ rx_Bitset b;
+#endif
+{
+ int x = rx_bitset_numb_subsets (size);
+ while (x--)
+ {
+ *b = ~*b;
+ ++b;
+ }
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_bitset_assign (int size, rx_Bitset a, rx_Bitset b)
+#else
+RX_DECL void
+rx_bitset_assign (size, a, b)
+ int size;
+ rx_Bitset a;
+ rx_Bitset b;
+#endif
+{
+ int x;
+ for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
+ a[x] = b[x];
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_bitset_union (int size, rx_Bitset a, rx_Bitset b)
+#else
+RX_DECL void
+rx_bitset_union (size, a, b)
+ int size;
+ rx_Bitset a;
+ rx_Bitset b;
+#endif
+{
+ int x;
+ for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
+ a[x] |= b[x];
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_bitset_intersection (int size,
+ rx_Bitset a, rx_Bitset b)
+#else
+RX_DECL void
+rx_bitset_intersection (size, a, b)
+ int size;
+ rx_Bitset a;
+ rx_Bitset b;
+#endif
+{
+ int x;
+ for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
+ a[x] &= b[x];
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_bitset_difference (int size, rx_Bitset a, rx_Bitset b)
+#else
+RX_DECL void
+rx_bitset_difference (size, a, b)
+ int size;
+ rx_Bitset a;
+ rx_Bitset b;
+#endif
+{
+ int x;
+ for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
+ a[x] &= ~ b[x];
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_bitset_revdifference (int size,
+ rx_Bitset a, rx_Bitset b)
+#else
+RX_DECL void
+rx_bitset_revdifference (size, a, b)
+ int size;
+ rx_Bitset a;
+ rx_Bitset b;
+#endif
+{
+ int x;
+ for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
+ a[x] = ~a[x] & b[x];
+}
+
+#ifdef __STDC__
+RX_DECL void
+rx_bitset_xor (int size, rx_Bitset a, rx_Bitset b)
+#else
+RX_DECL void
+rx_bitset_xor (size, a, b)
+ int size;
+ rx_Bitset a;
+ rx_Bitset b;
+#endif
+{
+ int x;
+ for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x)
+ a[x] ^= b[x];
+}
+
+
+#ifdef __STDC__
+RX_DECL unsigned long
+rx_bitset_hash (int size, rx_Bitset b)
+#else
+RX_DECL unsigned long
+rx_bitset_hash (size, b)
+ int size;
+ rx_Bitset b;
+#endif
+{
+ int x;
+ unsigned long hash = (unsigned long)rx_bitset_hash;
+
+ for (x = rx_bitset_numb_subsets(size) - 1; x >= 0; --x)
+ hash ^= rx_bitset_subset_val(b, x);
+
+ return hash;
+}
+
+
+RX_DECL RX_subset rx_subset_singletons [RX_subset_bits] =
+{
+ 0x1,
+ 0x2,
+ 0x4,
+ 0x8,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x100,
+ 0x200,
+ 0x400,
+ 0x800,
+ 0x1000,
+ 0x2000,
+ 0x4000,
+ 0x8000,
+ 0x10000,
+ 0x20000,
+ 0x40000,
+ 0x80000,
+ 0x100000,
+ 0x200000,
+ 0x400000,
+ 0x800000,
+ 0x1000000,
+ 0x2000000,
+ 0x4000000,
+ 0x8000000,
+ 0x10000000,
+ 0x20000000,
+ 0x40000000,
+ 0x80000000
+};
+
+#ifdef RX_DEBUG
+
+#ifdef __STDC__
+static void
+print_cset (struct rx *rx, rx_Bitset cset, FILE * fp)
+#else
+static void
+print_cset (rx, cset, fp)
+ struct rx *rx;
+ rx_Bitset cset;
+ FILE * fp;
+#endif
+{
+ int x;
+ fputc ('[', fp);
+ for (x = 0; x < rx->local_cset_size; ++x)
+ if (isprint(x) && RX_bitset_member (cset, x))
+ fputc (x, fp);
+ fputc (']', fp);
+}
+
+#endif /* RX_DEBUG */
+
+
+
+static unsigned long rx_hash_masks[4] =
+{
+ 0x12488421,
+ 0x96699669,
+ 0xbe7dd7eb,
+ 0xffffffff
+};
+
+
+/* Hash tables */
+#ifdef __STDC__
+RX_DECL struct rx_hash_item *
+rx_hash_find (struct rx_hash * table,
+ unsigned long hash,
+ void * value,
+ struct rx_hash_rules * rules)
+#else
+RX_DECL struct rx_hash_item *
+rx_hash_find (table, hash, value, rules)
+ struct rx_hash * table;
+ unsigned long hash;
+ void * value;
+ struct rx_hash_rules * rules;
+#endif
+{
+ rx_hash_eq eq = rules->eq;
+ int maskc = 0;
+ long mask = rx_hash_masks [0];
+ int bucket = (hash & mask) % 13;
+
+ while (table->children [bucket])
+ {
+ table = table->children [bucket];
+ ++maskc;
+ mask = rx_hash_masks[maskc];
+ bucket = (hash & mask) % 13;
+ }
+
+ {
+ struct rx_hash_item * it = table->buckets[bucket];
+ while (it)
+ if (eq (it->data, value))
+ return it;
+ else
+ it = it->next_same_hash;
+ }
+
+ return 0;
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rx_hash_item *
+rx_hash_store (struct rx_hash * table,
+ unsigned long hash,
+ void * value,
+ struct rx_hash_rules * rules)
+#else
+RX_DECL struct rx_hash_item *
+rx_hash_store (table, hash, value, rules)
+ struct rx_hash * table;
+ unsigned long hash;
+ void * value;
+ struct rx_hash_rules * rules;
+#endif
+{
+ rx_hash_eq eq = rules->eq;
+ int maskc = 0;
+ long mask = rx_hash_masks[0];
+ int bucket = (hash & mask) % 13;
+ int depth = 0;
+
+ while (table->children [bucket])
+ {
+ table = table->children [bucket];
+ ++maskc;
+ mask = rx_hash_masks[maskc];
+ bucket = (hash & mask) % 13;
+ ++depth;
+ }
+
+ {
+ struct rx_hash_item * it = table->buckets[bucket];
+ while (it)
+ if (eq (it->data, value))
+ return it;
+ else
+ it = it->next_same_hash;
+ }
+
+ {
+ if ( (depth < 3)
+ && (table->bucket_size [bucket] >= 4))
+ {
+ struct rx_hash * newtab = ((struct rx_hash *)
+ rules->hash_alloc (rules));
+ if (!newtab)
+ goto add_to_bucket;
+ bzero (newtab, sizeof (*newtab));
+ newtab->parent = table;
+ {
+ struct rx_hash_item * them = table->buckets[bucket];
+ unsigned long newmask = rx_hash_masks[maskc + 1];
+ while (them)
+ {
+ struct rx_hash_item * save = them->next_same_hash;
+ int new_buck = (them->hash & newmask) % 13;
+ them->next_same_hash = newtab->buckets[new_buck];
+ newtab->buckets[new_buck] = them;
+ them->table = newtab;
+ them = save;
+ ++newtab->bucket_size[new_buck];
+ ++newtab->refs;
+ }
+ table->refs = (table->refs - table->bucket_size[bucket] + 1);
+ table->bucket_size[bucket] = 0;
+ table->buckets[bucket] = 0;
+ table->children[bucket] = newtab;
+ table = newtab;
+ bucket = (hash & newmask) % 13;
+ }
+ }
+ }
+ add_to_bucket:
+ {
+ struct rx_hash_item * it = ((struct rx_hash_item *)
+ rules->hash_item_alloc (rules, value));
+ if (!it)
+ return 0;
+ it->hash = hash;
+ it->table = table;
+ /* DATA and BINDING are to be set in hash_item_alloc */
+ it->next_same_hash = table->buckets [bucket];
+ table->buckets[bucket] = it;
+ ++table->bucket_size [bucket];
+ ++table->refs;
+ return it;
+ }
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_hash_free (struct rx_hash_item * it, struct rx_hash_rules * rules)
+#else
+RX_DECL void
+rx_hash_free (it, rules)
+ struct rx_hash_item * it;
+ struct rx_hash_rules * rules;
+#endif
+{
+ if (it)
+ {
+ struct rx_hash * table = it->table;
+ unsigned long hash = it->hash;
+ int depth = (table->parent
+ ? (table->parent->parent
+ ? (table->parent->parent->parent
+ ? 3
+ : 2)
+ : 1)
+ : 0);
+ int bucket = (hash & rx_hash_masks [depth]) % 13;
+ struct rx_hash_item ** pos = &table->buckets [bucket];
+
+ while (*pos != it)
+ pos = &(*pos)->next_same_hash;
+ *pos = it->next_same_hash;
+ rules->free_hash_item (it, rules);
+ --table->bucket_size[bucket];
+ --table->refs;
+ while (!table->refs && depth)
+ {
+ struct rx_hash * save = table;
+ table = table->parent;
+ --depth;
+ bucket = (hash & rx_hash_masks [depth]) % 13;
+ --table->refs;
+ table->children[bucket] = 0;
+ rules->free_hash (save, rules);
+ }
+ }
+}
+
+#ifdef __STDC__
+RX_DECL void
+rx_free_hash_table (struct rx_hash * tab, rx_hash_freefn freefn,
+ struct rx_hash_rules * rules)
+#else
+RX_DECL void
+rx_free_hash_table (tab, freefn, rules)
+ struct rx_hash * tab;
+ rx_hash_freefn freefn;
+ struct rx_hash_rules * rules;
+#endif
+{
+ int x;
+
+ for (x = 0; x < 13; ++x)
+ if (tab->children[x])
+ {
+ rx_free_hash_table (tab->children[x], freefn, rules);
+ rules->free_hash (tab->children[x], rules);
+ }
+ else
+ {
+ struct rx_hash_item * them = tab->buckets[x];
+ while (them)
+ {
+ struct rx_hash_item * that = them;
+ them = that->next_same_hash;
+ freefn (that);
+ rules->free_hash_item (that, rules);
+ }
+ }
+}
+
+
+
+/* Utilities for manipulating bitset represntations of characters sets. */
+
+#ifdef __STDC__
+RX_DECL rx_Bitset
+rx_cset (struct rx *rx)
+#else
+RX_DECL rx_Bitset
+rx_cset (rx)
+ struct rx *rx;
+#endif
+{
+ rx_Bitset b = (rx_Bitset) malloc (rx_sizeof_bitset (rx->local_cset_size));
+ if (b)
+ rx_bitset_null (rx->local_cset_size, b);
+ return b;
+}
+
+
+#ifdef __STDC__
+RX_DECL rx_Bitset
+rx_copy_cset (struct rx *rx, rx_Bitset a)
+#else
+RX_DECL rx_Bitset
+rx_copy_cset (rx, a)
+ struct rx *rx;
+ rx_Bitset a;
+#endif
+{
+ rx_Bitset cs = rx_cset (rx);
+
+ if (cs)
+ rx_bitset_union (rx->local_cset_size, cs, a);
+
+ return cs;
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_free_cset (struct rx * rx, rx_Bitset c)
+#else
+RX_DECL void
+rx_free_cset (rx, c)
+ struct rx * rx;
+ rx_Bitset c;
+#endif
+{
+ if (c)
+ free ((char *)c);
+}
+
+
+/* Hash table memory allocation policy for the regexp compiler */
+
+#ifdef __STDC__
+static struct rx_hash *
+compiler_hash_alloc (struct rx_hash_rules * rules)
+#else
+static struct rx_hash *
+compiler_hash_alloc (rules)
+ struct rx_hash_rules * rules;
+#endif
+{
+ return (struct rx_hash *)malloc (sizeof (struct rx_hash));
+}
+
+
+#ifdef __STDC__
+static struct rx_hash_item *
+compiler_hash_item_alloc (struct rx_hash_rules * rules, void * value)
+#else
+static struct rx_hash_item *
+compiler_hash_item_alloc (rules, value)
+ struct rx_hash_rules * rules;
+ void * value;
+#endif
+{
+ struct rx_hash_item * it;
+ it = (struct rx_hash_item *)malloc (sizeof (*it));
+ if (it)
+ {
+ it->data = value;
+ it->binding = 0;
+ }
+ return it;
+}
+
+
+#ifdef __STDC__
+static void
+compiler_free_hash (struct rx_hash * tab,
+ struct rx_hash_rules * rules)
+#else
+static void
+compiler_free_hash (tab, rules)
+ struct rx_hash * tab;
+ struct rx_hash_rules * rules;
+#endif
+{
+ free ((char *)tab);
+}
+
+
+#ifdef __STDC__
+static void
+compiler_free_hash_item (struct rx_hash_item * item,
+ struct rx_hash_rules * rules)
+#else
+static void
+compiler_free_hash_item (item, rules)
+ struct rx_hash_item * item;
+ struct rx_hash_rules * rules;
+#endif
+{
+ free ((char *)item);
+}
+
+
+/* This page: REXP_NODE (expression tree) structures. */
+
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rexp_node (struct rx *rx,
+ enum rexp_node_type type)
+#else
+RX_DECL struct rexp_node *
+rexp_node (rx, type)
+ struct rx *rx;
+ enum rexp_node_type type;
+#endif
+{
+ struct rexp_node *n;
+
+ n = (struct rexp_node *)malloc (sizeof (*n));
+ bzero (n, sizeof (*n));
+ if (n)
+ n->type = type;
+ return n;
+}
+
+
+/* free_rexp_node assumes that the bitset passed to rx_mk_r_cset
+ * can be freed using rx_free_cset.
+ */
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rx_mk_r_cset (struct rx * rx,
+ rx_Bitset b)
+#else
+RX_DECL struct rexp_node *
+rx_mk_r_cset (rx, b)
+ struct rx * rx;
+ rx_Bitset b;
+#endif
+{
+ struct rexp_node * n = rexp_node (rx, r_cset);
+ if (n)
+ n->params.cset = b;
+ return n;
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rx_mk_r_concat (struct rx * rx,
+ struct rexp_node * a,
+ struct rexp_node * b)
+#else
+RX_DECL struct rexp_node *
+rx_mk_r_concat (rx, a, b)
+ struct rx * rx;
+ struct rexp_node * a;
+ struct rexp_node * b;
+#endif
+{
+ struct rexp_node * n = rexp_node (rx, r_concat);
+ if (n)
+ {
+ n->params.pair.left = a;
+ n->params.pair.right = b;
+ }
+ return n;
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rx_mk_r_alternate (struct rx * rx,
+ struct rexp_node * a,
+ struct rexp_node * b)
+#else
+RX_DECL struct rexp_node *
+rx_mk_r_alternate (rx, a, b)
+ struct rx * rx;
+ struct rexp_node * a;
+ struct rexp_node * b;
+#endif
+{
+ struct rexp_node * n = rexp_node (rx, r_alternate);
+ if (n)
+ {
+ n->params.pair.left = a;
+ n->params.pair.right = b;
+ }
+ return n;
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rx_mk_r_opt (struct rx * rx,
+ struct rexp_node * a)
+#else
+RX_DECL struct rexp_node *
+rx_mk_r_opt (rx, a)
+ struct rx * rx;
+ struct rexp_node * a;
+#endif
+{
+ struct rexp_node * n = rexp_node (rx, r_opt);
+ if (n)
+ {
+ n->params.pair.left = a;
+ n->params.pair.right = 0;
+ }
+ return n;
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rx_mk_r_star (struct rx * rx,
+ struct rexp_node * a)
+#else
+RX_DECL struct rexp_node *
+rx_mk_r_star (rx, a)
+ struct rx * rx;
+ struct rexp_node * a;
+#endif
+{
+ struct rexp_node * n = rexp_node (rx, r_star);
+ if (n)
+ {
+ n->params.pair.left = a;
+ n->params.pair.right = 0;
+ }
+ return n;
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rx_mk_r_2phase_star (struct rx * rx,
+ struct rexp_node * a,
+ struct rexp_node * b)
+#else
+RX_DECL struct rexp_node *
+rx_mk_r_2phase_star (rx, a, b)
+ struct rx * rx;
+ struct rexp_node * a;
+ struct rexp_node * b;
+#endif
+{
+ struct rexp_node * n = rexp_node (rx, r_2phase_star);
+ if (n)
+ {
+ n->params.pair.left = a;
+ n->params.pair.right = b;
+ }
+ return n;
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rx_mk_r_side_effect (struct rx * rx,
+ rx_side_effect a)
+#else
+RX_DECL struct rexp_node *
+rx_mk_r_side_effect (rx, a)
+ struct rx * rx;
+ rx_side_effect a;
+#endif
+{
+ struct rexp_node * n = rexp_node (rx, r_side_effect);
+ if (n)
+ {
+ n->params.side_effect = a;
+ n->params.pair.right = 0;
+ }
+ return n;
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rx_mk_r_data (struct rx * rx,
+ void * a)
+#else
+RX_DECL struct rexp_node *
+rx_mk_r_data (rx, a)
+ struct rx * rx;
+ void * a;
+#endif
+{
+ struct rexp_node * n = rexp_node (rx, r_data);
+ if (n)
+ {
+ n->params.pair.left = a;
+ n->params.pair.right = 0;
+ }
+ return n;
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_free_rexp (struct rx * rx, struct rexp_node * node)
+#else
+RX_DECL void
+rx_free_rexp (rx, node)
+ struct rx * rx;
+ struct rexp_node * node;
+#endif
+{
+ if (node)
+ {
+ switch (node->type)
+ {
+ case r_cset:
+ if (node->params.cset)
+ rx_free_cset (rx, node->params.cset);
+
+ case r_side_effect:
+ break;
+
+ case r_concat:
+ case r_alternate:
+ case r_2phase_star:
+ case r_opt:
+ case r_star:
+ rx_free_rexp (rx, node->params.pair.left);
+ rx_free_rexp (rx, node->params.pair.right);
+ break;
+
+ case r_data:
+ /* This shouldn't occur. */
+ break;
+ }
+ free ((char *)node);
+ }
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rexp_node *
+rx_copy_rexp (struct rx *rx,
+ struct rexp_node *node)
+#else
+RX_DECL struct rexp_node *
+rx_copy_rexp (rx, node)
+ struct rx *rx;
+ struct rexp_node *node;
+#endif
+{
+ if (!node)
+ return 0;
+ else
+ {
+ struct rexp_node *n = rexp_node (rx, node->type);
+ if (!n)
+ return 0;
+ switch (node->type)
+ {
+ case r_cset:
+ n->params.cset = rx_copy_cset (rx, node->params.cset);
+ if (!n->params.cset)
+ {
+ rx_free_rexp (rx, n);
+ return 0;
+ }
+ break;
+
+ case r_side_effect:
+ n->params.side_effect = node->params.side_effect;
+ break;
+
+ case r_concat:
+ case r_alternate:
+ case r_opt:
+ case r_2phase_star:
+ case r_star:
+ n->params.pair.left =
+ rx_copy_rexp (rx, node->params.pair.left);
+ n->params.pair.right =
+ rx_copy_rexp (rx, node->params.pair.right);
+ if ( (node->params.pair.left && !n->params.pair.left)
+ || (node->params.pair.right && !n->params.pair.right))
+ {
+ rx_free_rexp (rx, n);
+ return 0;
+ }
+ break;
+ case r_data:
+ /* shouldn't happen */
+ break;
+ }
+ return n;
+ }
+}
+
+
+
+/* This page: functions to build and destroy graphs that describe nfa's */
+
+/* Constructs a new nfa node. */
+#ifdef __STDC__
+RX_DECL struct rx_nfa_state *
+rx_nfa_state (struct rx *rx)
+#else
+RX_DECL struct rx_nfa_state *
+rx_nfa_state (rx)
+ struct rx *rx;
+#endif
+{
+ struct rx_nfa_state * n = (struct rx_nfa_state *)malloc (sizeof (*n));
+ if (!n)
+ return 0;
+ bzero (n, sizeof (*n));
+ n->next = rx->nfa_states;
+ rx->nfa_states = n;
+ return n;
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_free_nfa_state (struct rx_nfa_state * n)
+#else
+RX_DECL void
+rx_free_nfa_state (n)
+ struct rx_nfa_state * n;
+#endif
+{
+ free ((char *)n);
+}
+
+
+/* This looks up an nfa node, given a numeric id. Numeric id's are
+ * assigned after the nfa has been built.
+ */
+#ifdef __STDC__
+RX_DECL struct rx_nfa_state *
+rx_id_to_nfa_state (struct rx * rx,
+ int id)
+#else
+RX_DECL struct rx_nfa_state *
+rx_id_to_nfa_state (rx, id)
+ struct rx * rx;
+ int id;
+#endif
+{
+ struct rx_nfa_state * n;
+ for (n = rx->nfa_states; n; n = n->next)
+ if (n->id == id)
+ return n;
+ return 0;
+}
+
+
+/* This adds an edge between two nodes, but doesn't initialize the
+ * edge label.
+ */
+
+#ifdef __STDC__
+RX_DECL struct rx_nfa_edge *
+rx_nfa_edge (struct rx *rx,
+ enum rx_nfa_etype type,
+ struct rx_nfa_state *start,
+ struct rx_nfa_state *dest)
+#else
+RX_DECL struct rx_nfa_edge *
+rx_nfa_edge (rx, type, start, dest)
+ struct rx *rx;
+ enum rx_nfa_etype type;
+ struct rx_nfa_state *start;
+ struct rx_nfa_state *dest;
+#endif
+{
+ struct rx_nfa_edge *e;
+ e = (struct rx_nfa_edge *)malloc (sizeof (*e));
+ if (!e)
+ return 0;
+ e->next = start->edges;
+ start->edges = e;
+ e->type = type;
+ e->dest = dest;
+ return e;
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_free_nfa_edge (struct rx_nfa_edge * e)
+#else
+RX_DECL void
+rx_free_nfa_edge (e)
+ struct rx_nfa_edge * e;
+#endif
+{
+ free ((char *)e);
+}
+
+
+/* This constructs a POSSIBLE_FUTURE, which is a kind epsilon-closure
+ * of an NFA. These are added to an nfa automaticly by eclose_nfa.
+ */
+
+#ifdef __STDC__
+static struct rx_possible_future *
+rx_possible_future (struct rx * rx,
+ struct rx_se_list * effects)
+#else
+static struct rx_possible_future *
+rx_possible_future (rx, effects)
+ struct rx * rx;
+ struct rx_se_list * effects;
+#endif
+{
+ struct rx_possible_future *ec;
+ ec = (struct rx_possible_future *) malloc (sizeof (*ec));
+ if (!ec)
+ return 0;
+ ec->destset = 0;
+ ec->next = 0;
+ ec->effects = effects;
+ return ec;
+}
+
+
+#ifdef __STDC__
+static void
+rx_free_possible_future (struct rx_possible_future * pf)
+#else
+static void
+rx_free_possible_future (pf)
+ struct rx_possible_future * pf;
+#endif
+{
+ free ((char *)pf);
+}
+
+
+#ifdef __STDC__
+RX_DECL void
+rx_free_nfa (struct rx *rx)
+#else
+RX_DECL void
+rx_free_nfa (rx)
+ struct rx *rx;
+#endif
+{
+ while (rx->nfa_states)
+ {
+ while (rx->nfa_states->edges)
+ {
+ switch (rx->nfa_states->edges->type)
+ {
+ case ne_cset:
+ rx_free_cset (rx, rx->nfa_states->edges->params.cset);
+ break;
+ default:
+ break;
+ }
+ {
+ struct rx_nfa_edge * e;
+ e = rx->nfa_states->edges;
+ rx->nfa_states->edges = rx->nfa_states->edges->next;
+ rx_free_nfa_edge (e);
+ }
+ } /* while (rx->nfa_states->edges) */
+ {
+ /* Iterate over the partial epsilon closures of rx->nfa_states */
+ struct rx_possible_future * pf = rx->nfa_states->futures;
+ while (pf)
+ {
+ struct rx_possible_future * pft = pf;
+ pf = pf->next;
+ rx_free_possible_future (pft);
+ }
+ }
+ {
+ struct rx_nfa_state *n;
+ n = rx->nfa_states;
+ rx->nfa_states = rx->nfa_states->next;
+ rx_free_nfa_state (n);
+ }
+ }
+}
+
+
+
+/* This page: translating a pattern expression into an nfa and doing the
+ * static part of the nfa->super-nfa translation.
+ */
+
+/* This is the thompson regexp->nfa algorithm.
+ * It is modified to allow for `side-effect epsilons.' Those are
+ * edges that are taken whenever a similar epsilon edge would be,
+ * but which imply that some side effect occurs when the edge
+ * is taken.
+ *
+ * Side effects are used to model parts of the pattern langauge
+ * that are not regular (in the formal sense).
+ */
+
+#ifdef __STDC__
+RX_DECL int
+rx_build_nfa (struct rx *rx,
+ struct rexp_node *rexp,
+ struct rx_nfa_state **start,
+ struct rx_nfa_state **end)
+#else
+RX_DECL int
+rx_build_nfa (rx, rexp, start, end)
+ struct rx *rx;
+ struct rexp_node *rexp;
+ struct rx_nfa_state **start;
+ struct rx_nfa_state **end;
+#endif
+{
+ struct rx_nfa_edge *edge;
+
+ /* Start & end nodes may have been allocated by the caller. */
+ *start = *start ? *start : rx_nfa_state (rx);
+
+ if (!*start)
+ return 0;
+
+ if (!rexp)
+ {
+ *end = *start;
+ return 1;
+ }
+
+ *end = *end ? *end : rx_nfa_state (rx);
+
+ if (!*end)
+ {
+ rx_free_nfa_state (*start);
+ return 0;
+ }
+
+ switch (rexp->type)
+ {
+ case r_data:
+ return 0;
+
+ case r_cset:
+ edge = rx_nfa_edge (rx, ne_cset, *start, *end);
+ if (!edge)
+ return 0;
+ edge->params.cset = rx_copy_cset (rx, rexp->params.cset);
+ if (!edge->params.cset)
+ {
+ rx_free_nfa_edge (edge);
+ return 0;
+ }
+ return 1;
+
+ case r_opt:
+ return (rx_build_nfa (rx, rexp->params.pair.left, start, end)
+ && rx_nfa_edge (rx, ne_epsilon, *start, *end));
+
+ case r_star:
+ {
+ struct rx_nfa_state * star_start = 0;
+ struct rx_nfa_state * star_end = 0;
+ return (rx_build_nfa (rx, rexp->params.pair.left,
+ &star_start, &star_end)
+ && star_start
+ && star_end
+ && rx_nfa_edge (rx, ne_epsilon, star_start, star_end)
+ && rx_nfa_edge (rx, ne_epsilon, *start, star_start)
+ && rx_nfa_edge (rx, ne_epsilon, star_end, *end)
+
+ && rx_nfa_edge (rx, ne_epsilon, star_end, star_start));
+ }
+
+ case r_2phase_star:
+ {
+ struct rx_nfa_state * star_start = 0;
+ struct rx_nfa_state * star_end = 0;
+ struct rx_nfa_state * loop_exp_start = 0;
+ struct rx_nfa_state * loop_exp_end = 0;
+
+ return (rx_build_nfa (rx, rexp->params.pair.left,
+ &star_start, &star_end)
+ && rx_build_nfa (rx, rexp->params.pair.right,
+ &loop_exp_start, &loop_exp_end)
+ && star_start
+ && star_end
+ && loop_exp_end
+ && loop_exp_start
+ && rx_nfa_edge (rx, ne_epsilon, star_start, *end)
+ && rx_nfa_edge (rx, ne_epsilon, *start, star_start)
+ && rx_nfa_edge (rx, ne_epsilon, star_end, *end)
+
+ && rx_nfa_edge (rx, ne_epsilon, star_end, loop_exp_start)
+ && rx_nfa_edge (rx, ne_epsilon, loop_exp_end, star_start));
+ }
+
+
+ case r_concat:
+ {
+ struct rx_nfa_state *shared = 0;
+ return
+ (rx_build_nfa (rx, rexp->params.pair.left, start, &shared)
+ && rx_build_nfa (rx, rexp->params.pair.right, &shared, end));
+ }
+
+ case r_alternate:
+ {
+ struct rx_nfa_state *ls = 0;
+ struct rx_nfa_state *le = 0;
+ struct rx_nfa_state *rs = 0;
+ struct rx_nfa_state *re = 0;
+ return (rx_build_nfa (rx, rexp->params.pair.left, &ls, &le)
+ && rx_build_nfa (rx, rexp->params.pair.right, &rs, &re)
+ && rx_nfa_edge (rx, ne_epsilon, *start, ls)
+ && rx_nfa_edge (rx, ne_epsilon, *start, rs)
+ && rx_nfa_edge (rx, ne_epsilon, le, *end)
+ && rx_nfa_edge (rx, ne_epsilon, re, *end));
+ }
+
+ case r_side_effect:
+ edge = rx_nfa_edge (rx, ne_side_effect, *start, *end);
+ if (!edge)
+ return 0;
+ edge->params.side_effect = rexp->params.side_effect;
+ return 1;
+ }
+
+ /* this should never happen */
+ return 0;
+}
+
+
+/* RX_NAME_NFA_STATES identifies all nodes with outgoing non-epsilon
+ * transitions. Only these nodes can occur in super-states.
+ * All nodes are given an integer id.
+ * The id is non-negative if the node has non-epsilon out-transitions, negative
+ * otherwise (this is because we want the non-negative ids to be used as
+ * array indexes in a few places).
+ */
+
+#ifdef __STDC__
+RX_DECL void
+rx_name_nfa_states (struct rx *rx)
+#else
+RX_DECL void
+rx_name_nfa_states (rx)
+ struct rx *rx;
+#endif
+{
+ struct rx_nfa_state *n = rx->nfa_states;
+
+ rx->nodec = 0;
+ rx->epsnodec = -1;
+
+ while (n)
+ {
+ struct rx_nfa_edge *e = n->edges;
+
+ if (n->is_start)
+ n->eclosure_needed = 1;
+
+ while (e)
+ {
+ switch (e->type)
+ {
+ case ne_epsilon:
+ case ne_side_effect:
+ break;
+
+ case ne_cset:
+ n->id = rx->nodec++;
+ {
+ struct rx_nfa_edge *from_n = n->edges;
+ while (from_n)
+ {
+ from_n->dest->eclosure_needed = 1;
+ from_n = from_n->next;
+ }
+ }
+ goto cont;
+ }
+ e = e->next;
+ }
+ n->id = rx->epsnodec--;
+ cont:
+ n = n->next;
+ }
+ rx->epsnodec = -rx->epsnodec;
+}
+
+
+/* This page: data structures for the static part of the nfa->supernfa
+ * translation.
+ *
+ * There are side effect lists -- lists of side effects occuring
+ * along an uninterrupted, acyclic path of side-effect epsilon edges.
+ * Such paths are collapsed to single edges in the course of computing
+ * epsilon closures. Such single edges are labled with a list of all
+ * the side effects entailed in crossing them. Like lists of side
+ * effects are made == by the constructors below.
+ *
+ * There are also nfa state sets. These are used to hold a list of all
+ * states reachable from a starting state for a given type of transition
+ * and side effect list. These are also hash-consed.
+ */
+
+/* The next several functions compare, construct, etc. lists of side
+ * effects. See ECLOSE_NFA (below) for details.
+ */
+
+/* Ordering of rx_se_list
+ * (-1, 0, 1 return value convention).
+ */
+
+#ifdef __STDC__
+static int
+se_list_cmp (void * va, void * vb)
+#else
+static int
+se_list_cmp (va, vb)
+ void * va;
+ void * vb;
+#endif
+{
+ struct rx_se_list * a = (struct rx_se_list *)va;
+ struct rx_se_list * b = (struct rx_se_list *)vb;
+
+ return ((va == vb)
+ ? 0
+ : (!va
+ ? -1
+ : (!vb
+ ? 1
+ : ((long)a->car < (long)b->car
+ ? 1
+ : ((long)a->car > (long)b->car
+ ? -1
+ : se_list_cmp ((void *)a->cdr, (void *)b->cdr))))));
+}
+
+
+#ifdef __STDC__
+static int
+se_list_equal (void * va, void * vb)
+#else
+static int
+se_list_equal (va, vb)
+ void * va;
+ void * vb;
+#endif
+{
+ return !(se_list_cmp (va, vb));
+}
+
+static struct rx_hash_rules se_list_hash_rules =
+{
+ se_list_equal,
+ compiler_hash_alloc,
+ compiler_free_hash,
+ compiler_hash_item_alloc,
+ compiler_free_hash_item
+};
+
+
+#ifdef __STDC__
+static struct rx_se_list *
+side_effect_cons (struct rx * rx,
+ void * se, struct rx_se_list * list)
+#else
+static struct rx_se_list *
+side_effect_cons (rx, se, list)
+ struct rx * rx;
+ void * se;
+ struct rx_se_list * list;
+#endif
+{
+ struct rx_se_list * l;
+ l = ((struct rx_se_list *) malloc (sizeof (*l)));
+ if (!l)
+ return 0;
+ l->car = se;
+ l->cdr = list;
+ return l;
+}
+
+
+#ifdef __STDC__
+static struct rx_se_list *
+hash_cons_se_prog (struct rx * rx,
+ struct rx_hash * memo,
+ void * car, struct rx_se_list * cdr)
+#else
+static struct rx_se_list *
+hash_cons_se_prog (rx, memo, car, cdr)
+ struct rx * rx;
+ struct rx_hash * memo;
+ void * car;
+ struct rx_se_list * cdr;
+#endif
+{
+ long hash = (long)car ^ (long)cdr;
+ struct rx_se_list template;
+
+ template.car = car;
+ template.cdr = cdr;
+ {
+ struct rx_hash_item * it = rx_hash_store (memo, hash,
+ (void *)&template,
+ &se_list_hash_rules);
+ if (!it)
+ return 0;
+ if (it->data == (void *)&template)
+ {
+ struct rx_se_list * consed;
+ consed = (struct rx_se_list *) malloc (sizeof (*consed));
+ *consed = template;
+ it->data = (void *)consed;
+ }
+ return (struct rx_se_list *)it->data;
+ }
+}
+
+
+#ifdef __STDC__
+static struct rx_se_list *
+hash_se_prog (struct rx * rx, struct rx_hash * memo, struct rx_se_list * prog)
+#else
+static struct rx_se_list *
+hash_se_prog (rx, memo, prog)
+ struct rx * rx;
+ struct rx_hash * memo;
+ struct rx_se_list * prog;
+#endif
+{
+ struct rx_se_list * answer = 0;
+ while (prog)
+ {
+ answer = hash_cons_se_prog (rx, memo, prog->car, answer);
+ if (!answer)
+ return 0;
+ prog = prog->cdr;
+ }
+ return answer;
+}
+
+#ifdef __STDC__
+static int
+nfa_set_cmp (void * va, void * vb)
+#else
+static int
+nfa_set_cmp (va, vb)
+ void * va;
+ void * vb;
+#endif
+{
+ struct rx_nfa_state_set * a = (struct rx_nfa_state_set *)va;
+ struct rx_nfa_state_set * b = (struct rx_nfa_state_set *)vb;
+
+ return ((va == vb)
+ ? 0
+ : (!va
+ ? -1
+ : (!vb
+ ? 1
+ : (a->car->id < b->car->id
+ ? 1
+ : (a->car->id > b->car->id
+ ? -1
+ : nfa_set_cmp ((void *)a->cdr, (void *)b->cdr))))));
+}
+
+#ifdef __STDC__
+static int
+nfa_set_equal (void * va, void * vb)
+#else
+static int
+nfa_set_equal (va, vb)
+ void * va;
+ void * vb;
+#endif
+{
+ return !nfa_set_cmp (va, vb);
+}
+
+static struct rx_hash_rules nfa_set_hash_rules =
+{
+ nfa_set_equal,
+ compiler_hash_alloc,
+ compiler_free_hash,
+ compiler_hash_item_alloc,
+ compiler_free_hash_item
+};
+
+
+#ifdef __STDC__
+static struct rx_nfa_state_set *
+nfa_set_cons (struct rx * rx,
+ struct rx_hash * memo, struct rx_nfa_state * state,
+ struct rx_nfa_state_set * set)
+#else
+static struct rx_nfa_state_set *
+nfa_set_cons (rx, memo, state, set)
+ struct rx * rx;
+ struct rx_hash * memo;
+ struct rx_nfa_state * state;
+ struct rx_nfa_state_set * set;
+#endif
+{
+ struct rx_nfa_state_set template;
+ struct rx_hash_item * node;
+ template.car = state;
+ template.cdr = set;
+ node = rx_hash_store (memo,
+ (((long)state) >> 8) ^ (long)set,
+ &template, &nfa_set_hash_rules);
+ if (!node)
+ return 0;
+ if (node->data == &template)
+ {
+ struct rx_nfa_state_set * l;
+ l = (struct rx_nfa_state_set *) malloc (sizeof (*l));
+ node->data = (void *) l;
+ if (!l)
+ return 0;
+ *l = template;
+ }
+ return (struct rx_nfa_state_set *)node->data;
+}
+
+
+#ifdef __STDC__
+static struct rx_nfa_state_set *
+nfa_set_enjoin (struct rx * rx,
+ struct rx_hash * memo, struct rx_nfa_state * state,
+ struct rx_nfa_state_set * set)
+#else
+static struct rx_nfa_state_set *
+nfa_set_enjoin (rx, memo, state, set)
+ struct rx * rx;
+ struct rx_hash * memo;
+ struct rx_nfa_state * state;
+ struct rx_nfa_state_set * set;
+#endif
+{
+ if (!set || state->id < set->car->id)
+ return nfa_set_cons (rx, memo, state, set);
+ if (state->id == set->car->id)
+ return set;
+ else
+ {
+ struct rx_nfa_state_set * newcdr
+ = nfa_set_enjoin (rx, memo, state, set->cdr);
+ if (newcdr != set->cdr)
+ set = nfa_set_cons (rx, memo, set->car, newcdr);
+ return set;
+ }
+}
+
+
+
+/* This page: computing epsilon closures. The closures aren't total.
+ * Each node's closures are partitioned according to the side effects entailed
+ * along the epsilon edges. Return true on success.
+ */
+
+struct eclose_frame
+{
+ struct rx_se_list *prog_backwards;
+};
+
+
+#ifdef __STDC__
+static int
+eclose_node (struct rx *rx, struct rx_nfa_state *outnode,
+ struct rx_nfa_state *node, struct eclose_frame *frame)
+#else
+static int
+eclose_node (rx, outnode, node, frame)
+ struct rx *rx;
+ struct rx_nfa_state *outnode;
+ struct rx_nfa_state *node;
+ struct eclose_frame *frame;
+#endif
+{
+ struct rx_nfa_edge *e = node->edges;
+
+ /* For each node, we follow all epsilon paths to build the closure.
+ * The closure omits nodes that have only epsilon edges.
+ * The closure is split into partial closures -- all the states in
+ * a partial closure are reached by crossing the same list of
+ * of side effects (though not necessarily the same path).
+ */
+ if (node->mark)
+ return 1;
+ node->mark = 1;
+
+ if (node->id >= 0 || node->is_final)
+ {
+ struct rx_possible_future **ec;
+ struct rx_se_list * prog_in_order
+ = ((struct rx_se_list *)hash_se_prog (rx,
+ &rx->se_list_memo,
+ frame->prog_backwards));
+ int cmp;
+
+ ec = &outnode->futures;
+
+ while (*ec)
+ {
+ cmp = se_list_cmp ((void *)(*ec)->effects, (void *)prog_in_order);
+ if (cmp <= 0)
+ break;
+ ec = &(*ec)->next;
+ }
+ if (!*ec || (cmp < 0))
+ {
+ struct rx_possible_future * saved = *ec;
+ *ec = rx_possible_future (rx, prog_in_order);
+ (*ec)->next = saved;
+ if (!*ec)
+ return 0;
+ }
+ if (node->id >= 0)
+ {
+ (*ec)->destset = nfa_set_enjoin (rx, &rx->set_list_memo,
+ node, (*ec)->destset);
+ if (!(*ec)->destset)
+ return 0;
+ }
+ }
+
+ while (e)
+ {
+ switch (e->type)
+ {
+ case ne_epsilon:
+ if (!eclose_node (rx, outnode, e->dest, frame))
+ return 0;
+ break;
+ case ne_side_effect:
+ {
+ frame->prog_backwards = side_effect_cons (rx,
+ e->params.side_effect,
+ frame->prog_backwards);
+ if (!frame->prog_backwards)
+ return 0;
+ if (!eclose_node (rx, outnode, e->dest, frame))
+ return 0;
+ {
+ struct rx_se_list * dying = frame->prog_backwards;
+ frame->prog_backwards = frame->prog_backwards->cdr;
+ free ((char *)dying);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ e = e->next;
+ }
+ node->mark = 0;
+ return 1;
+}
+
+
+#ifdef __STDC__
+RX_DECL int
+rx_eclose_nfa (struct rx *rx)
+#else
+RX_DECL int
+rx_eclose_nfa (rx)
+ struct rx *rx;
+#endif
+{
+ struct rx_nfa_state *n = rx->nfa_states;
+ struct eclose_frame frame;
+ static int rx_id = 0;
+
+ frame.prog_backwards = 0;
+ rx->rx_id = rx_id++;
+ bzero (&rx->se_list_memo, sizeof (rx->se_list_memo));
+ bzero (&rx->set_list_memo, sizeof (rx->set_list_memo));
+ while (n)
+ {
+ n->futures = 0;
+ if (n->eclosure_needed && !eclose_node (rx, n, n, &frame))
+ return 0;
+ /* clear_marks (rx); */
+ n = n->next;
+ }
+ return 1;
+}
+
+
+/* This deletes epsilon edges from an NFA. After running eclose_node,
+ * we have no more need for these edges. They are removed to simplify
+ * further operations on the NFA.
+ */
+
+#ifdef __STDC__
+RX_DECL void
+rx_delete_epsilon_transitions (struct rx *rx)
+#else
+RX_DECL void
+rx_delete_epsilon_transitions (rx)
+ struct rx *rx;
+#endif
+{
+ struct rx_nfa_state *n = rx->nfa_states;
+ struct rx_nfa_edge **e;
+
+ while (n)
+ {
+ e = &n->edges;
+ while (*e)
+ {
+ struct rx_nfa_edge *t;
+ switch ((*e)->type)
+ {
+ case ne_epsilon:
+ case ne_side_effect:
+ t = *e;
+ *e = t->next;
+ rx_free_nfa_edge (t);
+ break;
+
+ default:
+ e = &(*e)->next;
+ break;
+ }
+ }
+ n = n->next;
+ }
+}
+
+
+/* This page: storing the nfa in a contiguous region of memory for
+ * subsequent conversion to a super-nfa.
+ */
+
+/* This is for qsort on an array of nfa_states. The order
+ * is based on state ids and goes
+ * [0...MAX][MIN..-1] where (MAX>=0) and (MIN<0)
+ * This way, positive ids double as array indices.
+ */
+
+#ifdef __STDC__
+static int
+nfacmp (void * va, void * vb)
+#else
+static int
+nfacmp (va, vb)
+ void * va;
+ void * vb;
+#endif
+{
+ struct rx_nfa_state **a = (struct rx_nfa_state **)va;
+ struct rx_nfa_state **b = (struct rx_nfa_state **)vb;
+ return (*a == *b /* &&&& 3.18 */
+ ? 0
+ : (((*a)->id < 0) == ((*b)->id < 0)
+ ? (((*a)->id < (*b)->id) ? -1 : 1)
+ : (((*a)->id < 0)
+ ? 1 : -1)));
+}
+
+#ifdef __STDC__
+static int
+count_hash_nodes (struct rx_hash * st)
+#else
+static int
+count_hash_nodes (st)
+ struct rx_hash * st;
+#endif
+{
+ int x;
+ int count = 0;
+ for (x = 0; x < 13; ++x)
+ count += ((st->children[x])
+ ? count_hash_nodes (st->children[x])
+ : st->bucket_size[x]);
+
+ return count;
+}
+
+
+#ifdef __STDC__
+static void
+se_memo_freer (struct rx_hash_item * node)
+#else
+static void
+se_memo_freer (node)
+ struct rx_hash_item * node;
+#endif
+{
+ free ((char *)node->data);
+}
+
+
+#ifdef __STDC__
+static void
+nfa_set_freer (struct rx_hash_item * node)
+#else
+static void
+nfa_set_freer (node)
+ struct rx_hash_item * node;
+#endif
+{
+ free ((char *)node->data);
+}
+
+
+/* This copies an entire NFA into a single malloced block of memory.
+ * Mostly this is for compatability with regex.c, though it is convenient
+ * to have the nfa nodes in an array.
+ */
+
+#ifdef __STDC__
+RX_DECL int
+rx_compactify_nfa (struct rx *rx,
+ void **mem, unsigned long *size)
+#else
+RX_DECL int
+rx_compactify_nfa (rx, mem, size)
+ struct rx *rx;
+ void **mem;
+ unsigned long *size;
+#endif
+{
+ int total_nodec;
+ struct rx_nfa_state *n;
+ int edgec = 0;
+ int eclosec = 0;
+ int se_list_consc = count_hash_nodes (&rx->se_list_memo);
+ int nfa_setc = count_hash_nodes (&rx->set_list_memo);
+ unsigned long total_size;
+
+ /* This takes place in two stages. First, the total size of the
+ * nfa is computed, then structures are copied.
+ */
+ n = rx->nfa_states;
+ total_nodec = 0;
+ while (n)
+ {
+ struct rx_nfa_edge *e = n->edges;
+ struct rx_possible_future *ec = n->futures;
+ ++total_nodec;
+ while (e)
+ {
+ ++edgec;
+ e = e->next;
+ }
+ while (ec)
+ {
+ ++eclosec;
+ ec = ec->next;
+ }
+ n = n->next;
+ }
+
+ total_size = (total_nodec * sizeof (struct rx_nfa_state)
+ + edgec * rx_sizeof_bitset (rx->local_cset_size)
+ + edgec * sizeof (struct rx_nfa_edge)
+ + nfa_setc * sizeof (struct rx_nfa_state_set)
+ + eclosec * sizeof (struct rx_possible_future)
+ + se_list_consc * sizeof (struct rx_se_list)
+ + rx->reserved);
+
+ if (total_size > *size)
+ {
+ *mem = remalloc (*mem, total_size);
+ if (*mem)
+ *size = total_size;
+ else
+ return 0;
+ }
+ /* Now we've allocated the memory; this copies the NFA. */
+ {
+ static struct rx_nfa_state **scratch = 0;
+ static int scratch_alloc = 0;
+ struct rx_nfa_state *state_base = (struct rx_nfa_state *) * mem;
+ struct rx_nfa_state *new_state = state_base;
+ struct rx_nfa_edge *new_edge =
+ (struct rx_nfa_edge *)
+ ((char *) state_base + total_nodec * sizeof (struct rx_nfa_state));
+ struct rx_se_list * new_se_list =
+ (struct rx_se_list *)
+ ((char *)new_edge + edgec * sizeof (struct rx_nfa_edge));
+ struct rx_possible_future *new_close =
+ ((struct rx_possible_future *)
+ ((char *) new_se_list
+ + se_list_consc * sizeof (struct rx_se_list)));
+ struct rx_nfa_state_set * new_nfa_set =
+ ((struct rx_nfa_state_set *)
+ ((char *)new_close + eclosec * sizeof (struct rx_possible_future)));
+ char *new_bitset =
+ ((char *) new_nfa_set + nfa_setc * sizeof (struct rx_nfa_state_set));
+ int x;
+ struct rx_nfa_state *n;
+
+ if (scratch_alloc < total_nodec)
+ {
+ scratch = ((struct rx_nfa_state **)
+ remalloc (scratch, total_nodec * sizeof (*scratch)));
+ if (scratch)
+ scratch_alloc = total_nodec;
+ else
+ {
+ scratch_alloc = 0;
+ return 0;
+ }
+ }
+
+ for (x = 0, n = rx->nfa_states; n; n = n->next)
+ scratch[x++] = n;
+
+ qsort (scratch, total_nodec,
+ sizeof (struct rx_nfa_state *), (int (*)())nfacmp);
+
+ for (x = 0; x < total_nodec; ++x)
+ {
+ struct rx_possible_future *eclose = scratch[x]->futures;
+ struct rx_nfa_edge *edge = scratch[x]->edges;
+ struct rx_nfa_state *cn = new_state++;
+ cn->futures = 0;
+ cn->edges = 0;
+ cn->next = (x == total_nodec - 1) ? 0 : (cn + 1);
+ cn->id = scratch[x]->id;
+ cn->is_final = scratch[x]->is_final;
+ cn->is_start = scratch[x]->is_start;
+ cn->mark = 0;
+ while (edge)
+ {
+ int indx = (edge->dest->id < 0
+ ? (total_nodec + edge->dest->id)
+ : edge->dest->id);
+ struct rx_nfa_edge *e = new_edge++;
+ rx_Bitset cset = (rx_Bitset) new_bitset;
+ new_bitset += rx_sizeof_bitset (rx->local_cset_size);
+ rx_bitset_null (rx->local_cset_size, cset);
+ rx_bitset_union (rx->local_cset_size, cset, edge->params.cset);
+ e->next = cn->edges;
+ cn->edges = e;
+ e->type = edge->type;
+ e->dest = state_base + indx;
+ e->params.cset = cset;
+ edge = edge->next;
+ }
+ while (eclose)
+ {
+ struct rx_possible_future *ec = new_close++;
+ struct rx_hash_item * sp;
+ struct rx_se_list ** sepos;
+ struct rx_se_list * sesrc;
+ struct rx_nfa_state_set * destlst;
+ struct rx_nfa_state_set ** destpos;
+ ec->next = cn->futures;
+ cn->futures = ec;
+ for (sepos = &ec->effects, sesrc = eclose->effects;
+ sesrc;
+ sesrc = sesrc->cdr, sepos = &(*sepos)->cdr)
+ {
+ sp = rx_hash_find (&rx->se_list_memo,
+ (long)sesrc->car ^ (long)sesrc->cdr,
+ sesrc, &se_list_hash_rules);
+ if (sp->binding)
+ {
+ sesrc = (struct rx_se_list *)sp->binding;
+ break;
+ }
+ *new_se_list = *sesrc;
+ sp->binding = (void *)new_se_list;
+ *sepos = new_se_list;
+ ++new_se_list;
+ }
+ *sepos = sesrc;
+ for (destpos = &ec->destset, destlst = eclose->destset;
+ destlst;
+ destpos = &(*destpos)->cdr, destlst = destlst->cdr)
+ {
+ sp = rx_hash_find (&rx->set_list_memo,
+ ((((long)destlst->car) >> 8)
+ ^ (long)destlst->cdr),
+ destlst, &nfa_set_hash_rules);
+ if (sp->binding)
+ {
+ destlst = (struct rx_nfa_state_set *)sp->binding;
+ break;
+ }
+ *new_nfa_set = *destlst;
+ new_nfa_set->car = state_base + destlst->car->id;
+ sp->binding = (void *)new_nfa_set;
+ *destpos = new_nfa_set;
+ ++new_nfa_set;
+ }
+ *destpos = destlst;
+ eclose = eclose->next;
+ }
+ }
+ }
+ rx_free_hash_table (&rx->se_list_memo, se_memo_freer, &se_list_hash_rules);
+ bzero (&rx->se_list_memo, sizeof (rx->se_list_memo));
+ rx_free_hash_table (&rx->set_list_memo, nfa_set_freer, &nfa_set_hash_rules);
+ bzero (&rx->set_list_memo, sizeof (rx->set_list_memo));
+
+ rx_free_nfa (rx);
+ rx->nfa_states = (struct rx_nfa_state *)*mem;
+ return 1;
+}
+
+
+/* The functions in the next several pages define the lazy-NFA-conversion used
+ * by matchers. The input to this construction is an NFA such as
+ * is built by compactify_nfa (rx.c). The output is the superNFA.
+ */
+
+/* Match engines can use arbitrary values for opcodes. So, the parse tree
+ * is built using instructions names (enum rx_opcode), but the superstate
+ * nfa is populated with mystery opcodes (void *).
+ *
+ * For convenience, here is an id table. The opcodes are == to their inxs
+ *
+ * The lables in re_search_2 would make good values for instructions.
+ */
+
+void * rx_id_instruction_table[rx_num_instructions] =
+{
+ (void *) rx_backtrack_point,
+ (void *) rx_do_side_effects,
+ (void *) rx_cache_miss,
+ (void *) rx_next_char,
+ (void *) rx_backtrack,
+ (void *) rx_error_inx
+};
+
+
+
+/* Memory mgt. for superstate graphs. */
+
+#ifdef __STDC__
+static char *
+rx_cache_malloc (struct rx_cache * cache, int bytes)
+#else
+static char *
+rx_cache_malloc (cache, bytes)
+ struct rx_cache * cache;
+ int bytes;
+#endif
+{
+ while (cache->bytes_left < bytes)
+ {
+ if (cache->memory_pos)
+ cache->memory_pos = cache->memory_pos->next;
+ if (!cache->memory_pos)
+ {
+ cache->morecore (cache);
+ if (!cache->memory_pos)
+ return 0;
+ }
+ cache->bytes_left = cache->memory_pos->bytes;
+ cache->memory_addr = ((char *)cache->memory_pos
+ + sizeof (struct rx_blocklist));
+ }
+ cache->bytes_left -= bytes;
+ {
+ char * addr = cache->memory_addr;
+ cache->memory_addr += bytes;
+ return addr;
+ }
+}
+
+#ifdef __STDC__
+static void
+rx_cache_free (struct rx_cache * cache,
+ struct rx_freelist ** freelist, char * mem)
+#else
+static void
+rx_cache_free (cache, freelist, mem)
+ struct rx_cache * cache;
+ struct rx_freelist ** freelist;
+ char * mem;
+#endif
+{
+ struct rx_freelist * it = (struct rx_freelist *)mem;
+ it->next = *freelist;
+ *freelist = it;
+}
+
+
+/* The partially instantiated superstate graph has a transition
+ * table at every node. There is one entry for every character.
+ * This fills in the transition for a set.
+ */
+#ifdef __STDC__
+static void
+install_transition (struct rx_superstate *super,
+ struct rx_inx *answer, rx_Bitset trcset)
+#else
+static void
+install_transition (super, answer, trcset)
+ struct rx_superstate *super;
+ struct rx_inx *answer;
+ rx_Bitset trcset;
+#endif
+{
+ struct rx_inx * transitions = super->transitions;
+ int chr;
+ for (chr = 0; chr < 256; )
+ if (!*trcset)
+ {
+ ++trcset;
+ chr += 32;
+ }
+ else
+ {
+ RX_subset sub = *trcset;
+ RX_subset mask = 1;
+ int bound = chr + 32;
+ while (chr < bound)
+ {
+ if (sub & mask)
+ transitions [chr] = *answer;
+ ++chr;
+ mask <<= 1;
+ }
+ ++trcset;
+ }
+}
+
+
+#ifdef __STDC__
+static int
+qlen (struct rx_superstate * q)
+#else
+static int
+qlen (q)
+ struct rx_superstate * q;
+#endif
+{
+ int count = 1;
+ struct rx_superstate * it;
+ if (!q)
+ return 0;
+ for (it = q->next_recyclable; it != q; it = it->next_recyclable)
+ ++count;
+ return count;
+}
+
+#ifdef __STDC__
+static void
+check_cache (struct rx_cache * cache)
+#else
+static void
+check_cache (cache)
+ struct rx_cache * cache;
+#endif
+{
+ struct rx_cache * you_fucked_up = 0;
+ int total = cache->superstates;
+ int semi = cache->semifree_superstates;
+ if (semi != qlen (cache->semifree_superstate))
+ check_cache (you_fucked_up);
+ if ((total - semi) != qlen (cache->lru_superstate))
+ check_cache (you_fucked_up);
+}
+
+/* When a superstate is old and neglected, it can enter a
+ * semi-free state. A semi-free state is slated to die.
+ * Incoming transitions to a semi-free state are re-written
+ * to cause an (interpreted) fault when they are taken.
+ * The fault handler revives the semi-free state, patches
+ * incoming transitions back to normal, and continues.
+ *
+ * The idea is basicly to free in two stages, aborting
+ * between the two if the state turns out to be useful again.
+ * When a free is aborted, the rescued superstate is placed
+ * in the most-favored slot to maximize the time until it
+ * is next semi-freed.
+ */
+
+#ifdef __STDC__
+static void
+semifree_superstate (struct rx_cache * cache)
+#else
+static void
+semifree_superstate (cache)
+ struct rx_cache * cache;
+#endif
+{
+ int disqualified = cache->semifree_superstates;
+ if (disqualified == cache->superstates)
+ return;
+ while (cache->lru_superstate->locks)
+ {
+ cache->lru_superstate = cache->lru_superstate->next_recyclable;
+ ++disqualified;
+ if (disqualified == cache->superstates)
+ return;
+ }
+ {
+ struct rx_superstate * it = cache->lru_superstate;
+ it->next_recyclable->prev_recyclable = it->prev_recyclable;
+ it->prev_recyclable->next_recyclable = it->next_recyclable;
+ cache->lru_superstate = (it == it->next_recyclable
+ ? 0
+ : it->next_recyclable);
+ if (!cache->semifree_superstate)
+ {
+ cache->semifree_superstate = it;
+ it->next_recyclable = it;
+ it->prev_recyclable = it;
+ }
+ else
+ {
+ it->prev_recyclable = cache->semifree_superstate->prev_recyclable;
+ it->next_recyclable = cache->semifree_superstate;
+ it->prev_recyclable->next_recyclable = it;
+ it->next_recyclable->prev_recyclable = it;
+ }
+ {
+ struct rx_distinct_future *df;
+ it->is_semifree = 1;
+ ++cache->semifree_superstates;
+ df = it->transition_refs;
+ if (df)
+ {
+ df->prev_same_dest->next_same_dest = 0;
+ for (df = it->transition_refs; df; df = df->next_same_dest)
+ {
+ df->future_frame.inx = cache->instruction_table[rx_cache_miss];
+ df->future_frame.data = 0;
+ df->future_frame.data_2 = (void *) df;
+ /* If there are any NEXT-CHAR instruction frames that
+ * refer to this state, we convert them to CACHE-MISS frames.
+ */
+ if (!df->effects
+ && (df->edge->options->next_same_super_edge[0]
+ == df->edge->options))
+ install_transition (df->present, &df->future_frame,
+ df->edge->cset);
+ }
+ df = it->transition_refs;
+ df->prev_same_dest->next_same_dest = df;
+ }
+ }
+ }
+}
+
+
+#ifdef __STDC__
+static void
+refresh_semifree_superstate (struct rx_cache * cache,
+ struct rx_superstate * super)
+#else
+static void
+refresh_semifree_superstate (cache, super)
+ struct rx_cache * cache;
+ struct rx_superstate * super;
+#endif
+{
+ struct rx_distinct_future *df;
+
+ if (super->transition_refs)
+ {
+ super->transition_refs->prev_same_dest->next_same_dest = 0;
+ for (df = super->transition_refs; df; df = df->next_same_dest)
+ {
+ df->future_frame.inx = cache->instruction_table[rx_next_char];
+ df->future_frame.data = (void *) super->transitions;
+ /* CACHE-MISS instruction frames that refer to this state,
+ * must be converted to NEXT-CHAR frames.
+ */
+ if (!df->effects
+ && (df->edge->options->next_same_super_edge[0]
+ == df->edge->options))
+ install_transition (df->present, &df->future_frame,
+ df->edge->cset);
+ }
+ super->transition_refs->prev_same_dest->next_same_dest
+ = super->transition_refs;
+ }
+ if (cache->semifree_superstate == super)
+ cache->semifree_superstate = (super->prev_recyclable == super
+ ? 0
+ : super->prev_recyclable);
+ super->next_recyclable->prev_recyclable = super->prev_recyclable;
+ super->prev_recyclable->next_recyclable = super->next_recyclable;
+
+ if (!cache->lru_superstate)
+ (cache->lru_superstate
+ = super->next_recyclable
+ = super->prev_recyclable
+ = super);
+ else
+ {
+ super->next_recyclable = cache->lru_superstate;
+ super->prev_recyclable = cache->lru_superstate->prev_recyclable;
+ super->next_recyclable->prev_recyclable = super;
+ super->prev_recyclable->next_recyclable = super;
+ }
+ super->is_semifree = 0;
+ --cache->semifree_superstates;
+}
+
+#ifdef __STDC__
+static void
+rx_refresh_this_superstate (struct rx_cache * cache, struct rx_superstate * superstate)
+#else
+static void
+rx_refresh_this_superstate (cache, superstate)
+ struct rx_cache * cache;
+ struct rx_superstate * superstate;
+#endif
+{
+ if (superstate->is_semifree)
+ refresh_semifree_superstate (cache, superstate);
+ else if (cache->lru_superstate == superstate)
+ cache->lru_superstate = superstate->next_recyclable;
+ else if (superstate != cache->lru_superstate->prev_recyclable)
+ {
+ superstate->next_recyclable->prev_recyclable
+ = superstate->prev_recyclable;
+ superstate->prev_recyclable->next_recyclable
+ = superstate->next_recyclable;
+ superstate->next_recyclable = cache->lru_superstate;
+ superstate->prev_recyclable = cache->lru_superstate->prev_recyclable;
+ superstate->next_recyclable->prev_recyclable = superstate;
+ superstate->prev_recyclable->next_recyclable = superstate;
+ }
+}
+
+#ifdef __STDC__
+static void
+release_superset_low (struct rx_cache * cache,
+ struct rx_superset *set)
+#else
+static void
+release_superset_low (cache, set)
+ struct rx_cache * cache;
+ struct rx_superset *set;
+#endif
+{
+ if (!--set->refs)
+ {
+ if (set->cdr)
+ release_superset_low (cache, set->cdr);
+
+ set->starts_for = 0;
+
+ rx_hash_free
+ (rx_hash_find
+ (&cache->superset_table,
+ (unsigned long)set->car ^ set->id ^ (unsigned long)set->cdr,
+ (void *)set,
+ &cache->superset_hash_rules),
+ &cache->superset_hash_rules);
+ rx_cache_free (cache, &cache->free_supersets, (char *)set);
+ }
+}
+
+#ifdef __STDC__
+RX_DECL void
+rx_release_superset (struct rx *rx,
+ struct rx_superset *set)
+#else
+RX_DECL void
+rx_release_superset (rx, set)
+ struct rx *rx;
+ struct rx_superset *set;
+#endif
+{
+ release_superset_low (rx->cache, set);
+}
+
+/* This tries to add a new superstate to the superstate freelist.
+ * It might, as a result, free some edge pieces or hash tables.
+ * If nothing can be freed because too many locks are being held, fail.
+ */
+
+#ifdef __STDC__
+static int
+rx_really_free_superstate (struct rx_cache * cache)
+#else
+static int
+rx_really_free_superstate (cache)
+ struct rx_cache * cache;
+#endif
+{
+ int locked_superstates = 0;
+ struct rx_superstate * it;
+
+ if (!cache->superstates)
+ return 0;
+
+ {
+ /* This is a total guess. The idea is that we should expect as
+ * many misses as we've recently experienced. I.e., cache->misses
+ * should be the same as cache->semifree_superstates.
+ */
+ while ((cache->hits + cache->misses) > cache->superstates_allowed)
+ {
+ cache->hits >>= 1;
+ cache->misses >>= 1;
+ }
+ if ( ((cache->hits + cache->misses) * cache->semifree_superstates)
+ < (cache->superstates * cache->misses))
+ {
+ semifree_superstate (cache);
+ semifree_superstate (cache);
+ }
+ }
+
+ while (cache->semifree_superstate && cache->semifree_superstate->locks)
+ {
+ refresh_semifree_superstate (cache, cache->semifree_superstate);
+ ++locked_superstates;
+ if (locked_superstates == cache->superstates)
+ return 0;
+ }
+
+ if (cache->semifree_superstate)
+ {
+ it = cache->semifree_superstate;
+ it->next_recyclable->prev_recyclable = it->prev_recyclable;
+ it->prev_recyclable->next_recyclable = it->next_recyclable;
+ cache->semifree_superstate = ((it == it->next_recyclable)
+ ? 0
+ : it->next_recyclable);
+ --cache->semifree_superstates;
+ }
+ else
+ {
+ while (cache->lru_superstate->locks)
+ {
+ cache->lru_superstate = cache->lru_superstate->next_recyclable;
+ ++locked_superstates;
+ if (locked_superstates == cache->superstates)
+ return 0;
+ }
+ it = cache->lru_superstate;
+ it->next_recyclable->prev_recyclable = it->prev_recyclable;
+ it->prev_recyclable->next_recyclable = it->next_recyclable;
+ cache->lru_superstate = ((it == it->next_recyclable)
+ ? 0
+ : it->next_recyclable);
+ }
+
+ if (it->transition_refs)
+ {
+ struct rx_distinct_future *df;
+ for (df = it->transition_refs,
+ df->prev_same_dest->next_same_dest = 0;
+ df;
+ df = df->next_same_dest)
+ {
+ df->future_frame.inx = cache->instruction_table[rx_cache_miss];
+ df->future_frame.data = 0;
+ df->future_frame.data_2 = (void *) df;
+ df->future = 0;
+ }
+ it->transition_refs->prev_same_dest->next_same_dest =
+ it->transition_refs;
+ }
+ {
+ struct rx_super_edge *tc = it->edges;
+ while (tc)
+ {
+ struct rx_distinct_future * df;
+ struct rx_super_edge *tct = tc->next;
+ df = tc->options;
+ df->next_same_super_edge[1]->next_same_super_edge[0] = 0;
+ while (df)
+ {
+ struct rx_distinct_future *dft = df;
+ df = df->next_same_super_edge[0];
+
+
+ if (dft->future && dft->future->transition_refs == dft)
+ {
+ dft->future->transition_refs = dft->next_same_dest;
+ if (dft->future->transition_refs == dft)
+ dft->future->transition_refs = 0;
+ }
+ dft->next_same_dest->prev_same_dest = dft->prev_same_dest;
+ dft->prev_same_dest->next_same_dest = dft->next_same_dest;
+ rx_cache_free (cache, &cache->free_discernable_futures,
+ (char *)dft);
+ }
+ rx_cache_free (cache, &cache->free_transition_classes, (char *)tc);
+ tc = tct;
+ }
+ }
+
+ if (it->contents->superstate == it)
+ it->contents->superstate = 0;
+ release_superset_low (cache, it->contents);
+ rx_cache_free (cache, &cache->free_superstates, (char *)it);
+ --cache->superstates;
+ return 1;
+}
+
+#ifdef __STDC__
+static char *
+rx_cache_get (struct rx_cache * cache,
+ struct rx_freelist ** freelist)
+#else
+static char *
+rx_cache_get (cache, freelist)
+ struct rx_cache * cache;
+ struct rx_freelist ** freelist;
+#endif
+{
+ while (!*freelist && rx_really_free_superstate (cache))
+ ;
+ if (!*freelist)
+ return 0;
+ {
+ struct rx_freelist * it = *freelist;
+ *freelist = it->next;
+ return (char *)it;
+ }
+}
+
+#ifdef __STDC__
+static char *
+rx_cache_malloc_or_get (struct rx_cache * cache,
+ struct rx_freelist ** freelist, int bytes)
+#else
+static char *
+rx_cache_malloc_or_get (cache, freelist, bytes)
+ struct rx_cache * cache;
+ struct rx_freelist ** freelist;
+ int bytes;
+#endif
+{
+ if (!*freelist)
+ {
+ char * answer = rx_cache_malloc (cache, bytes);
+ if (answer)
+ return answer;
+ }
+
+ return rx_cache_get (cache, freelist);
+}
+
+#ifdef __STDC__
+static char *
+rx_cache_get_superstate (struct rx_cache * cache)
+#else
+static char *
+rx_cache_get_superstate (cache)
+ struct rx_cache * cache;
+#endif
+{
+ char * answer;
+ int bytes = ( sizeof (struct rx_superstate)
+ + cache->local_cset_size * sizeof (struct rx_inx));
+ if (!cache->free_superstates
+ && (cache->superstates < cache->superstates_allowed))
+ {
+ answer = rx_cache_malloc (cache, bytes);
+ if (answer)
+ {
+ ++cache->superstates;
+ return answer;
+ }
+ }
+ answer = rx_cache_get (cache, &cache->free_superstates);
+ if (!answer)
+ {
+ answer = rx_cache_malloc (cache, bytes);
+ if (answer)
+ ++cache->superstates_allowed;
+ }
+ ++cache->superstates;
+ return answer;
+}
+
+
+
+#ifdef __STDC__
+static int
+supersetcmp (void * va, void * vb)
+#else
+static int
+supersetcmp (va, vb)
+ void * va;
+ void * vb;
+#endif
+{
+ struct rx_superset * a = (struct rx_superset *)va;
+ struct rx_superset * b = (struct rx_superset *)vb;
+ return ( (a == b)
+ || (a && b && (a->car == b->car) && (a->cdr == b->cdr)));
+}
+
+#ifdef __STDC__
+static struct rx_hash_item *
+superset_allocator (struct rx_hash_rules * rules, void * val)
+#else
+static struct rx_hash_item *
+superset_allocator (rules, val)
+ struct rx_hash_rules * rules;
+ void * val;
+#endif
+{
+ struct rx_cache * cache
+ = ((struct rx_cache *)
+ ((char *)rules
+ - (unsigned long)(&((struct rx_cache *)0)->superset_hash_rules)));
+ struct rx_superset * template = (struct rx_superset *)val;
+ struct rx_superset * newset
+ = ((struct rx_superset *)
+ rx_cache_malloc_or_get (cache,
+ &cache->free_supersets,
+ sizeof (*template)));
+ if (!newset)
+ return 0;
+ newset->refs = 0;
+ newset->car = template->car;
+ newset->id = template->car->id;
+ newset->cdr = template->cdr;
+ newset->superstate = 0;
+ rx_protect_superset (rx, template->cdr);
+ newset->hash_item.data = (void *)newset;
+ newset->hash_item.binding = 0;
+ return &newset->hash_item;
+}
+
+#ifdef __STDC__
+static struct rx_hash *
+super_hash_allocator (struct rx_hash_rules * rules)
+#else
+static struct rx_hash *
+super_hash_allocator (rules)
+ struct rx_hash_rules * rules;
+#endif
+{
+ struct rx_cache * cache
+ = ((struct rx_cache *)
+ ((char *)rules
+ - (unsigned long)(&((struct rx_cache *)0)->superset_hash_rules)));
+ return ((struct rx_hash *)
+ rx_cache_malloc_or_get (cache,
+ &cache->free_hash, sizeof (struct rx_hash)));
+}
+
+
+#ifdef __STDC__
+static void
+super_hash_liberator (struct rx_hash * hash, struct rx_hash_rules * rules)
+#else
+static void
+super_hash_liberator (hash, rules)
+ struct rx_hash * hash;
+ struct rx_hash_rules * rules;
+#endif
+{
+ struct rx_cache * cache
+ = ((struct rx_cache *)
+ (char *)rules - (long)(&((struct rx_cache *)0)->superset_hash_rules));
+ rx_cache_free (cache, &cache->free_hash, (char *)hash);
+}
+
+#ifdef __STDC__
+static void
+superset_hash_item_liberator (struct rx_hash_item * it,
+ struct rx_hash_rules * rules)
+#else
+static void
+superset_hash_item_liberator (it, rules) /* Well, it does ya know. */
+ struct rx_hash_item * it;
+ struct rx_hash_rules * rules;
+#endif
+{
+}
+
+int rx_cache_bound = 128;
+static int rx_default_cache_got = 0;
+
+#ifdef __STDC__
+static int
+bytes_for_cache_size (int supers, int cset_size)
+#else
+static int
+bytes_for_cache_size (supers, cset_size)
+ int supers;
+ int cset_size;
+#endif
+{
+ /* What the hell is this? !!!*/
+ return (int)
+ ((float)supers *
+ ( (1.03 * (float) ( rx_sizeof_bitset (cset_size)
+ + sizeof (struct rx_super_edge)))
+ + (1.80 * (float) sizeof (struct rx_possible_future))
+ + (float) ( sizeof (struct rx_superstate)
+ + cset_size * sizeof (struct rx_inx))));
+}
+
+#ifdef __STDC__
+static void
+rx_morecore (struct rx_cache * cache)
+#else
+static void
+rx_morecore (cache)
+ struct rx_cache * cache;
+#endif
+{
+ if (rx_default_cache_got >= rx_cache_bound)
+ return;
+
+ rx_default_cache_got += 16;
+ cache->superstates_allowed = rx_cache_bound;
+ {
+ struct rx_blocklist ** pos = &cache->memory;
+ int size = bytes_for_cache_size (16, cache->local_cset_size);
+ while (*pos)
+ pos = &(*pos)->next;
+ *pos = ((struct rx_blocklist *)
+ malloc (size + sizeof (struct rx_blocklist)));
+ if (!*pos)
+ return;
+
+ (*pos)->next = 0;
+ (*pos)->bytes = size;
+ cache->memory_pos = *pos;
+ cache->memory_addr = (char *)*pos + sizeof (**pos);
+ cache->bytes_left = size;
+ }
+}
+
+static struct rx_cache default_cache =
+{
+ {
+ supersetcmp,
+ super_hash_allocator,
+ super_hash_liberator,
+ superset_allocator,
+ superset_hash_item_liberator,
+ },
+ 0,
+ 0,
+ 0,
+ 0,
+ rx_morecore,
+
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+ 128,
+
+ 256,
+ rx_id_instruction_table,
+
+ {
+ 0,
+ 0,
+ {0},
+ {0},
+ {0}
+ }
+};
+
+/* This adds an element to a superstate set. These sets are lists, such
+ * that lists with == elements are ==. The empty set is returned by
+ * superset_cons (rx, 0, 0) and is NOT equivelent to
+ * (struct rx_superset)0.
+ */
+
+#ifdef __STDC__
+RX_DECL struct rx_superset *
+rx_superset_cons (struct rx * rx,
+ struct rx_nfa_state *car, struct rx_superset *cdr)
+#else
+RX_DECL struct rx_superset *
+rx_superset_cons (rx, car, cdr)
+ struct rx * rx;
+ struct rx_nfa_state *car;
+ struct rx_superset *cdr;
+#endif
+{
+ struct rx_cache * cache = rx->cache;
+ if (!car && !cdr)
+ {
+ if (!cache->empty_superset)
+ {
+ cache->empty_superset
+ = ((struct rx_superset *)
+ rx_cache_malloc_or_get (cache, &cache->free_supersets,
+ sizeof (struct rx_superset)));
+ if (!cache->empty_superset)
+ return 0;
+ bzero (cache->empty_superset, sizeof (struct rx_superset));
+ cache->empty_superset->refs = 1000;
+ }
+ return cache->empty_superset;
+ }
+ {
+ struct rx_superset template;
+ struct rx_hash_item * hit;
+ template.car = car;
+ template.cdr = cdr;
+ template.id = car->id;
+ hit = rx_hash_store (&cache->superset_table,
+ (unsigned long)car ^ car->id ^ (unsigned long)cdr,
+ (void *)&template,
+ &cache->superset_hash_rules);
+ return (hit
+ ? (struct rx_superset *)hit->data
+ : 0);
+ }
+}
+
+/* This computes a union of two NFA state sets. The sets do not have the
+ * same representation though. One is a RX_SUPERSET structure (part
+ * of the superstate NFA) and the other is an NFA_STATE_SET (part of the NFA).
+ */
+
+#ifdef __STDC__
+RX_DECL struct rx_superset *
+rx_superstate_eclosure_union
+ (struct rx * rx, struct rx_superset *set, struct rx_nfa_state_set *ecl)
+#else
+RX_DECL struct rx_superset *
+rx_superstate_eclosure_union (rx, set, ecl)
+ struct rx * rx;
+ struct rx_superset *set;
+ struct rx_nfa_state_set *ecl;
+#endif
+{
+ if (!ecl)
+ return set;
+
+ if (!set->car)
+ return rx_superset_cons (rx, ecl->car,
+ rx_superstate_eclosure_union (rx, set, ecl->cdr));
+ if (set->car == ecl->car)
+ return rx_superstate_eclosure_union (rx, set, ecl->cdr);
+
+ {
+ struct rx_superset * tail;
+ struct rx_nfa_state * first;
+
+ if (set->car > ecl->car)
+ {
+ tail = rx_superstate_eclosure_union (rx, set->cdr, ecl);
+ first = set->car;
+ }
+ else
+ {
+ tail = rx_superstate_eclosure_union (rx, set, ecl->cdr);
+ first = ecl->car;
+ }
+ if (!tail)
+ return 0;
+ else
+ {
+ struct rx_superset * answer;
+ answer = rx_superset_cons (rx, first, tail);
+ if (!answer)
+ {
+ rx_protect_superset (rx, tail);
+ rx_release_superset (rx, tail);
+ return 0;
+ }
+ else
+ return answer;
+ }
+ }
+}
+
+
+
+
+/*
+ * This makes sure that a list of rx_distinct_futures contains
+ * a future for each possible set of side effects in the eclosure
+ * of a given state. This is some of the work of filling in a
+ * superstate transition.
+ */
+
+#ifdef __STDC__
+static struct rx_distinct_future *
+include_futures (struct rx *rx,
+ struct rx_distinct_future *df, struct rx_nfa_state
+ *state, struct rx_superstate *superstate)
+#else
+static struct rx_distinct_future *
+include_futures (rx, df, state, superstate)
+ struct rx *rx;
+ struct rx_distinct_future *df;
+ struct rx_nfa_state *state;
+ struct rx_superstate *superstate;
+#endif
+{
+ struct rx_possible_future *future;
+ struct rx_cache * cache = rx->cache;
+ for (future = state->futures; future; future = future->next)
+ {
+ struct rx_distinct_future *dfp;
+ struct rx_distinct_future *insert_before = 0;
+ if (df)
+ df->next_same_super_edge[1]->next_same_super_edge[0] = 0;
+ for (dfp = df; dfp; dfp = dfp->next_same_super_edge[0])
+ if (dfp->effects == future->effects)
+ break;
+ else
+ {
+ int order = rx->se_list_cmp (rx, dfp->effects, future->effects);
+ if (order > 0)
+ {
+ insert_before = dfp;
+ dfp = 0;
+ break;
+ }
+ }
+ if (df)
+ df->next_same_super_edge[1]->next_same_super_edge[0] = df;
+ if (!dfp)
+ {
+ dfp
+ = ((struct rx_distinct_future *)
+ rx_cache_malloc_or_get (cache, &cache->free_discernable_futures,
+ sizeof (struct rx_distinct_future)));
+ if (!dfp)
+ return 0;
+ if (!df)
+ {
+ df = insert_before = dfp;
+ df->next_same_super_edge[0] = df->next_same_super_edge[1] = df;
+ }
+ else if (!insert_before)
+ insert_before = df;
+ else if (insert_before == df)
+ df = dfp;
+
+ dfp->next_same_super_edge[0] = insert_before;
+ dfp->next_same_super_edge[1]
+ = insert_before->next_same_super_edge[1];
+ dfp->next_same_super_edge[1]->next_same_super_edge[0] = dfp;
+ dfp->next_same_super_edge[0]->next_same_super_edge[1] = dfp;
+ dfp->next_same_dest = dfp->prev_same_dest = dfp;
+ dfp->future = 0;
+ dfp->present = superstate;
+ dfp->future_frame.inx = rx->instruction_table[rx_cache_miss];
+ dfp->future_frame.data = 0;
+ dfp->future_frame.data_2 = (void *) dfp;
+ dfp->side_effects_frame.inx
+ = rx->instruction_table[rx_do_side_effects];
+ dfp->side_effects_frame.data = 0;
+ dfp->side_effects_frame.data_2 = (void *) dfp;
+ dfp->effects = future->effects;
+ }
+ }
+ return df;
+}
+
+
+
+/* This constructs a new superstate from its state set. The only
+ * complexity here is memory management.
+ */
+#ifdef __STDC__
+RX_DECL struct rx_superstate *
+rx_superstate (struct rx *rx,
+ struct rx_superset *set)
+#else
+RX_DECL struct rx_superstate *
+rx_superstate (rx, set)
+ struct rx *rx;
+ struct rx_superset *set;
+#endif
+{
+ struct rx_cache * cache = rx->cache;
+ struct rx_superstate * superstate = 0;
+
+ /* Does the superstate already exist in the cache? */
+ if (set->superstate)
+ {
+ if (set->superstate->rx_id != rx->rx_id)
+ {
+ /* Aha. It is in the cache, but belongs to a superstate
+ * that refers to an NFA that no longer exists.
+ * (We know it no longer exists because it was evidently
+ * stored in the same region of memory as the current nfa
+ * yet it has a different id.)
+ */
+ superstate = set->superstate;
+ if (!superstate->is_semifree)
+ {
+ if (cache->lru_superstate == superstate)
+ {
+ cache->lru_superstate = superstate->next_recyclable;
+ if (cache->lru_superstate == superstate)
+ cache->lru_superstate = 0;
+ }
+ {
+ superstate->next_recyclable->prev_recyclable
+ = superstate->prev_recyclable;
+ superstate->prev_recyclable->next_recyclable
+ = superstate->next_recyclable;
+ if (!cache->semifree_superstate)
+ {
+ (cache->semifree_superstate
+ = superstate->next_recyclable
+ = superstate->prev_recyclable
+ = superstate);
+ }
+ else
+ {
+ superstate->next_recyclable = cache->semifree_superstate;
+ superstate->prev_recyclable
+ = cache->semifree_superstate->prev_recyclable;
+ superstate->next_recyclable->prev_recyclable
+ = superstate;
+ superstate->prev_recyclable->next_recyclable
+ = superstate;
+ cache->semifree_superstate = superstate;
+ }
+ ++cache->semifree_superstates;
+ }
+ }
+ set->superstate = 0;
+ goto handle_cache_miss;
+ }
+ ++cache->hits;
+ superstate = set->superstate;
+
+ rx_refresh_this_superstate (cache, superstate);
+ return superstate;
+ }
+
+ handle_cache_miss:
+
+ /* This point reached only for cache misses. */
+ ++cache->misses;
+#if RX_DEBUG
+ if (rx_debug_trace > 1)
+ {
+ struct rx_superset * setp = set;
+ fprintf (stderr, "Building a superstet %d(%d): ", rx->rx_id, set);
+ while (setp)
+ {
+ fprintf (stderr, "%d ", setp->id);
+ setp = setp->cdr;
+ }
+ fprintf (stderr, "(%d)\n", set);
+ }
+#endif
+ superstate = (struct rx_superstate *)rx_cache_get_superstate (cache);
+ if (!superstate)
+ return 0;
+
+ if (!cache->lru_superstate)
+ (cache->lru_superstate
+ = superstate->next_recyclable
+ = superstate->prev_recyclable
+ = superstate);
+ else
+ {
+ superstate->next_recyclable = cache->lru_superstate;
+ superstate->prev_recyclable = cache->lru_superstate->prev_recyclable;
+ ( superstate->prev_recyclable->next_recyclable
+ = superstate->next_recyclable->prev_recyclable
+ = superstate);
+ }
+ superstate->rx_id = rx->rx_id;
+ superstate->transition_refs = 0;
+ superstate->locks = 0;
+ superstate->is_semifree = 0;
+ set->superstate = superstate;
+ superstate->contents = set;
+ rx_protect_superset (rx, set);
+ superstate->edges = 0;
+ {
+ int x;
+ /* None of the transitions from this superstate are known yet. */
+ for (x = 0; x < rx->local_cset_size; ++x) /* &&&&& 3.8 % */
+ {
+ struct rx_inx * ifr = &superstate->transitions[x];
+ ifr->inx = rx->instruction_table [rx_cache_miss];
+ ifr->data = ifr->data_2 = 0;
+ }
+ }
+ return superstate;
+}
+
+
+/* This computes the destination set of one edge of the superstate NFA.
+ * Note that a RX_DISTINCT_FUTURE is a superstate edge.
+ * Returns 0 on an allocation failure.
+ */
+
+#ifdef __STDC__
+static int
+solve_destination (struct rx *rx, struct rx_distinct_future *df)
+#else
+static int
+solve_destination (rx, df)
+ struct rx *rx;
+ struct rx_distinct_future *df;
+#endif
+{
+ struct rx_super_edge *tc = df->edge;
+ struct rx_superset *nfa_state;
+ struct rx_superset *nil_set = rx_superset_cons (rx, 0, 0);
+ struct rx_superset *solution = nil_set;
+ struct rx_superstate *dest;
+
+ rx_protect_superset (rx, solution);
+ /* Iterate over all NFA states in the state set of this superstate. */
+ for (nfa_state = df->present->contents;
+ nfa_state->car;
+ nfa_state = nfa_state->cdr)
+ {
+ struct rx_nfa_edge *e;
+ /* Iterate over all edges of each NFA state. */
+ for (e = nfa_state->car->edges; e; e = e->next)
+ /* If we find an edge that is labeled with
+ * the characters we are solving for.....
+ */
+ if (rx_bitset_is_subset (rx->local_cset_size,
+ tc->cset, e->params.cset))
+ {
+ struct rx_nfa_state *n = e->dest;
+ struct rx_possible_future *pf;
+ /* ....search the partial epsilon closures of the destination
+ * of that edge for a path that involves the same set of
+ * side effects we are solving for.
+ * If we find such a RX_POSSIBLE_FUTURE, we add members to the
+ * stateset we are computing.
+ */
+ for (pf = n->futures; pf; pf = pf->next)
+ if (pf->effects == df->effects)
+ {
+ struct rx_superset * old_sol;
+ old_sol = solution;
+ solution = rx_superstate_eclosure_union (rx, solution,
+ pf->destset);
+ if (!solution)
+ return 0;
+ rx_protect_superset (rx, solution);
+ rx_release_superset (rx, old_sol);
+ }
+ }
+ }
+ /* It is possible that the RX_DISTINCT_FUTURE we are working on has
+ * the empty set of NFA states as its definition. In that case, this
+ * is a failure point.
+ */
+ if (solution == nil_set)
+ {
+ df->future_frame.inx = (void *) rx_backtrack;
+ df->future_frame.data = 0;
+ df->future_frame.data_2 = 0;
+ return 1;
+ }
+ dest = rx_superstate (rx, solution);
+ rx_release_superset (rx, solution);
+ if (!dest)
+ return 0;
+
+ {
+ struct rx_distinct_future *dft;
+ dft = df;
+ df->prev_same_dest->next_same_dest = 0;
+ while (dft)
+ {
+ dft->future = dest;
+ dft->future_frame.inx = rx->instruction_table[rx_next_char];
+ dft->future_frame.data = (void *) dest->transitions;
+ dft = dft->next_same_dest;
+ }
+ df->prev_same_dest->next_same_dest = df;
+ }
+ if (!dest->transition_refs)
+ dest->transition_refs = df;
+ else
+ {
+ struct rx_distinct_future *dft = dest->transition_refs->next_same_dest;
+ dest->transition_refs->next_same_dest = df->next_same_dest;
+ df->next_same_dest->prev_same_dest = dest->transition_refs;
+ df->next_same_dest = dft;
+ dft->prev_same_dest = df;
+ }
+ return 1;
+}
+
+
+/* This takes a superstate and a character, and computes some edges
+ * from the superstate NFA. In particular, this computes all edges
+ * that lead from SUPERSTATE given CHR. This function also
+ * computes the set of characters that share this edge set.
+ * This returns 0 on allocation error.
+ * The character set and list of edges are returned through
+ * the paramters CSETOUT and DFOUT.
+} */
+
+#ifdef __STDC__
+static int
+compute_super_edge (struct rx *rx, struct rx_distinct_future **dfout,
+ rx_Bitset csetout, struct rx_superstate *superstate,
+ unsigned char chr)
+#else
+static int
+compute_super_edge (rx, dfout, csetout, superstate, chr)
+ struct rx *rx;
+ struct rx_distinct_future **dfout;
+ rx_Bitset csetout;
+ struct rx_superstate *superstate;
+ unsigned char chr;
+#endif
+{
+ struct rx_superset *stateset = superstate->contents;
+
+ /* To compute the set of characters that share edges with CHR,
+ * we start with the full character set, and subtract.
+ */
+ rx_bitset_universe (rx->local_cset_size, csetout);
+ *dfout = 0;
+
+ /* Iterate over the NFA states in the superstate state-set. */
+ while (stateset->car)
+ {
+ struct rx_nfa_edge *e;
+ for (e = stateset->car->edges; e; e = e->next)
+ if (RX_bitset_member (e->params.cset, chr))
+ {
+ /* If we find an NFA edge that applies, we make sure there
+ * are corresponding edges in the superstate NFA.
+ */
+ {
+ struct rx_distinct_future * saved;
+ saved = *dfout;
+ *dfout = include_futures (rx, *dfout, e->dest, superstate);
+ if (!*dfout)
+ {
+ struct rx_distinct_future * df;
+ df = saved;
+ df->next_same_super_edge[1]->next_same_super_edge[0] = 0;
+ while (df)
+ {
+ struct rx_distinct_future *dft;
+ dft = df;
+ df = df->next_same_super_edge[0];
+
+ if (dft->future && dft->future->transition_refs == dft)
+ {
+ dft->future->transition_refs = dft->next_same_dest;
+ if (dft->future->transition_refs == dft)
+ dft->future->transition_refs = 0;
+ }
+ dft->next_same_dest->prev_same_dest = dft->prev_same_dest;
+ dft->prev_same_dest->next_same_dest = dft->next_same_dest;
+ rx_cache_free (rx->cache,
+ &rx->cache->free_discernable_futures,
+ (char *)dft);
+ }
+ return 0;
+ }
+ }
+ /* We also trim the character set a bit. */
+ rx_bitset_intersection (rx->local_cset_size,
+ csetout, e->params.cset);
+ }
+ else
+ /* An edge that doesn't apply at least tells us some characters
+ * that don't share the same edge set as CHR.
+ */
+ rx_bitset_difference (rx->local_cset_size, csetout, e->params.cset);
+ stateset = stateset->cdr;
+ }
+ return 1;
+}
+
+
+/* This is a constructor for RX_SUPER_EDGE structures. These are
+ * wrappers for lists of superstate NFA edges that share character sets labels.
+ * If a transition class contains more than one rx_distinct_future (superstate
+ * edge), then it represents a non-determinism in the superstate NFA.
+ */
+
+#ifdef __STDC__
+static struct rx_super_edge *
+rx_super_edge (struct rx *rx,
+ struct rx_superstate *super, rx_Bitset cset,
+ struct rx_distinct_future *df)
+#else
+static struct rx_super_edge *
+rx_super_edge (rx, super, cset, df)
+ struct rx *rx;
+ struct rx_superstate *super;
+ rx_Bitset cset;
+ struct rx_distinct_future *df;
+#endif
+{
+ struct rx_super_edge *tc =
+ (struct rx_super_edge *)rx_cache_malloc_or_get
+ (rx->cache, &rx->cache->free_transition_classes,
+ sizeof (struct rx_super_edge) + rx_sizeof_bitset (rx->local_cset_size));
+
+ if (!tc)
+ return 0;
+ tc->next = super->edges;
+ super->edges = tc;
+ tc->rx_backtrack_frame.inx = rx->instruction_table[rx_backtrack_point];
+ tc->rx_backtrack_frame.data = 0;
+ tc->rx_backtrack_frame.data_2 = (void *) tc;
+ tc->options = df;
+ tc->cset = (rx_Bitset) ((char *) tc + sizeof (*tc));
+ rx_bitset_assign (rx->local_cset_size, tc->cset, cset);
+ if (df)
+ {
+ struct rx_distinct_future * dfp = df;
+ df->next_same_super_edge[1]->next_same_super_edge[0] = 0;
+ while (dfp)
+ {
+ dfp->edge = tc;
+ dfp = dfp->next_same_super_edge[0];
+ }
+ df->next_same_super_edge[1]->next_same_super_edge[0] = df;
+ }
+ return tc;
+}
+
+
+/* There are three kinds of cache miss. The first occurs when a
+ * transition is taken that has never been computed during the
+ * lifetime of the source superstate. That cache miss is handled by
+ * calling COMPUTE_SUPER_EDGE. The second kind of cache miss
+ * occurs when the destination superstate of a transition doesn't
+ * exist. SOLVE_DESTINATION is used to construct the destination superstate.
+ * Finally, the third kind of cache miss occurs when the destination
+ * superstate of a transition is in a `semi-free state'. That case is
+ * handled by UNFREE_SUPERSTATE.
+ *
+ * The function of HANDLE_CACHE_MISS is to figure out which of these
+ * cases applies.
+ */
+
+#ifdef __STDC__
+static void
+install_partial_transition (struct rx_superstate *super,
+ struct rx_inx *answer,
+ RX_subset set, int offset)
+#else
+static void
+install_partial_transition (super, answer, set, offset)
+ struct rx_superstate *super;
+ struct rx_inx *answer;
+ RX_subset set;
+ int offset;
+#endif
+{
+ int start = offset;
+ int end = start + 32;
+ RX_subset pos = 1;
+ struct rx_inx * transitions = super->transitions;
+
+ while (start < end)
+ {
+ if (set & pos)
+ transitions[start] = *answer;
+ pos <<= 1;
+ ++start;
+ }
+}
+
+
+#ifdef __STDC__
+RX_DECL struct rx_inx *
+rx_handle_cache_miss
+ (struct rx *rx, struct rx_superstate *super, unsigned char chr, void *data)
+#else
+RX_DECL struct rx_inx *
+rx_handle_cache_miss (rx, super, chr, data)
+ struct rx *rx;
+ struct rx_superstate *super;
+ unsigned char chr;
+ void *data;
+#endif
+{
+ int offset = chr / RX_subset_bits;
+ struct rx_distinct_future *df = data;
+
+ if (!df) /* must be the shared_cache_miss_frame */
+ {
+ /* Perhaps this is just a transition waiting to be filled. */
+ struct rx_super_edge *tc;
+ RX_subset mask = rx_subset_singletons [chr % RX_subset_bits];
+
+ for (tc = super->edges; tc; tc = tc->next)
+ if (tc->cset[offset] & mask)
+ {
+ struct rx_inx * answer;
+ df = tc->options;
+ answer = ((tc->options->next_same_super_edge[0] != tc->options)
+ ? &tc->rx_backtrack_frame
+ : (df->effects
+ ? &df->side_effects_frame
+ : &df->future_frame));
+ install_partial_transition (super, answer,
+ tc->cset [offset], offset * 32);
+ return answer;
+ }
+ /* Otherwise, it's a flushed or newly encountered edge. */
+ {
+ char cset_space[1024]; /* this limit is far from unreasonable */
+ rx_Bitset trcset;
+ struct rx_inx *answer;
+
+ if (rx_sizeof_bitset (rx->local_cset_size) > sizeof (cset_space))
+ return 0; /* If the arbitrary limit is hit, always fail */
+ /* cleanly. */
+ trcset = (rx_Bitset)cset_space;
+ rx_lock_superstate (rx, super);
+ if (!compute_super_edge (rx, &df, trcset, super, chr))
+ {
+ rx_unlock_superstate (rx, super);
+ return 0;
+ }
+ if (!df) /* We just computed the fail transition. */
+ {
+ static struct rx_inx
+ shared_fail_frame = { (void *)rx_backtrack, 0, 0 };
+ answer = &shared_fail_frame;
+ }
+ else
+ {
+ tc = rx_super_edge (rx, super, trcset, df);
+ if (!tc)
+ {
+ rx_unlock_superstate (rx, super);
+ return 0;
+ }
+ answer = ((tc->options->next_same_super_edge[0] != tc->options)
+ ? &tc->rx_backtrack_frame
+ : (df->effects
+ ? &df->side_effects_frame
+ : &df->future_frame));
+ }
+ install_partial_transition (super, answer,
+ trcset[offset], offset * 32);
+ rx_unlock_superstate (rx, super);
+ return answer;
+ }
+ }
+ else if (df->future) /* A cache miss on an edge with a future? Must be
+ * a semi-free destination. */
+ {
+ if (df->future->is_semifree)
+ refresh_semifree_superstate (rx->cache, df->future);
+ return &df->future_frame;
+ }
+ else
+ /* no future superstate on an existing edge */
+ {
+ rx_lock_superstate (rx, super);
+ if (!solve_destination (rx, df))
+ {
+ rx_unlock_superstate (rx, super);
+ return 0;
+ }
+ if (!df->effects
+ && (df->edge->options->next_same_super_edge[0] == df->edge->options))
+ install_partial_transition (super, &df->future_frame,
+ df->edge->cset[offset], offset * 32);
+ rx_unlock_superstate (rx, super);
+ return &df->future_frame;
+ }
+}
+
+
+
+
+/* The rest of the code provides a regex.c compatable interface. */
+
+
+__const__ char *re_error_msg[] =
+{
+ 0, /* REG_NOUT */
+ "No match", /* REG_NOMATCH */
+ "Invalid regular expression", /* REG_BADPAT */
+ "Invalid collation character", /* REG_ECOLLATE */
+ "Invalid character class name", /* REG_ECTYPE */
+ "Trailing backslash", /* REG_EESCAPE */
+ "Invalid back reference", /* REG_ESUBREG */
+ "Unmatched [ or [^", /* REG_EBRACK */
+ "Unmatched ( or \\(", /* REG_EPAREN */
+ "Unmatched \\{", /* REG_EBRACE */
+ "Invalid content of \\{\\}", /* REG_BADBR */
+ "Invalid range end", /* REG_ERANGE */
+ "Memory exhausted", /* REG_ESPACE */
+ "Invalid preceding regular expression", /* REG_BADRPT */
+ "Premature end of regular expression", /* REG_EEND */
+ "Regular expression too big", /* REG_ESIZE */
+ "Unmatched ) or \\)", /* REG_ERPAREN */
+};
+
+
+
+/*
+ * Macros used while compiling patterns.
+ *
+ * By convention, PEND points just past the end of the uncompiled pattern,
+ * P points to the read position in the pattern. `translate' is the name
+ * of the translation table (`TRANSLATE' is the name of a macro that looks
+ * things up in `translate').
+ */
+
+
+/*
+ * Fetch the next character in the uncompiled pattern---translating it
+ * if necessary. *Also cast from a signed character in the constant
+ * string passed to us by the user to an unsigned char that we can use
+ * as an array index (in, e.g., `translate').
+ */
+#define PATFETCH(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ c = translate[c]; \
+ } while (0)
+
+/*
+ * Fetch the next character in the uncompiled pattern, with no
+ * translation.
+ */
+#define PATFETCH_RAW(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ } while (0)
+
+/* Go backwards one character in the pattern. */
+#define PATUNFETCH p--
+
+
+#define TRANSLATE(d) translate[(unsigned char) (d)]
+
+typedef unsigned regnum_t;
+
+/* Since offsets can go either forwards or backwards, this type needs to
+ * be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1.
+ */
+typedef int pattern_offset_t;
+
+typedef struct
+{
+ struct rexp_node ** top_expression; /* was begalt */
+ struct rexp_node ** last_expression; /* was laststart */
+ pattern_offset_t inner_group_offset;
+ regnum_t regnum;
+} compile_stack_elt_t;
+
+typedef struct
+{
+ compile_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} compile_stack_type;
+
+
+#define INIT_COMPILE_STACK_SIZE 32
+
+#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
+#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
+
+/* The next available element. */
+#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
+
+
+/* Set the bit for character C in a list. */
+#define SET_LIST_BIT(c) \
+ (b[((unsigned char) (c)) / CHARBITS] \
+ |= 1 << (((unsigned char) c) % CHARBITS))
+
+/* Get the next unsigned number in the uncompiled pattern. */
+#define GET_UNSIGNED_NUMBER(num) \
+ { if (p != pend) \
+ { \
+ PATFETCH (c); \
+ while (isdigit (c)) \
+ { \
+ if (num < 0) \
+ num = 0; \
+ num = num * 10 + c - '0'; \
+ if (p == pend) \
+ break; \
+ PATFETCH (c); \
+ } \
+ } \
+ }
+
+#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
+
+#define IS_CHAR_CLASS(string) \
+ (!strcmp (string, "alpha") || !strcmp (string, "upper") \
+ || !strcmp (string, "lower") || !strcmp (string, "digit") \
+ || !strcmp (string, "alnum") || !strcmp (string, "xdigit") \
+ || !strcmp (string, "space") || !strcmp (string, "print") \
+ || !strcmp (string, "punct") || !strcmp (string, "graph") \
+ || !strcmp (string, "cntrl") || !strcmp (string, "blank"))
+
+
+/* These predicates are used in regex_compile. */
+
+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
+ * after an alternative or a begin-subexpression. We assume there is at
+ * least one character before the ^.
+ */
+
+#ifdef __STDC__
+static boolean
+at_begline_loc_p (__const__ char *pattern, __const__ char * p, reg_syntax_t syntax)
+#else
+static boolean
+at_begline_loc_p (pattern, p, syntax)
+ __const__ char *pattern;
+ __const__ char * p;
+ reg_syntax_t syntax;
+#endif
+{
+ __const__ char *prev = p - 2;
+ boolean prev_prev_backslash = ((prev > pattern) && (prev[-1] == '\\'));
+
+ return
+
+ (/* After a subexpression? */
+ ((*prev == '(') && ((syntax & RE_NO_BK_PARENS) || prev_prev_backslash))
+ ||
+ /* After an alternative? */
+ ((*prev == '|') && ((syntax & RE_NO_BK_VBAR) || prev_prev_backslash))
+ );
+}
+
+/* The dual of at_begline_loc_p. This one is for $. We assume there is
+ * at least one character after the $, i.e., `P < PEND'.
+ */
+
+#ifdef __STDC__
+static boolean
+at_endline_loc_p (__const__ char *p, __const__ char *pend, int syntax)
+#else
+static boolean
+at_endline_loc_p (p, pend, syntax)
+ __const__ char *p;
+ __const__ char *pend;
+ int syntax;
+#endif
+{
+ __const__ char *next = p;
+ boolean next_backslash = (*next == '\\');
+ __const__ char *next_next = (p + 1 < pend) ? (p + 1) : 0;
+
+ return
+ (
+ /* Before a subexpression? */
+ ((syntax & RE_NO_BK_PARENS)
+ ? (*next == ')')
+ : (next_backslash && next_next && (*next_next == ')')))
+ ||
+ /* Before an alternative? */
+ ((syntax & RE_NO_BK_VBAR)
+ ? (*next == '|')
+ : (next_backslash && next_next && (*next_next == '|')))
+ );
+}
+
+
+unsigned char rx_id_translation[256] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+
+ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
+ 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
+ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
+ 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
+
+ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
+ 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
+ 220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
+ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
+ 250, 251, 252, 253, 254, 255
+};
+
+/* The compiler keeps an inverted translation table.
+ * This looks up/inititalize elements.
+ * VALID is an array of booleans that validate CACHE.
+ */
+
+#ifdef __STDC__
+static rx_Bitset
+inverse_translation (struct re_pattern_buffer * rxb,
+ char * valid, rx_Bitset cache,
+ unsigned char * translate, int c)
+#else
+static rx_Bitset
+inverse_translation (rxb, valid, cache, translate, c)
+ struct re_pattern_buffer * rxb;
+ char * valid;
+ rx_Bitset cache;
+ unsigned char * translate;
+ int c;
+#endif
+{
+ rx_Bitset cs
+ = cache + c * rx_bitset_numb_subsets (rxb->rx.local_cset_size);
+
+ if (!valid[c])
+ {
+ int x;
+ int c_tr = TRANSLATE(c);
+ rx_bitset_null (rxb->rx.local_cset_size, cs);
+ for (x = 0; x < 256; ++x) /* &&&& 13.37 */
+ if (TRANSLATE(x) == c_tr)
+ RX_bitset_enjoin (cs, x);
+ valid[c] = 1;
+ }
+ return cs;
+}
+
+
+
+
+/* More subroutine declarations and macros for regex_compile. */
+
+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
+ false if it's not. */
+
+#ifdef __STDC__
+static boolean
+group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum)
+#else
+static boolean
+group_in_compile_stack (compile_stack, regnum)
+ compile_stack_type compile_stack;
+ regnum_t regnum;
+#endif
+{
+ int this_element;
+
+ for (this_element = compile_stack.avail - 1;
+ this_element >= 0;
+ this_element--)
+ if (compile_stack.stack[this_element].regnum == regnum)
+ return true;
+
+ return false;
+}
+
+
+/*
+ * Read the ending character of a range (in a bracket expression) from the
+ * uncompiled pattern *P_PTR (which ends at PEND). We assume the
+ * starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
+ * Then we set the translation of all bits between the starting and
+ * ending characters (inclusive) in the compiled pattern B.
+ *
+ * Return an error code.
+ *
+ * We use these short variable names so we can use the same macros as
+ * `regex_compile' itself.
+ */
+
+#ifdef __STDC__
+static reg_errcode_t
+compile_range (struct re_pattern_buffer * rxb, rx_Bitset cs,
+ __const__ char ** p_ptr, __const__ char * pend,
+ unsigned char * translate, reg_syntax_t syntax,
+ rx_Bitset inv_tr, char * valid_inv_tr)
+#else
+static reg_errcode_t
+compile_range (rxb, cs, p_ptr, pend, translate, syntax, inv_tr, valid_inv_tr)
+ struct re_pattern_buffer * rxb;
+ rx_Bitset cs;
+ __const__ char ** p_ptr;
+ __const__ char * pend;
+ unsigned char * translate;
+ reg_syntax_t syntax;
+ rx_Bitset inv_tr;
+ char * valid_inv_tr;
+#endif
+{
+ unsigned this_char;
+
+ __const__ char *p = *p_ptr;
+
+ unsigned char range_end;
+ unsigned char range_start = TRANSLATE(p[-2]);
+
+ if (p == pend)
+ return REG_ERANGE;
+
+ PATFETCH (range_end);
+
+ (*p_ptr)++;
+
+ if (range_start > range_end)
+ return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
+
+ for (this_char = range_start; this_char <= range_end; this_char++)
+ {
+ rx_Bitset it =
+ inverse_translation (rxb, valid_inv_tr, inv_tr, translate, this_char);
+ rx_bitset_union (rxb->rx.local_cset_size, cs, it);
+ }
+
+ return REG_NOERROR;
+}
+
+
+/* This searches a regexp for backreference side effects.
+ * It fills in the array OUT with 1 at the index of every register pair
+ * referenced by a backreference.
+ *
+ * This is used to help optimize patterns for searching. The information is
+ * useful because, if the caller doesn't want register values, backreferenced
+ * registers are the only registers for which we need rx_backtrack.
+ */
+
+#ifdef __STDC__
+static void
+find_backrefs (char * out, struct rexp_node * rexp,
+ struct re_se_params * params)
+#else
+static void
+find_backrefs (out, rexp, params)
+ char * out;
+ struct rexp_node * rexp;
+ struct re_se_params * params;
+#endif
+{
+ if (rexp)
+ switch (rexp->type)
+ {
+ case r_cset:
+ case r_data:
+ return;
+ case r_alternate:
+ case r_concat:
+ case r_opt:
+ case r_star:
+ case r_2phase_star:
+ find_backrefs (out, rexp->params.pair.left, params);
+ find_backrefs (out, rexp->params.pair.right, params);
+ return;
+ case r_side_effect:
+ if ( ((long)rexp->params.side_effect >= 0)
+ && (params [(long)rexp->params.side_effect].se == re_se_backref))
+ out[ params [(long)rexp->params.side_effect].op1] = 1;
+ return;
+ }
+}
+
+
+
+/* Returns 0 unless the pattern can match the empty string. */
+
+#ifdef __STDC__
+static int
+compute_fastset (struct re_pattern_buffer * rxb, struct rexp_node * rexp)
+#else
+static int
+compute_fastset (rxb, rexp)
+ struct re_pattern_buffer * rxb;
+ struct rexp_node * rexp;
+#endif
+{
+ if (!rexp)
+ return 1;
+ switch (rexp->type)
+ {
+ case r_data:
+ return 1;
+ case r_cset:
+ {
+ rx_bitset_union (rxb->rx.local_cset_size,
+ rxb->fastset, rexp->params.cset);
+ }
+ return 0;
+ case r_concat:
+ return (compute_fastset (rxb, rexp->params.pair.left)
+ && compute_fastset (rxb, rexp->params.pair.right));
+ case r_2phase_star:
+ compute_fastset (rxb, rexp->params.pair.left);
+ /* compute_fastset (rxb, rexp->params.pair.right); nope... */
+ return 1;
+ case r_alternate:
+ return !!(compute_fastset (rxb, rexp->params.pair.left)
+ + compute_fastset (rxb, rexp->params.pair.right));
+ case r_opt:
+ case r_star:
+ compute_fastset (rxb, rexp->params.pair.left);
+ return 1;
+ case r_side_effect:
+ return 1;
+ }
+
+ /* this should never happen */
+ return 0;
+}
+
+
+/* returns
+ * 1 -- yes, definately anchored by the given side effect.
+ * 2 -- maybe anchored, maybe the empty string.
+ * 0 -- definately not anchored
+ * There is simply no other possibility.
+ */
+
+#ifdef __STDC__
+static int
+is_anchored (struct rexp_node * rexp, rx_side_effect se)
+#else
+static int
+is_anchored (rexp, se)
+ struct rexp_node * rexp;
+ rx_side_effect se;
+#endif
+{
+ if (!rexp)
+ return 2;
+ switch (rexp->type)
+ {
+ case r_cset:
+ case r_data:
+ return 0;
+ case r_concat:
+ case r_2phase_star:
+ {
+ int l = is_anchored (rexp->params.pair.left, se);
+ return (l == 2 ? is_anchored (rexp->params.pair.right, se) : l);
+ }
+ case r_alternate:
+ {
+ int l = is_anchored (rexp->params.pair.left, se);
+ int r = l ? is_anchored (rexp->params.pair.right, se) : 0;
+ return MAX (l, r);
+ }
+ case r_opt:
+ case r_star:
+ return is_anchored (rexp->params.pair.left, se) ? 2 : 0;
+
+ case r_side_effect:
+ return ((rexp->params.side_effect == se)
+ ? 1 : 2);
+ }
+
+ /* this should never happen */
+ return 0;
+}
+
+
+/* This removes register assignments that aren't required by backreferencing.
+ * This can speed up explore_future, especially if it eliminates
+ * non-determinism in the superstate NFA.
+ *
+ * NEEDED is an array of characters, presumably filled in by FIND_BACKREFS.
+ * The non-zero elements of the array indicate which register assignments
+ * can NOT be removed from the expression.
+ */
+
+#ifdef __STDC__
+static struct rexp_node *
+remove_unecessary_side_effects (struct rx * rx, char * needed,
+ struct rexp_node * rexp,
+ struct re_se_params * params)
+#else
+static struct rexp_node *
+remove_unecessary_side_effects (rx, needed, rexp, params)
+ struct rx * rx;
+ char * needed;
+ struct rexp_node * rexp;
+ struct re_se_params * params;
+#endif
+{
+ struct rexp_node * l;
+ struct rexp_node * r;
+ if (!rexp)
+ return 0;
+ else
+ switch (rexp->type)
+ {
+ case r_cset:
+ case r_data:
+ return rexp;
+ case r_alternate:
+ case r_concat:
+ case r_2phase_star:
+ l = remove_unecessary_side_effects (rx, needed,
+ rexp->params.pair.left, params);
+ r = remove_unecessary_side_effects (rx, needed,
+ rexp->params.pair.right, params);
+ if ((l && r) || (rexp->type != r_concat))
+ {
+ rexp->params.pair.left = l;
+ rexp->params.pair.right = r;
+ return rexp;
+ }
+ else
+ {
+ rexp->params.pair.left = rexp->params.pair.right = 0;
+ rx_free_rexp (rx, rexp);
+ return l ? l : r;
+ }
+ case r_opt:
+ case r_star:
+ l = remove_unecessary_side_effects (rx, needed,
+ rexp->params.pair.left, params);
+ if (l)
+ {
+ rexp->params.pair.left = l;
+ return rexp;
+ }
+ else
+ {
+ rexp->params.pair.left = 0;
+ rx_free_rexp (rx, rexp);
+ return 0;
+ }
+ case r_side_effect:
+ {
+ int se = (long)rexp->params.side_effect;
+ if ( (se >= 0)
+ && ( ((enum re_side_effects)params[se].se == re_se_lparen)
+ || ((enum re_side_effects)params[se].se == re_se_rparen))
+ && (params [se].op1 > 0)
+ && (!needed [params [se].op1]))
+ {
+ rx_free_rexp (rx, rexp);
+ return 0;
+ }
+ else
+ return rexp;
+ }
+ }
+
+ /* this should never happen */
+ return 0;
+}
+
+
+
+#ifdef __STDC__
+static int
+pointless_if_repeated (struct rexp_node * node, struct re_se_params * params)
+#else
+static int
+pointless_if_repeated (node, params)
+ struct rexp_node * node;
+ struct re_se_params * params;
+#endif
+{
+ if (!node)
+ return 1;
+ switch (node->type)
+ {
+ case r_cset:
+ return 0;
+ case r_alternate:
+ case r_concat:
+ case r_2phase_star:
+ return (pointless_if_repeated (node->params.pair.left, params)
+ && pointless_if_repeated (node->params.pair.right, params));
+ case r_opt:
+ case r_star:
+ return pointless_if_repeated (node->params.pair.left, params);
+ case r_side_effect:
+ switch (((long)node->params.side_effect < 0)
+ ? (enum re_side_effects)node->params.side_effect
+ : (enum re_side_effects)params[(long)node->params.side_effect].se)
+ {
+ case re_se_try:
+ case re_se_at_dot:
+ case re_se_begbuf:
+ case re_se_hat:
+ case re_se_wordbeg:
+ case re_se_wordbound:
+ case re_se_notwordbound:
+ case re_se_wordend:
+ case re_se_endbuf:
+ case re_se_dollar:
+ case re_se_fail:
+ case re_se_win:
+ return 1;
+ case re_se_lparen:
+ case re_se_rparen:
+ case re_se_iter:
+ case re_se_end_iter:
+ case re_se_syntax:
+ case re_se_not_syntax:
+ case re_se_backref:
+ return 0;
+ }
+ case r_data:
+ default:
+ return 0;
+ }
+}
+
+
+
+#ifdef __STDC__
+static int
+registers_on_stack (struct re_pattern_buffer * rxb,
+ struct rexp_node * rexp, int in_danger,
+ struct re_se_params * params)
+#else
+static int
+registers_on_stack (rxb, rexp, in_danger, params)
+ struct re_pattern_buffer * rxb;
+ struct rexp_node * rexp;
+ int in_danger;
+ struct re_se_params * params;
+#endif
+{
+ if (!rexp)
+ return 0;
+ else
+ switch (rexp->type)
+ {
+ case r_cset:
+ case r_data:
+ return 0;
+ case r_alternate:
+ case r_concat:
+ return ( registers_on_stack (rxb, rexp->params.pair.left,
+ in_danger, params)
+ || (registers_on_stack
+ (rxb, rexp->params.pair.right,
+ in_danger, params)));
+ case r_opt:
+ return registers_on_stack (rxb, rexp->params.pair.left, 0, params);
+ case r_star:
+ return registers_on_stack (rxb, rexp->params.pair.left, 1, params);
+ case r_2phase_star:
+ return
+ ( registers_on_stack (rxb, rexp->params.pair.left, 1, params)
+ || registers_on_stack (rxb, rexp->params.pair.right, 1, params));
+ case r_side_effect:
+ {
+ int se = (long)rexp->params.side_effect;
+ if ( in_danger
+ && (se >= 0)
+ && (params [se].op1 > 0)
+ && ( ((enum re_side_effects)params[se].se == re_se_lparen)
+ || ((enum re_side_effects)params[se].se == re_se_rparen)))
+ return 1;
+ else
+ return 0;
+ }
+ }
+
+ /* this should never happen */
+ return 0;
+}
+
+
+
+static char idempotent_complex_se[] =
+{
+#define RX_WANT_SE_DEFS 1
+#undef RX_DEF_SE
+#undef RX_DEF_CPLX_SE
+#define RX_DEF_SE(IDEM, NAME, VALUE)
+#define RX_DEF_CPLX_SE(IDEM, NAME, VALUE) IDEM,
+#include "rx.h"
+#undef RX_DEF_SE
+#undef RX_DEF_CPLX_SE
+#undef RX_WANT_SE_DEFS
+ 23
+};
+
+static char idempotent_se[] =
+{
+ 13,
+#define RX_WANT_SE_DEFS 1
+#undef RX_DEF_SE
+#undef RX_DEF_CPLX_SE
+#define RX_DEF_SE(IDEM, NAME, VALUE) IDEM,
+#define RX_DEF_CPLX_SE(IDEM, NAME, VALUE)
+#include "rx.h"
+#undef RX_DEF_SE
+#undef RX_DEF_CPLX_SE
+#undef RX_WANT_SE_DEFS
+ 42
+};
+
+
+
+
+#ifdef __STDC__
+static int
+has_any_se (struct rx * rx,
+ struct rexp_node * rexp)
+#else
+static int
+has_any_se (rx, rexp)
+ struct rx * rx;
+ struct rexp_node * rexp;
+#endif
+{
+ if (!rexp)
+ return 0;
+
+ switch (rexp->type)
+ {
+ case r_cset:
+ case r_data:
+ return 0;
+
+ case r_side_effect:
+ return 1;
+
+ case r_2phase_star:
+ case r_concat:
+ case r_alternate:
+ return
+ ( has_any_se (rx, rexp->params.pair.left)
+ || has_any_se (rx, rexp->params.pair.right));
+
+ case r_opt:
+ case r_star:
+ return has_any_se (rx, rexp->params.pair.left);
+ }
+
+ /* this should never happen */
+ return 0;
+}
+
+
+
+/* This must be called AFTER `convert_hard_loops' for a given REXP. */
+#ifdef __STDC__
+static int
+has_non_idempotent_epsilon_path (struct rx * rx,
+ struct rexp_node * rexp,
+ struct re_se_params * params)
+#else
+static int
+has_non_idempotent_epsilon_path (rx, rexp, params)
+ struct rx * rx;
+ struct rexp_node * rexp;
+ struct re_se_params * params;
+#endif
+{
+ if (!rexp)
+ return 0;
+
+ switch (rexp->type)
+ {
+ case r_cset:
+ case r_data:
+ case r_star:
+ return 0;
+
+ case r_side_effect:
+ return
+ !((long)rexp->params.side_effect > 0
+ ? idempotent_complex_se [ params [(long)rexp->params.side_effect].se ]
+ : idempotent_se [-(long)rexp->params.side_effect]);
+
+ case r_alternate:
+ return
+ ( has_non_idempotent_epsilon_path (rx,
+ rexp->params.pair.left, params)
+ || has_non_idempotent_epsilon_path (rx,
+ rexp->params.pair.right, params));
+
+ case r_2phase_star:
+ case r_concat:
+ return
+ ( has_non_idempotent_epsilon_path (rx,
+ rexp->params.pair.left, params)
+ && has_non_idempotent_epsilon_path (rx,
+ rexp->params.pair.right, params));
+
+ case r_opt:
+ return has_non_idempotent_epsilon_path (rx,
+ rexp->params.pair.left, params);
+ }
+
+ /* this should never happen */
+ return 0;
+}
+
+
+
+/* This computes rougly what it's name suggests. It can (and does) go wrong
+ * in the direction of returning spurious 0 without causing disasters.
+ */
+#ifdef __STDC__
+static int
+begins_with_complex_se (struct rx * rx, struct rexp_node * rexp)
+#else
+static int
+begins_with_complex_se (rx, rexp)
+ struct rx * rx;
+ struct rexp_node * rexp;
+#endif
+{
+ if (!rexp)
+ return 0;
+
+ switch (rexp->type)
+ {
+ case r_cset:
+ case r_data:
+ return 0;
+
+ case r_side_effect:
+ return ((long)rexp->params.side_effect >= 0);
+
+ case r_alternate:
+ return
+ ( begins_with_complex_se (rx, rexp->params.pair.left)
+ && begins_with_complex_se (rx, rexp->params.pair.right));
+
+
+ case r_concat:
+ return has_any_se (rx, rexp->params.pair.left);
+ case r_opt:
+ case r_star:
+ case r_2phase_star:
+ return 0;
+ }
+
+ /* this should never happen */
+ return 0;
+}
+
+
+/* This destructively removes some of the re_se_tv side effects from
+ * a rexp tree. In particular, during parsing re_se_tv was inserted on the
+ * right half of every | to guarantee that posix path preference could be
+ * honored. This function removes some which it can be determined aren't
+ * needed.
+ */
+
+#ifdef __STDC__
+static void
+speed_up_alt (struct rx * rx,
+ struct rexp_node * rexp,
+ int unposix)
+#else
+static void
+speed_up_alt (rx, rexp, unposix)
+ struct rx * rx;
+ struct rexp_node * rexp;
+ int unposix;
+#endif
+{
+ if (!rexp)
+ return;
+
+ switch (rexp->type)
+ {
+ case r_cset:
+ case r_data:
+ case r_side_effect:
+ return;
+
+ case r_opt:
+ case r_star:
+ speed_up_alt (rx, rexp->params.pair.left, unposix);
+ return;
+
+ case r_2phase_star:
+ case r_concat:
+ speed_up_alt (rx, rexp->params.pair.left, unposix);
+ speed_up_alt (rx, rexp->params.pair.right, unposix);
+ return;
+
+ case r_alternate:
+ /* the right child is guaranteed to be (concat re_se_tv <subexp>) */
+
+ speed_up_alt (rx, rexp->params.pair.left, unposix);
+ speed_up_alt (rx, rexp->params.pair.right->params.pair.right, unposix);
+
+ if ( unposix
+ || (begins_with_complex_se
+ (rx, rexp->params.pair.right->params.pair.right))
+ || !( has_any_se (rx, rexp->params.pair.right->params.pair.right)
+ || has_any_se (rx, rexp->params.pair.left)))
+ {
+ struct rexp_node * conc = rexp->params.pair.right;
+ rexp->params.pair.right = conc->params.pair.right;
+ conc->params.pair.right = 0;
+ rx_free_rexp (rx, conc);
+ }
+ }
+}
+
+
+
+
+
+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
+ Returns one of error codes defined in `regex.h', or zero for success.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate'
+ fields are set in BUFP on entry.
+
+ If it succeeds, results are put in BUFP (if it returns an error, the
+ contents of BUFP are undefined):
+ `buffer' is the compiled pattern;
+ `syntax' is set to SYNTAX;
+ `used' is set to the length of the compiled pattern;
+ `fastmap_accurate' is set to zero;
+ `re_nsub' is set to the number of groups in PATTERN;
+ `not_bol' and `not_eol' are set to zero.
+
+ The `fastmap' and `newline_anchor' fields are neither
+ examined nor set. */
+
+
+
+#ifdef __STDC__
+RX_DECL reg_errcode_t
+rx_compile (__const__ char *pattern, int size,
+ reg_syntax_t syntax,
+ struct re_pattern_buffer * rxb)
+#else
+RX_DECL reg_errcode_t
+rx_compile (pattern, size, syntax, rxb)
+ __const__ char *pattern;
+ int size;
+ reg_syntax_t syntax;
+ struct re_pattern_buffer * rxb;
+#endif
+{
+ RX_subset
+ inverse_translate [CHAR_SET_SIZE * rx_bitset_numb_subsets(CHAR_SET_SIZE)];
+ char
+ validate_inv_tr [CHAR_SET_SIZE * rx_bitset_numb_subsets(CHAR_SET_SIZE)];
+
+ /* We fetch characters from PATTERN here. Even though PATTERN is
+ `char *' (i.e., signed), we declare these variables as unsigned, so
+ they can be reliably used as array indices. */
+ register unsigned char c, c1;
+
+ /* A random tempory spot in PATTERN. */
+ __const__ char *p1;
+
+ /* Keeps track of unclosed groups. */
+ compile_stack_type compile_stack;
+
+ /* Points to the current (ending) position in the pattern. */
+ __const__ char *p = pattern;
+ __const__ char *pend = pattern + size;
+
+ /* How to translate the characters in the pattern. */
+ unsigned char *translate = (rxb->translate
+ ? rxb->translate
+ : rx_id_translation);
+
+ /* When parsing is done, this will hold the expression tree. */
+ struct rexp_node * rexp = 0;
+
+ /* In the midst of compilation, this holds onto the regexp
+ * first parst while rexp goes on to aquire additional constructs.
+ */
+ struct rexp_node * orig_rexp = 0;
+ struct rexp_node * fewer_side_effects = 0;
+
+ /* This and top_expression are saved on the compile stack. */
+ struct rexp_node ** top_expression = &rexp;
+ struct rexp_node ** last_expression = top_expression;
+
+ /* Parameter to `goto append_node' */
+ struct rexp_node * append;
+
+ /* Counts open-groups as they are encountered. This is the index of the
+ * innermost group being compiled.
+ */
+ regnum_t regnum = 0;
+
+ /* Place in the uncompiled pattern (i.e., the {) to
+ * which to go back if the interval is invalid.
+ */
+ __const__ char *beg_interval;
+
+ struct re_se_params * params = 0;
+ int paramc = 0; /* How many complex side effects so far? */
+
+ rx_side_effect side; /* param to `goto add_side_effect' */
+
+ bzero (validate_inv_tr, sizeof (validate_inv_tr));
+
+ rxb->rx.instruction_table = rx_id_instruction_table;
+
+
+ /* Initialize the compile stack. */
+ compile_stack.stack = (( compile_stack_elt_t *) malloc ((INIT_COMPILE_STACK_SIZE) * sizeof ( compile_stack_elt_t)));
+ if (compile_stack.stack == 0)
+ return REG_ESPACE;
+
+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
+ compile_stack.avail = 0;
+
+ /* Initialize the pattern buffer. */
+ rxb->rx.cache = &default_cache;
+ rxb->syntax = syntax;
+ rxb->fastmap_accurate = 0;
+ rxb->not_bol = rxb->not_eol = 0;
+ rxb->least_subs = 0;
+
+ /* Always count groups, whether or not rxb->no_sub is set.
+ * The whole pattern is implicitly group 0, so counting begins
+ * with 1.
+ */
+ rxb->re_nsub = 0;
+
+#if !defined (emacs) && !defined (SYNTAX_TABLE)
+ /* Initialize the syntax table. */
+ init_syntax_once ();
+#endif
+
+ /* Loop through the uncompiled pattern until we're at the end. */
+ while (p != pend)
+ {
+ PATFETCH (c);
+
+ switch (c)
+ {
+ case '^':
+ {
+ if ( /* If at start of pattern, it's an operator. */
+ p == pattern + 1
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's come before. */
+ || at_begline_loc_p (pattern, p, syntax))
+ {
+ struct rexp_node * n
+ = rx_mk_r_side_effect (&rxb->rx, (rx_side_effect)re_se_hat);
+ if (!n)
+ return REG_ESPACE;
+ append = n;
+ goto append_node;
+ }
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '$':
+ {
+ if ( /* If at end of pattern, it's an operator. */
+ p == pend
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's next. */
+ || at_endline_loc_p (p, pend, syntax))
+ {
+ struct rexp_node * n
+ = rx_mk_r_side_effect (&rxb->rx, (rx_side_effect)re_se_dollar);
+ if (!n)
+ return REG_ESPACE;
+ append = n;
+ goto append_node;
+ }
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '+':
+ case '?':
+ if ((syntax & RE_BK_PLUS_QM)
+ || (syntax & RE_LIMITED_OPS))
+ goto normal_char;
+
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern... */
+ if (pointless_if_repeated (*last_expression, params))
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ return REG_BADRPT;
+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+
+ {
+ /* 1 means zero (many) matches is allowed. */
+ char zero_times_ok = 0, many_times_ok = 0;
+
+ /* If there is a sequence of repetition chars, collapse it
+ down to just one (the right one). We can't combine
+ interval operators with these because of, e.g., `a{2}*',
+ which should only match an even number of `a's. */
+
+ for (;;)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
+
+ if (p == pend)
+ break;
+
+ PATFETCH (c);
+
+ if (c == '*'
+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
+ ;
+
+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
+ {
+ if (p == pend) return REG_EESCAPE;
+
+ PATFETCH (c1);
+ if (!(c1 == '+' || c1 == '?'))
+ {
+ PATUNFETCH;
+ PATUNFETCH;
+ break;
+ }
+
+ c = c1;
+ }
+ else
+ {
+ PATUNFETCH;
+ break;
+ }
+
+ /* If we get here, we found another repeat character. */
+ }
+
+ /* Star, etc. applied to an empty pattern is equivalent
+ to an empty pattern. */
+ if (!last_expression)
+ break;
+
+ /* Now we know whether or not zero matches is allowed
+ * and also whether or not two or more matches is allowed.
+ */
+
+ {
+ struct rexp_node * inner_exp = *last_expression;
+ int need_sync = 0;
+
+ if (many_times_ok
+ && has_non_idempotent_epsilon_path (&rxb->rx,
+ inner_exp, params))
+ {
+ struct rexp_node * pusher
+ = rx_mk_r_side_effect (&rxb->rx,
+ (rx_side_effect)re_se_pushpos);
+ struct rexp_node * checker
+ = rx_mk_r_side_effect (&rxb->rx,
+ (rx_side_effect)re_se_chkpos);
+ struct rexp_node * pushback
+ = rx_mk_r_side_effect (&rxb->rx,
+ (rx_side_effect)re_se_pushback);
+ rx_Bitset cs = rx_cset (&rxb->rx);
+ struct rexp_node * lit_t = rx_mk_r_cset (&rxb->rx, cs);
+ struct rexp_node * fake_state
+ = rx_mk_r_concat (&rxb->rx, pushback, lit_t);
+ struct rexp_node * phase2
+ = rx_mk_r_concat (&rxb->rx, checker, fake_state);
+ struct rexp_node * popper
+ = rx_mk_r_side_effect (&rxb->rx,
+ (rx_side_effect)re_se_poppos);
+ struct rexp_node * star
+ = rx_mk_r_2phase_star (&rxb->rx, inner_exp, phase2);
+ struct rexp_node * a
+ = rx_mk_r_concat (&rxb->rx, pusher, star);
+ struct rexp_node * whole_thing
+ = rx_mk_r_concat (&rxb->rx, a, popper);
+ if (!(pusher && star && pushback && lit_t && fake_state
+ && lit_t && phase2 && checker && popper
+ && a && whole_thing))
+ return REG_ESPACE;
+ RX_bitset_enjoin (cs, 't');
+ *last_expression = whole_thing;
+ }
+ else
+ {
+ struct rexp_node * star =
+ (many_times_ok ? rx_mk_r_star : rx_mk_r_opt)
+ (&rxb->rx, *last_expression);
+ if (!star)
+ return REG_ESPACE;
+ *last_expression = star;
+ need_sync = has_any_se (&rxb->rx, *last_expression);
+ }
+ if (!zero_times_ok)
+ {
+ struct rexp_node * concat
+ = rx_mk_r_concat (&rxb->rx, inner_exp,
+ rx_copy_rexp (&rxb->rx,
+ *last_expression));
+ if (!concat)
+ return REG_ESPACE;
+ *last_expression = concat;
+ }
+ if (need_sync)
+ {
+ int sync_se = paramc;
+ params = (params
+ ? ((struct re_se_params *)
+ realloc (params,
+ sizeof (*params) * (1 + paramc)))
+ : ((struct re_se_params *)
+ malloc (sizeof (*params))));
+ if (!params)
+ return REG_ESPACE;
+ ++paramc;
+ params [sync_se].se = re_se_tv;
+ side = (rx_side_effect)sync_se;
+ goto add_side_effect;
+ }
+ }
+ /* The old regex.c used to optimize `.*\n'.
+ * Maybe rx should too?
+ */
+ }
+ break;
+
+
+ case '.':
+ {
+ rx_Bitset cs = rx_cset (&rxb->rx);
+ struct rexp_node * n = rx_mk_r_cset (&rxb->rx, cs);
+ if (!(cs && n))
+ return REG_ESPACE;
+
+ rx_bitset_universe (rxb->rx.local_cset_size, cs);
+ if (!(rxb->syntax & RE_DOT_NEWLINE))
+ RX_bitset_remove (cs, '\n');
+ if (!(rxb->syntax & RE_DOT_NOT_NULL))
+ RX_bitset_remove (cs, 0);
+
+ append = n;
+ goto append_node;
+ break;
+ }
+
+
+ case '[':
+ if (p == pend) return REG_EBRACK;
+ {
+ boolean had_char_class = false;
+ rx_Bitset cs = rx_cset (&rxb->rx);
+ struct rexp_node * node = rx_mk_r_cset (&rxb->rx, cs);
+ int is_inverted = *p == '^';
+
+ if (!(node && cs))
+ return REG_ESPACE;
+
+ /* This branch of the switch is normally exited with
+ *`goto append_node'
+ */
+ append = node;
+
+ if (is_inverted)
+ p++;
+
+ /* Remember the first position in the bracket expression. */
+ p1 = p;
+
+ /* Read in characters and ranges, setting map bits. */
+ for (;;)
+ {
+ if (p == pend) return REG_EBRACK;
+
+ PATFETCH (c);
+
+ /* \ might escape characters inside [...] and [^...]. */
+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
+ {
+ if (p == pend) return REG_EESCAPE;
+
+ PATFETCH (c1);
+ {
+ rx_Bitset it = inverse_translation (rxb,
+ validate_inv_tr,
+ inverse_translate,
+ translate,
+ c1);
+ rx_bitset_union (rxb->rx.local_cset_size, cs, it);
+ }
+