summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2000-10-02 06:33:59 +0000
committerpeter <peter@FreeBSD.org>2000-10-02 06:33:59 +0000
commit590c411955d6975551ffeaf41d7faf4b26f836d1 (patch)
treec2ec0b150478a3cab9fb18e60d02dedbdc1cfd15 /contrib
parent784ea5066cbea73d04e8ce5783dd0eb842e3ac1f (diff)
downloadFreeBSD-src-590c411955d6975551ffeaf41d7faf4b26f836d1.zip
FreeBSD-src-590c411955d6975551ffeaf41d7faf4b26f836d1.tar.gz
Import cvs-1.11 onto vendor branch.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/cvs/ChangeLog100
-rw-r--r--contrib/cvs/DEVEL-CVS2
-rw-r--r--contrib/cvs/FAQ4
-rw-r--r--contrib/cvs/HACKING2
-rw-r--r--contrib/cvs/INSTALL12
-rw-r--r--contrib/cvs/Makefile.in8
-rw-r--r--contrib/cvs/NEWS19
-rw-r--r--contrib/cvs/README7
-rw-r--r--contrib/cvs/TESTS25
-rw-r--r--contrib/cvs/TODO5
-rw-r--r--contrib/cvs/acconfig.h12
-rw-r--r--contrib/cvs/config.h.in73
-rwxr-xr-xcontrib/cvs/configure2372
-rw-r--r--contrib/cvs/configure.in159
-rw-r--r--contrib/cvs/contrib/ChangeLog17
-rw-r--r--contrib/cvs/contrib/Makefile.in6
-rw-r--r--contrib/cvs/contrib/log.pl11
-rw-r--r--contrib/cvs/contrib/log_accum.pl9
-rw-r--r--contrib/cvs/contrib/sccs2rcs.csh5
-rw-r--r--contrib/cvs/diff/ChangeLog30
-rw-r--r--contrib/cvs/diff/diff.c43
-rw-r--r--contrib/cvs/diff/diff3.c10
-rw-r--r--contrib/cvs/diff/util.c2
-rw-r--r--contrib/cvs/doc/ChangeLog190
-rw-r--r--contrib/cvs/doc/Makefile.in2
-rw-r--r--contrib/cvs/doc/cvs.texinfo772
-rw-r--r--contrib/cvs/doc/cvsclient.texi80
-rwxr-xr-xcontrib/cvs/install-sh1
-rw-r--r--contrib/cvs/lib/ChangeLog43
-rw-r--r--contrib/cvs/lib/Makefile.in11
-rw-r--r--contrib/cvs/lib/getdate.y18
-rw-r--r--contrib/cvs/lib/getline.c46
-rw-r--r--contrib/cvs/lib/getline.h7
-rw-r--r--contrib/cvs/lib/regex.c5981
-rw-r--r--contrib/cvs/lib/regex.h50
-rw-r--r--contrib/cvs/lib/savecwd.c1
-rw-r--r--contrib/cvs/lib/sighandle.c10
-rw-r--r--contrib/cvs/man/ChangeLog34
-rw-r--r--contrib/cvs/man/Makefile.in2
-rw-r--r--contrib/cvs/man/cvs.137
-rw-r--r--contrib/cvs/man/cvsbug.82
-rwxr-xr-xcontrib/cvs/mkinstalldirs1
-rw-r--r--contrib/cvs/src/ChangeLog1101
-rw-r--r--contrib/cvs/src/Makefile.in6
-rw-r--r--contrib/cvs/src/add.c39
-rw-r--r--contrib/cvs/src/admin.c119
-rw-r--r--contrib/cvs/src/checkout.c127
-rw-r--r--contrib/cvs/src/client.c167
-rw-r--r--contrib/cvs/src/client.h1
-rw-r--r--contrib/cvs/src/commit.c179
-rw-r--r--contrib/cvs/src/create_adm.c6
-rw-r--r--contrib/cvs/src/cvs.h16
-rw-r--r--contrib/cvs/src/edit.c23
-rw-r--r--contrib/cvs/src/entries.c5
-rw-r--r--contrib/cvs/src/error.c9
-rw-r--r--contrib/cvs/src/fileattr.c19
-rw-r--r--contrib/cvs/src/filesubr.c9
-rw-r--r--contrib/cvs/src/hardlink.c15
-rw-r--r--contrib/cvs/src/hash.c9
-rw-r--r--contrib/cvs/src/hash.h4
-rw-r--r--contrib/cvs/src/history.c184
-rw-r--r--contrib/cvs/src/ignore.c31
-rw-r--r--contrib/cvs/src/import.c78
-rw-r--r--contrib/cvs/src/lock.c12
-rw-r--r--contrib/cvs/src/log.c249
-rw-r--r--contrib/cvs/src/login.c54
-rw-r--r--contrib/cvs/src/logmsg.c16
-rw-r--r--contrib/cvs/src/main.c94
-rw-r--r--contrib/cvs/src/mkmodules.c38
-rw-r--r--contrib/cvs/src/modules.c202
-rw-r--r--contrib/cvs/src/myndbm.c3
-rw-r--r--contrib/cvs/src/parseinfo.c43
-rw-r--r--contrib/cvs/src/patch.c31
-rw-r--r--contrib/cvs/src/rcs.c851
-rw-r--r--contrib/cvs/src/rcs.h8
-rw-r--r--contrib/cvs/src/recurse.c13
-rw-r--r--contrib/cvs/src/release.c2
-rw-r--r--contrib/cvs/src/remove.c1
-rw-r--r--contrib/cvs/src/repos.c12
-rw-r--r--contrib/cvs/src/root.c69
-rw-r--r--contrib/cvs/src/rtag.c24
-rw-r--r--contrib/cvs/src/run.c12
-rwxr-xr-xcontrib/cvs/src/sanity.sh2034
-rw-r--r--contrib/cvs/src/server.c527
-rw-r--r--contrib/cvs/src/subr.c58
-rw-r--r--contrib/cvs/src/tag.c16
-rw-r--r--contrib/cvs/src/update.c252
-rw-r--r--contrib/cvs/src/vers_ts.c15
-rw-r--r--contrib/cvs/src/version.c48
-rw-r--r--contrib/cvs/src/watch.c1
-rw-r--r--contrib/cvs/src/zlib.c4
91 files changed, 10838 insertions, 6219 deletions
diff --git a/contrib/cvs/ChangeLog b/contrib/cvs/ChangeLog
index 8a97c2f..eaa0aea 100644
--- a/contrib/cvs/ChangeLog
+++ b/contrib/cvs/ChangeLog
@@ -1,3 +1,103 @@
+2000-09-07 Larry Jones <larry.jones@sdrc.com>
+
+ * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@
+ from autoconf.
+
+ * acconfig.h: Copy HAVE_CRYPT, HAVE_GETSPNAM, REGEX_MALLOC, and
+ _REGEX_RE_COMP from config.h.in to here, where they should have
+ been in the first place.
+ * config.h.in: Regenerated.
+
+2000-08-30 Larry Jones <larry.jones@sdrc.com>
+
+ * NEWS: Note additional history enhancements.
+
+2000-08-01 Larry Jones <larry.jones@sdrc.com>
+
+ * configure.in, config.h.in: Add check for getpassphrase (Solaris).
+ * configure: Regenerated.
+
+2000-07-11 Larry Jones <larry.jones@sdrc.com>
+
+ * configure.in, config.h.in: Add checks for mknod() and st_rdev
+ since some systems (notably Plan 9) don't have them.
+ * configure: Regenerated.
+
+2000-07-10 Larry Jones <larry.jones@sdrc.com>
+
+ * NEWS: Note the new "version" command.
+
+2000-07-06 Larry Jones <larry.jones@sdrc.com>
+
+ * NEWS: Note that admin -t works in client/server.
+
+2000-06-19 Larry Jones <larry.jones@sdrc.com>
+
+ * configure.in (AC_DEFINE): Define REGEX_MALLOC and _REGEX_RE_COMP
+ to configure lib/regex.c the way we want without messing with the
+ code.
+ * config.h.in: Ditto.
+ * configure: Regenerated.
+
+2000-05-16 Jim Kingdon <kingdon@redhat.com>
+
+ * TODO (186): Remove paragraph about Eric Raymond's interest.
+ This is still on the future projects on his site, it just seems to
+ brief (and too long ago updated) that I don't really see the need
+ to mention it.
+
+2000-05-05 Larry Jones <larry.jones@sdrc.com>
+
+ * TESTS: Add notes about required tools and where to get them.
+
+2000-05-02 Donald Sharp <sharpd@cisco.com>
+ and Larry Jones <larry.jones@sdrc.com>
+
+ * NEWS: Note history output format change.
+
+2000-02-17 Larry Jones <larry.jones@sdrc.com>
+
+ * NEWS: Note that PreservePermissions is disabled.
+ * configure.in: Don't define PRESERVE_PERMISSIONS_SUPPORT.
+ * configure: Regenerated.
+
+2000-02-01 Larry Jones <larry.jones@sdrc.com>
+
+ * configure.in: Try again to handle systems that need both libsocket
+ and libnsl.
+ * configure: Regenerated.
+
+1999-12-09 Larry Jones <larry.jones@sdrc.com>
+
+ * configure.in: Correctly handle systems that need both libsocket
+ and libnsl.
+ * configure: Regenerated.
+
+1999-12-06 Larry Jones <larry.jones@sdrc.com>
+
+ * configure.in: Update to autoconf 2.13; use new AC_SEARCH_LIBS
+ to handle getspnam, connect, gethostbyname, and crypt correctly;
+ use new AC_FUNC_FNMATCH instead of doing it by hand.
+ * configure: Regenerated with autoconf 2.13.
+
+1999-12-06 Larry Jones <larry.jones@sdrc.com>
+
+ * INSTALL (Tested platforms): Update info.
+
+1999-11-04 Jim Kingdon <http://developer.redhat.com/>
+
+ * README (Installation): Yet another prep.ai.mit.edu -> gnu.org
+ change (can't believe we still haven't gotten them all).
+
+1999-11-04 Karl Fogel <kfogel@red-bean.com>
+
+ * NEWS: added item about anon cvs no longer needing password.
+
+1999-10-28 Larry Jones <larry.jones@sdrc.com>
+
+ * TESTS: Add note about not running as root. Remove note about
+ Solaris sort since sanity.sh was changed to avoid the problem.
+
1999-07-12 Larry Jones <larry.jones@sdrc.com>
* TESTS: Remove suspicion that setting LC_COLLATE has fixed the
diff --git a/contrib/cvs/DEVEL-CVS b/contrib/cvs/DEVEL-CVS
index b91b9ba..803d78c 100644
--- a/contrib/cvs/DEVEL-CVS
+++ b/contrib/cvs/DEVEL-CVS
@@ -6,7 +6,7 @@ development group operates. Also see the HACKING file.
----------------------------------------------------------------------
Charter for the devel-cvs mailing list:
-The CVS Developers' List <devel-cvs@cyclic.com> exists to help people
+The CVS Developers' List <devel-cvs@cvshome.org> exists to help people
with access to the CVS source repository co-ordinate changes, make
releases, and administer the repository.
diff --git a/contrib/cvs/FAQ b/contrib/cvs/FAQ
index 06fe818..7a1b4e8 100644
--- a/contrib/cvs/FAQ
+++ b/contrib/cvs/FAQ
@@ -18,6 +18,9 @@ some time, you are encouraged to double-check them against other
sources like the Cederqvist manual and update the FAQ. If you don't
have such time, take them with a grain of salt or a few.
+Since Feb. 2000 CVS is being maintained by OpenAvenue, Inc. and many of
+the existing resources have been centeralized on http://www.cvshome.org.
+
Category: /, all questions
Category: /
@@ -8554,3 +8557,4 @@ done
The FAQ-O-Matic lives at http://gille.loria.fr:7000/cgi-bin/faqomatic.
The code was written by Jon Howell, and the content by folks from all
over the web.
+ _________________________________________________________________
diff --git a/contrib/cvs/HACKING b/contrib/cvs/HACKING
index aa6029d..a284027 100644
--- a/contrib/cvs/HACKING
+++ b/contrib/cvs/HACKING
@@ -191,7 +191,7 @@ Anyone can add themselves to the following mailing lists:
automatically, daily, by a script which runs "make check"
and "make remotecheck" on the master CVS sources.
To subscribe to devel-cvs, commit-cvs, or test-results, send
-a message to "majordomo@cyclic.com" whose body consists of
+a message to "majordomo@cvshome.org" whose body consists of
"subscribe <list>", where <list> is devel-cvs, commit-cvs or
test-results.
diff --git a/contrib/cvs/INSTALL b/contrib/cvs/INSTALL
index 2400f07..1a1da8c 100644
--- a/contrib/cvs/INSTALL
+++ b/contrib/cvs/INSTALL
@@ -122,7 +122,7 @@ HPPA:
HPPA 1.1 running HP-UX A.09.04 (1.7.1)
HPPA running HP-UX 9.05 (1.9)
HPPA running HP-UX 10.01 (1.7)
- HPPA running HP-UX 10.20 (1.9, 1.9.14)
+ HPPA running HP-UX 10.20 (1.10.7)
NextSTEP 3.3 (1.7)
i386 family:
Solaris 2.4 using gcc (about 1.4A2)
@@ -134,7 +134,7 @@ i386 family:
Linux (kernel 1.2.x) (1.8.86)
Linux (kernel 2.0.x, RedHat 4.2) (1.10)
Linux (kernel 2.0.x, RedHat 5.x) (1.10)
- BSDI 2.0 (1.4.93) (footnote 5)
+ BSDI 4.0 (1.10.7)
FreeBSD 2.1.5-stable (1.8.87)
NextSTEP 3.3 (1.7)
SCO Unix 3.2.4.2, gcc 2.7.2 (1.8.87) (footnote 4)
@@ -168,11 +168,13 @@ MIPS:
SGI running Irix 6.2 using SGI MIPSpro 6.2 and beta 7.2 compilers (1.9)
SGI running Irix-6.2 (1.9.8)
SGI running IRIX 6.4 (1.10)
+ SGI running IRIX 6.5 (1.10.7)
Siemens-Nixdorf RM600 running SINIX-Y (1.6)
PowerPC or RS/6000:
IBM RS/6000 running AIX 3.1 using gcc and cc (1.6.86)
IBM RS/6000 running AIX 3.2.5 (1.8)
IBM RS/6000 running AIX 4.1 (1.9)
+ IBM RS/6000 running AIX 4.3 (1.10.7)
Lynx 2.3.1 120495 (1.6.86) (footnote 9)
Lynx 2.5 (1.9) (footnote 10)
MkLinux DR3 GENERIC #6 (1.10.5.1) (presumably LinuxPPC too)
@@ -182,6 +184,7 @@ SPARC:
Sun SPARCstation running Solaris 2.4 using gcc and cc (about 1.5.91)
Sun SPARC running Solaris 2.5 (1.8.87)
Sun SPARC running Solaris 2.5.1 using gcc 2.7.2.2 (1.9.14)
+ Sun SPARC running Solaris 2.6 (1.10.7)
Sun UltraSPARC running Solaris 2.6 using gcc 2.8.1 (1.10)
NextSTEP 3.3 (1.7)
Sun SPARC running Linux 2.0.17, gcc 2.7.2 (1.8.87)
@@ -198,11 +201,6 @@ VAX:
(footnote 4) Comment out the include of sys/time.h in src/server.c. (1.4.93)
You also may have to make sure TIME_WITH_SYS_TIME is undef'ed.
-(footnote 5) Change /usr/tmp to /var/tmp in src/server.c (2 places) (1.4.93).
- (This should no longer be needed; CVS doesn't have /usr/tmp in
- src/server.c any more. Has anyone tried a more recent version
- on BSDI? If so, please report it so we can update this file).
-
(footnote 6) Build in ucb universe with COFF compiler tools. Put
/usr/local/bin first in PATH while doing a configure, make
and install of GNU diffutils-2.7, rcs-5.7, then cvs-1.5.
diff --git a/contrib/cvs/Makefile.in b/contrib/cvs/Makefile.in
index dfced91..f8384e1 100644
--- a/contrib/cvs/Makefile.in
+++ b/contrib/cvs/Makefile.in
@@ -50,16 +50,16 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
# Where to install the executables.
-bindir = $(exec_prefix)/bin
+bindir = @bindir@
# Where to put the system-wide .cvsrc file
-libdir = $(prefix)/lib
+libdir = @libdir@
# Where to put the Info files
-infodir = $(prefix)/info
+infodir = @infodir@
# Where to put the manual pages.
-mandir = $(prefix)/man
+mandir = @mandir@
#### End of system configuration section. ####
diff --git a/contrib/cvs/NEWS b/contrib/cvs/NEWS
index 05506ef..cd5ad87 100644
--- a/contrib/cvs/NEWS
+++ b/contrib/cvs/NEWS
@@ -1,5 +1,24 @@
Changes since 1.10:
+* The new "cvs version" command gives a short version message. If
+the repository is remote, both the client and server versions are
+reported.
+
+* "cvs admin -t" now works correctly in client/server mode.
+
+* The "cvs history" command output format has changed -- the date
+now includes the year and is given is ISO 8601 format (yyyy-mm-dd).
+Also, the new LogHistory option in CVSROOT/config can be used to
+control what information gets recorded in the log file and code has
+been added to record file removals.
+
+* The buggy PreservePermissions code has been disabled.
+
+* Anonymous read-only access can now be done without requiring a
+password. On the server side, simply give that user (presumably
+`anonymous') an empty password in the CVSROOT/passwd file, and then
+any received password will authenticate successfully.
+
* There is a new access method :fork: which is similar to :local:
except that it is implemented via the CVS remote protocol, and thus
has a somewhat different set of quirks and bugs.
diff --git a/contrib/cvs/README b/contrib/cvs/README
index e6c436b..cde5be6 100644
--- a/contrib/cvs/README
+++ b/contrib/cvs/README
@@ -97,9 +97,12 @@ versions of CVS?
On the web, http://www.loria.fr/~molli/cvs-index.html.
-The mailing list for CVS is info-cvs@prep.ai.mit.edu. Send
+See also
+ http://www.cvshome.org
+
+The mailing list for CVS is info-cvs@gnu.org. Send
subscription and removal requests for that list to
-info-cvs-request@prep.ai.mit.edu.
+info-cvs-request@gnu.org.
The newsgroup for CVS (and other configuration management systems) is
comp.software.config-mgmt. There is not yet a CVS-specific newsgroup,
diff --git a/contrib/cvs/TESTS b/contrib/cvs/TESTS
index c27f970..bde8d1f 100644
--- a/contrib/cvs/TESTS
+++ b/contrib/cvs/TESTS
@@ -8,6 +8,8 @@ pathname of a shell which handles normal shell functions:
$ make SHELL=/bin/sh5 check
+Also note that you must be logged in as a regular user, not root.
+
WARNING: This test can take quite a while to run, esp. if your
disks are slow or over-loaded.
@@ -16,13 +18,22 @@ If for some reason you want them to work in a different directory, you
can set the TESTDIR environment variable to the desired location
before running them.
-You will probably need GNU expr, which is part of the GNU sh-utils
-package. This is just for running the tests; CVS itself doesn't
-require expr.
-
-With CVS 1.10 people also had trouble with the Solaris sort program
-not behaving the way that the testsuite expects (with Solaris, lines
-starting with tabs sort before blank lines).
+The tests use a number of tools (awk, expr, id, tr, etc.) that are not
+required for running CVS itself. In most cases, the standard vendor-
+supplied versions of these tools work just fine, but there are some
+exceptions -- expr in particular is heavily used and many vendor
+versions are deficient in one way or another. Note that some vendors
+provide multiple versions of tools (typically an ancient, traditional
+version and a new, standards-conforming version), so you may already
+have a usable version even if the default version isn't. If you don't
+have a suitable tool, you can probably get one from the GNU Project (see
+http://www.gnu.org). expr and id are both part of the GNU shellutils
+package, tr is part of the GNU textutils package, and awk is part of the
+GNU gawk package. The test script tries to verify that the tools exist
+and are usable; if not, it tries to find the GNU versions and use them
+instead. If it can't find the GNU versions either, it will print an
+error message and, depending on the severity of the deficiency, it may
+exit.
If there is some unexpected output, that is a failure which can be
somewhat hard to track down. Finding out which test is producing the
diff --git a/contrib/cvs/TODO b/contrib/cvs/TODO
index 91313a3..06d1ebc 100644
--- a/contrib/cvs/TODO
+++ b/contrib/cvs/TODO
@@ -515,11 +515,6 @@ merges from one branch to the other happen automatically (for example,
the case in which the branches have not diverged). This might be a
legitimate question to ask even quite aside from multisite features.
-One additional random tidbit is to note that Eric Raymond has some
-interest in this sort of thing. The item "Cooperative distributed
-freeware development" on http://www.ccil.org/~esr/ has a very brief
-introduction to what he is thinking about.
-
187. Might want to separate out usage error messages and help
messages. The problem now is that if you specify an invalid option,
for example, the error message is lost among all the help text. In
diff --git a/contrib/cvs/acconfig.h b/contrib/cvs/acconfig.h
index 7748e28..15589e8 100644
--- a/contrib/cvs/acconfig.h
+++ b/contrib/cvs/acconfig.h
@@ -43,3 +43,15 @@
/* Define if the diff library should use setmode for binary files.
FIXME: Why two different macros for setmode? */
#undef HAVE_SETMODE
+
+/* Define if you have the crypt function. */
+#undef HAVE_CRYPT
+
+/* Define if you have the getspnam function. */
+#undef HAVE_GETSPNAM
+
+/* Define to force lib/regex.c to use malloc instead of alloca. */
+#undef REGEX_MALLOC
+
+/* Define to force lib/regex.c to define re_comp et al. */
+#undef _REGEX_RE_COMP
diff --git a/contrib/cvs/config.h.in b/contrib/cvs/config.h.in
index 1280d2e..438b798 100644
--- a/contrib/cvs/config.h.in
+++ b/contrib/cvs/config.h.in
@@ -16,12 +16,18 @@
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
+/* Define if your system has a working fnmatch function. */
+#undef HAVE_FNMATCH
+
/* Define if you support file names longer than 14 characters. */
#undef HAVE_LONG_FILE_NAMES
/* Define if your struct stat has st_blksize. */
#undef HAVE_ST_BLKSIZE
+/* Define if your struct stat has st_rdev. */
+#undef HAVE_ST_RDEV
+
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
@@ -94,9 +100,6 @@
/* Define if you have the connect function. */
#undef HAVE_CONNECT
-/* Define if this system supports chown(), link(), and friends. */
-#undef PRESERVE_PERMISSIONS_SUPPORT
-
/* Define if you have memchr (always for CVS). */
#undef HAVE_MEMCHR
@@ -117,6 +120,18 @@
/* Define if you have the crypt function. */
#undef HAVE_CRYPT
+/* Define if you have the getspnam function. */
+#undef HAVE_GETSPNAM
+
+/* Define to force lib/regex.c to use malloc instead of alloca. */
+#undef REGEX_MALLOC
+
+/* Define to force lib/regex.c to define re_comp et al. */
+#undef _REGEX_RE_COMP
+
+/* Define if you have the dup2 function. */
+#undef HAVE_DUP2
+
/* Define if you have the fchdir function. */
#undef HAVE_FCHDIR
@@ -135,8 +150,8 @@
/* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE
-/* Define if you have the getspnam function. */
-#undef HAVE_GETSPNAM
+/* Define if you have the getpassphrase function. */
+#undef HAVE_GETPASSPHRASE
/* Define if you have the initgroups function. */
#undef HAVE_INITGROUPS
@@ -144,6 +159,15 @@
/* Define if you have the krb_get_err_text function. */
#undef HAVE_KRB_GET_ERR_TEXT
+/* Define if you have the memmove function. */
+#undef HAVE_MEMMOVE
+
+/* Define if you have the mkdir function. */
+#undef HAVE_MKDIR
+
+/* Define if you have the mknod function. */
+#undef HAVE_MKNOD
+
/* Define if you have the mktemp function. */
#undef HAVE_MKTEMP
@@ -153,6 +177,9 @@
/* Define if you have the readlink function. */
#undef HAVE_READLINK
+/* Define if you have the rename function. */
+#undef HAVE_RENAME
+
/* Define if you have the sigaction function. */
#undef HAVE_SIGACTION
@@ -168,6 +195,15 @@
/* Define if you have the sigvec function. */
#undef HAVE_SIGVEC
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the strstr function. */
+#undef HAVE_STRSTR
+
+/* Define if you have the strtoul function. */
+#undef HAVE_STRTOUL
+
/* Define if you have the tempnam function. */
#undef HAVE_TEMPNAM
@@ -177,12 +213,18 @@
/* Define if you have the tzset function. */
#undef HAVE_TZSET
+/* Define if you have the valloc function. */
+#undef HAVE_VALLOC
+
/* Define if you have the vprintf function. */
#undef HAVE_VPRINTF
/* Define if you have the wait3 function. */
#undef HAVE_WAIT3
+/* Define if you have the waitpid function. */
+#undef HAVE_WAITPID
+
/* Define if you have the <direct.h> header file. */
#undef HAVE_DIRECT_H
@@ -207,6 +249,9 @@
/* Define if you have the <io.h> header file. */
#undef HAVE_IO_H
+/* Define if you have the <krb5.h> header file. */
+#undef HAVE_KRB5_H
+
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
@@ -255,23 +300,5 @@
/* Define if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
-/* Define if you have the crypt library (-lcrypt). */
-#undef HAVE_LIBCRYPT
-
/* Define if you have the gen library (-lgen). */
#undef HAVE_LIBGEN
-
-/* Define if you have the inet library (-linet). */
-#undef HAVE_LIBINET
-
-/* Define if you have the nsl library (-lnsl). */
-#undef HAVE_LIBNSL
-
-/* Define if you have the nsl_s library (-lnsl_s). */
-#undef HAVE_LIBNSL_S
-
-/* Define if you have the sec library (-lsec). */
-#undef HAVE_LIBSEC
-
-/* Define if you have the socket library (-lsocket). */
-#undef HAVE_LIBSOCKET
diff --git a/contrib/cvs/configure b/contrib/cvs/configure
index 340c7ee..f1ead55 100755
--- a/contrib/cvs/configure
+++ b/contrib/cvs/configure
@@ -1,7 +1,7 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.10
+# Generated automatically using autoconf version 2.13
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
@@ -61,6 +61,9 @@ mandir='${prefix}/man'
# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
ac_prev=
for ac_option
@@ -342,7 +345,7 @@ EOF
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.10"
+ echo "configure generated by autoconf version 2.13"
exit 0 ;;
-with-* | --with-*)
@@ -444,11 +447,14 @@ do
done
# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
@@ -509,8 +515,11 @@ ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+ac_exeext=
+ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
@@ -525,18 +534,97 @@ fi
+if test "x$prefix" = xNONE; then
+echo $ac_n "checking for prefix by $ac_c" 1>&6
+# Extract the first word of "cvs", so it can be a program name with args.
+set dummy cvs; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:543: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_CVS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$CVS" in
+ /*)
+ ac_cv_path_CVS="$CVS" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_CVS="$CVS" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_CVS="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+CVS="$ac_cv_path_CVS"
+if test -n "$CVS"; then
+ echo "$ac_t""$CVS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -n "$ac_cv_path_CVS"; then
+ prefix=`echo $ac_cv_path_CVS|sed 's%/[^/][^/]*//*[^/][^/]*$%%'`
+ fi
+fi
+
+
+
+for ac_prog in mawk gawk nawk awk
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:587: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AWK="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+ echo "$ac_t""$AWK" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AWK" && break
+done
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:619: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="gcc"
@@ -557,15 +645,17 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:649: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
@@ -600,346 +690,150 @@ else
echo "$ac_t""no" 1>&6
fi
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:616: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
-else
- ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
- if test "${CFLAGS+set}" != set; then
- echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:700: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_gcc_g=yes
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
else
- ac_cv_prog_gcc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
- if test $ac_cv_prog_gcc_g = yes; then
- CFLAGS="-g -O"
- else
- CFLAGS="-O"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
fi
- fi
-else
- GCC=
- test "${CFLAGS+set}" = set || CFLAGS="-g"
-fi
-
-
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 669 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:675: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 684 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:690: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
+ done
+ IFS="$ac_save_ifs"
fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
fi
- CPP="$ac_cv_prog_CPP"
-else
- ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
-echo $ac_n "checking for AIX""... $ac_c" 1>&6
-cat > conftest.$ac_ext <<EOF
-#line 712 "configure"
-#include "confdefs.h"
-#ifdef _AIX
- yes
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "yes" >/dev/null 2>&1; then
- rm -rf conftest*
- echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF
-#define _ALL_SOURCE 1
-EOF
-
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
else
- rm -rf conftest*
echo "$ac_t""no" 1>&6
fi
-rm -f conftest*
-
-
-ac_safe=`echo "minix/config.h" | tr './\055' '___'`
-echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 739 "configure"
-#include "confdefs.h"
-#include <minix/config.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:744: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- MINIX=yes
-else
- echo "$ac_t""no" 1>&6
-MINIX=
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
fi
-if test "$MINIX" = yes; then
- cat >> confdefs.h <<\EOF
-#define _POSIX_SOURCE 1
-EOF
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:732: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
- cat >> confdefs.h <<\EOF
-#define _POSIX_1_SOURCE 2
-EOF
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
- cat >> confdefs.h <<\EOF
-#define _MINIX 1
-EOF
+cat > conftest.$ac_ext << EOF
-fi
+#line 743 "configure"
+#include "confdefs.h"
-echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
-if test -d /etc/conf/kconfig.d &&
- grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
-then
- echo "$ac_t""yes" 1>&6
- ISC=yes # If later tests want to check for ISC.
- cat >> confdefs.h <<\EOF
-#define _POSIX_SOURCE 1
+main(){return(0);}
EOF
-
- if test "$GCC" = yes; then
- CC="$CC -posix"
+if { (eval echo configure:748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
else
- CC="$CC -Xp"
+ ac_cv_prog_cc_cross=yes
fi
else
- echo "$ac_t""no" 1>&6
- ISC=
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
-if test "$ISC" = yes; then
-CFLAGS="$CFLAGS -D_SYSV3"
-LIBS="-lcrypt $LIBS"
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:774: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
-if test "x$prefix" = xNONE; then
-echo $ac_n "checking for prefix by ""... $ac_c" 1>&6
-# Extract the first word of "cvs", so it can be a program name with args.
-set dummy cvs; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_path_CVS'+set}'`\" = set"; then
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:779: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- case "$CVS" in
- /*)
- ac_cv_path_CVS="$CVS" # Let the user override the test with a path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_path_CVS="$ac_dir/$ac_word"
- break
- fi
- done
- IFS="$ac_save_ifs"
- ;;
-esac
-fi
-CVS="$ac_cv_path_CVS"
-if test -n "$CVS"; then
- echo "$ac_t""$CVS" 1>&6
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:788: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
else
- echo "$ac_t""no" 1>&6
+ ac_cv_prog_gcc=no
fi
-
- if test -n "$ac_cv_path_CVS"; then
- prefix=`echo $ac_cv_path_CVS|sed 's%/[^/][^/]*//*[^/][^/]*$%%'`
- fi
fi
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-# If we cannot run a trivial program, we must be cross compiling.
-echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_c_cross=yes
-else
-cat > conftest.$ac_ext <<EOF
-#line 851 "configure"
-#include "confdefs.h"
-main(){return(0);}
-EOF
-{ (eval echo configure:855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- ac_cv_c_cross=no
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
else
- ac_cv_c_cross=yes
-fi
-fi
-rm -fr conftest*
+ GCC=
fi
-echo "$ac_t""$ac_cv_c_cross" 1>&6
-cross_compiling=$ac_cv_c_cross
-
-
-echo $ac_n "checking for working const""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:807: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- cat > conftest.$ac_ext <<EOF
-#line 874 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-
-/* Ultrix mips cc rejects this. */
-typedef int charset[2]; const charset x;
-/* SunOS 4.1.1 cc rejects this. */
-char const *const *ccp;
-char **p;
-/* NEC SVR4.0.2 mips cc rejects this. */
-struct point {int x, y;};
-static struct point const zero = {0,0};
-/* AIX XL C 1.02.0.0 rejects this.
- It does not let you subtract one const X* pointer from another in an arm
- of an if-expression whose if-part is not a constant expression */
-const char *g = "string";
-ccp = &g + (g ? g-g : 0);
-/* HPUX 7.0 cc rejects these. */
-++ccp;
-p = (char**) ccp;
-ccp = (char const *const *) p;
-{ /* SCO 3.2v4 cc rejects this. */
- char *t;
- char const *s = 0 ? (char *) 0 : (char const *) 0;
-
- *t++ = 0;
-}
-{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
- int x[] = {25, 17};
- const int *foo = &x[0];
- ++foo;
-}
-{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
- typedef const int *iptr;
- iptr p = 0;
- ++p;
-}
-{ /* AIX XL C 1.02.0.0 rejects this saying
- "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
- struct s { int j; const int *ap[3]; };
- struct s *b; b->j = 5;
-}
-{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
- const int foo = 10;
-}
-
-; return 0; }
-EOF
-if { (eval echo configure:924: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_c_const=yes
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
else
- rm -rf conftest*
- ac_cv_c_const=no
+ ac_cv_prog_cc_g=no
fi
rm -f conftest*
fi
-echo "$ac_t""$ac_cv_c_const" 1>&6
-if test $ac_cv_c_const = no; then
- cat >> confdefs.h <<\EOF
-#define const
-EOF
-
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
fi
-
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
if test -f $ac_dir/install-sh; then
@@ -966,27 +860,30 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:869: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
for ac_dir in $PATH; do
# Account for people who put trailing slashes in PATH elements.
case "$ac_dir/" in
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
- for ac_prog in ginstall installbsd scoinst install; do
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
if test -f $ac_dir/$ac_prog; then
if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
- # OSF/1 installbsd also uses dspmsg, but is usable.
:
else
ac_cv_path_install="$ac_dir/$ac_prog -c"
@@ -997,7 +894,7 @@ else
;;
esac
done
- IFS="$ac_save_ifs"
+ IFS="$ac_save_IFS"
fi
if test "${ac_cv_path_install+set}" = set; then
@@ -1016,19 +913,50 @@ echo "$ac_t""$INSTALL" 1>&6
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:922: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:951: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$RANLIB"; then
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_RANLIB="ranlib"
@@ -1051,14 +979,16 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:983: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$YACC"; then
ac_cv_prog_YACC="$YACC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_YACC="$ac_prog"
@@ -1079,36 +1009,11 @@ test -n "$YACC" && break
done
test -n "$YACC" || YACC="yacc"
-echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-set dummy ${MAKE-make}; ac_make=$2
-if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftestmake <<\EOF
-all:
- @echo 'ac_maketemp="${MAKE}"'
-EOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
-if test -n "$ac_maketemp"; then
- eval ac_cv_prog_make_${ac_make}_set=yes
-else
- eval ac_cv_prog_make_${ac_make}_set=no
-fi
-rm -f conftestmake
-fi
-if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- SET_MAKE=
-else
- echo "$ac_t""no" 1>&6
- SET_MAKE="MAKE=${MAKE-make}"
-fi
-
# Extract the first word of "perl", so it can be a program name with args.
set dummy perl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1017: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_perl_path'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1116,9 +1021,13 @@ else
/*)
ac_cv_path_perl_path="$perl_path" # Let the user override the test with a path.
;;
+ ?:/*)
+ ac_cv_path_perl_path="$perl_path" # Let the user override the test with a dos path.
+ ;;
*)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_path_perl_path="$ac_dir/$ac_word"
@@ -1140,6 +1049,7 @@ fi
# Extract the first word of "csh", so it can be a program name with args.
set dummy csh; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1053: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_csh_path'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1147,9 +1057,13 @@ else
/*)
ac_cv_path_csh_path="$csh_path" # Let the user override the test with a path.
;;
+ ?:/*)
+ ac_cv_path_csh_path="$csh_path" # Let the user override the test with a dos path.
+ ;;
*)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_path_csh_path="$ac_dir/$ac_word"
@@ -1172,6 +1086,7 @@ fi
# Pull the hash mark out of the macro call to avoid m4 problems.
ac_msg="whether #! works in shell scripts"
echo $ac_n "checking $ac_msg""... $ac_c" 1>&6
+echo "configure:1090: checking $ac_msg" >&5
if eval "test \"`echo '$''{'ac_cv_sys_interpreter'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1189,6 +1104,7 @@ rm -f conftest
fi
echo "$ac_t""$ac_cv_sys_interpreter" 1>&6
+interpval="$ac_cv_sys_interpreter"
if test X"$ac_cv_sys_interpreter" != X"yes" ; then
# silly trick to avoid problems in AC macros...
@@ -1196,12 +1112,317 @@ if test X"$ac_cv_sys_interpreter" != X"yes" ; then
echo "configure: warning: $ac_msg" 1>&2
fi
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1117: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1132 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1138: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1149 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1155: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1166 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for AIX""... $ac_c" 1>&6
+echo "configure:1197: checking for AIX" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1199 "configure"
+#include "confdefs.h"
+#ifdef _AIX
+ yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF
+#define _ALL_SOURCE 1
+EOF
+
+else
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
+
+ac_safe=`echo "minix/config.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6
+echo "configure:1222: checking for minix/config.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1227 "configure"
+#include "confdefs.h"
+#include <minix/config.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1232: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ MINIX=yes
+else
+ echo "$ac_t""no" 1>&6
+MINIX=
+fi
+
+if test "$MINIX" = yes; then
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define _POSIX_1_SOURCE 2
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define _MINIX 1
+EOF
+
+fi
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:1270: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+if test "$ISC" = yes; then
+CFLAGS="$CFLAGS -D_SYSV3"
+LIBS="-lcrypt $LIBS"
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:1300: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1305 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:1313: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:1338: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1346 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1357: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:1379: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1387 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1398: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1421: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1205 "configure"
+#line 1426 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1209,13 +1430,15 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1213: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1434: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
ac_cv_header_stdc=yes
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_header_stdc=no
fi
@@ -1224,7 +1447,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1228 "configure"
+#line 1451 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1242,7 +1465,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1246 "configure"
+#line 1469 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1262,8 +1485,8 @@ if test $ac_cv_header_stdc = yes; then
if test "$cross_compiling" = yes; then
:
else
-cat > conftest.$ac_ext <<EOF
-#line 1267 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1490 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1274,15 +1497,19 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-{ (eval echo configure:1278: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1501: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_header_stdc=no
fi
-fi
rm -fr conftest*
fi
+
+fi
fi
echo "$ac_t""$ac_cv_header_stdc" 1>&6
@@ -1293,52 +1520,13 @@ EOF
fi
-for ac_hdr in errno.h unistd.h string.h memory.h utime.h fcntl.h ndbm.h \
- limits.h sys/file.h \
- sys/param.h sys/select.h sys/time.h sys/timeb.h \
- io.h direct.h sys/bsdtypes.h sys/resource.h
-do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1308 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1313: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:1525: checking for sys/wait.h that is POSIX.1 compatible" >&5
if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1342 "configure"
+#line 1530 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
@@ -1348,22 +1536,22 @@ else
#ifndef WIFEXITED
#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
-int main() { return 0; }
-int t() {
+int main() {
int s;
wait (&s);
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
-if { (eval echo configure:1359: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1546: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_header_sys_wait_h=no
fi
rm -f conftest*
-
fi
echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
@@ -1374,12 +1562,56 @@ EOF
fi
+for ac_hdr in errno.h unistd.h string.h memory.h utime.h fcntl.h ndbm.h \
+ limits.h sys/file.h \
+ sys/param.h sys/select.h sys/time.h sys/timeb.h \
+ io.h direct.h sys/bsdtypes.h sys/resource.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1573: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1578 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1583: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
+echo "configure:1610: checking whether stat file-mode macros are broken" >&5
if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1383 "configure"
+#line 1615 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -1430,29 +1662,30 @@ EOF
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1666: checking whether time.h and sys/time.h may both be included" >&5
if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1438 "configure"
+#line 1671 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
-int main() { return 0; }
-int t() {
+int main() {
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1448: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1680: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_header_time=no
fi
rm -f conftest*
-
fi
echo "$ac_t""$ac_cv_header_time" 1>&6
@@ -1463,172 +1696,89 @@ EOF
fi
-ac_header_dirent=no
-for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
-do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1476 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <$ac_hdr>
-int main() { return 0; }
-int t() {
-DIR *dirp = 0;
-; return 0; }
-EOF
-if { (eval echo configure:1485: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- eval "ac_cv_header_dirent_$ac_safe=yes"
-else
- rm -rf conftest*
- eval "ac_cv_header_dirent_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdedfghijklmnopqrstuvwxyz./\055' 'ABCDEDFGHIJKLMNOPQRSTUVWXYZ___'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
- ac_header_dirent=$ac_hdr; break
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
-if test $ac_header_dirent = dirent.h; then
-echo $ac_n "checking for -ldir""... $ac_c" 1>&6
-ac_lib_var=`echo dir'_'opendir | tr './+\055' '__p_'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1702: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- ac_save_LIBS="$LIBS"
-LIBS="-ldir $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1516 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 1707 "configure"
#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char opendir();
-int main() { return 0; }
-int t() {
-opendir()
-; return 0; }
-EOF
-if { (eval echo configure:1528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
+int main() {
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- LIBS="$LIBS -ldir"
-else
- echo "$ac_t""no" 1>&6
-fi
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
-else
-echo $ac_n "checking for -lx""... $ac_c" 1>&6
-ac_lib_var=`echo x'_'opendir | tr './+\055' '__p_'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lx $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1555 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char opendir();
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
-int main() { return 0; }
-int t() {
-opendir()
; return 0; }
EOF
-if { (eval echo configure:1567: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:1756: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
+ ac_cv_c_const=yes
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
+ ac_cv_c_const=no
fi
rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- LIBS="$LIBS -lx"
-else
- echo "$ac_t""no" 1>&6
-fi
-
fi
-echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1592 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <signal.h>
-#ifdef signal
-#undef signal
-#endif
-#ifdef __cplusplus
-extern "C" void (*signal (int, void (*)(int)))(int);
-#else
-void (*signal ()) ();
-#endif
-
-int main() { return 0; }
-int t() {
-int i;
-; return 0; }
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
EOF
-if { (eval echo configure:1610: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_type_signal=void
-else
- rm -rf conftest*
- ac_cv_type_signal=int
-fi
-rm -f conftest*
fi
-echo "$ac_t""$ac_cv_type_signal" 1>&6
-cat >> confdefs.h <<EOF
-#define RETSIGTYPE $ac_cv_type_signal
-EOF
-
-
echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:1777: checking for uid_t in sys/types.h" >&5
if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1632 "configure"
+#line 1782 "configure"
#include "confdefs.h"
#include <sys/types.h>
EOF
@@ -1657,19 +1807,21 @@ EOF
fi
echo $ac_n "checking for mode_t""... $ac_c" 1>&6
+echo "configure:1811: checking for mode_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1665 "configure"
+#line 1816 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
#include <stdlib.h>
+#include <stddef.h>
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "mode_t" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_mode_t=yes
else
@@ -1687,20 +1839,55 @@ EOF
fi
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:1844: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1849 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1877: checking for size_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1696 "configure"
+#line 1882 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
#include <stdlib.h>
+#include <stddef.h>
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "size_t" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_size_t=yes
else
@@ -1718,60 +1905,72 @@ EOF
fi
-echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:1910: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1727 "configure"
+#line 1915 "configure"
#include "confdefs.h"
#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "pid_t" >/dev/null 2>&1; then
+if { (eval echo configure:1932: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
- ac_cv_type_pid_t=yes
+ ac_cv_type_signal=void
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- ac_cv_type_pid_t=no
+ ac_cv_type_signal=int
fi
rm -f conftest*
-
fi
-echo "$ac_t""$ac_cv_type_pid_t" 1>&6
-if test $ac_cv_type_pid_t = no; then
- cat >> confdefs.h <<\EOF
-#define pid_t int
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
EOF
-fi
+
echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6
+echo "configure:1952: checking for st_blksize in struct stat" >&5
if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1758 "configure"
+#line 1957 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
-int main() { return 0; }
-int t() {
+int main() {
struct stat s; s.st_blksize;
; return 0; }
EOF
-if { (eval echo configure:1767: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1965: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_st_blksize=yes
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_struct_st_blksize=no
fi
rm -f conftest*
-
fi
echo "$ac_t""$ac_cv_struct_st_blksize" 1>&6
@@ -1782,14 +1981,49 @@ EOF
fi
+echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
+echo "configure:1986: checking for st_rdev in struct stat" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1991 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+int main() {
+struct stat s; s.st_rdev;
+; return 0; }
+EOF
+if { (eval echo configure:1999: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_st_rdev=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_st_rdev=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_st_rdev" 1>&6
+if test $ac_cv_struct_st_rdev = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ST_RDEV 1
+EOF
+
+fi
+
for ac_func in mkdir rename strstr dup2 strerror valloc waitpid memmove strtoul
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2022: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1793 "configure"
+#line 2027 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1799,8 +2033,7 @@ else
builtin and then its argument prototype would still apply. */
char $ac_func();
-int main() { return 0; }
-int t() {
+int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
@@ -1813,34 +2046,41 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1817: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2050: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
-
fi
+
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
- :
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
else
echo "$ac_t""no" 1>&6
-LIBOBJS="$LIBOBJS ${ac_func}.o"
+LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}"
fi
-
done
-for ac_func in fchmod fsync ftime mktemp putenv vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam tzset readlink wait3
+
+for ac_func in fchmod fsync ftime mktemp putenv vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam tzset readlink wait3 mknod getpassphrase
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2079: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1844 "configure"
+#line 2084 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -1850,8 +2090,7 @@ else
builtin and then its argument prototype would still apply. */
char $ac_func();
-int main() { return 0; }
-int t() {
+int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
@@ -1864,16 +2103,18 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1868: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2107: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
-
fi
+
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
@@ -1896,24 +2137,35 @@ cat >> confdefs.h <<\EOF
EOF
-ac_safe=`echo "vfork.h" | tr './\055' '___'`
+cat >> confdefs.h <<\EOF
+#define REGEX_MALLOC 1
+EOF
+
+cat >> confdefs.h <<\EOF
+#define _REGEX_RE_COMP 1
+EOF
+
+ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
+echo "configure:2151: checking for vfork.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1906 "configure"
+#line 2156 "configure"
#include "confdefs.h"
#include <vfork.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1911: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:2161: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_header_$ac_safe=no"
fi
@@ -1930,16 +2182,18 @@ else
fi
echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
+echo "configure:2186: checking for working vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
echo $ac_n "checking for vfork""... $ac_c" 1>&6
+echo "configure:2192: checking for vfork" >&5
if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1943 "configure"
+#line 2197 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vfork(); below. */
@@ -1949,8 +2203,7 @@ else
builtin and then its argument prototype would still apply. */
char vfork();
-int main() { return 0; }
-int t() {
+int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
@@ -1963,16 +2216,18 @@ vfork();
; return 0; }
EOF
-if { (eval echo configure:1967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_vfork=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_vfork=no"
fi
rm -f conftest*
-
fi
+
if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then
echo "$ac_t""yes" 1>&6
:
@@ -1980,9 +2235,10 @@ else
echo "$ac_t""no" 1>&6
fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
else
-cat > conftest.$ac_ext <<EOF
-#line 1986 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 2242 "configure"
#include "confdefs.h"
/* Thanks to Paul Eggert for this test. */
#include <stdio.h>
@@ -2010,8 +2266,10 @@ sparc_address_test (arg) int arg;
static pid_t child;
if (!child) {
child = vfork ();
- if (child < 0)
+ if (child < 0) {
perror ("vfork");
+ _exit(2);
+ }
if (!child) {
arg = getpid();
write(-1, "", 0);
@@ -2075,18 +2333,22 @@ main() {
}
}
EOF
-{ (eval echo configure:2079: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- ac_cv_func_vfork=yes
+if { (eval echo configure:2337: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_vfork_works=yes
else
- ac_cv_func_vfork=no
-fi
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_vfork_works=no
fi
rm -fr conftest*
fi
-echo "$ac_t""$ac_cv_func_vfork" 1>&6
-if test $ac_cv_func_vfork = no; then
+fi
+
+echo "$ac_t""$ac_cv_func_vfork_works" 1>&6
+if test $ac_cv_func_vfork_works = no; then
cat >> confdefs.h <<\EOF
#define vfork fork
EOF
@@ -2094,29 +2356,34 @@ EOF
fi
echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6
+echo "configure:2360: checking whether closedir returns void" >&5
if eval "test \"`echo '$''{'ac_cv_func_closedir_void'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_func_closedir_void=yes
else
-cat > conftest.$ac_ext <<EOF
-#line 2105 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 2368 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_header_dirent>
int closedir(); main() { exit(closedir(opendir(".")) != 0); }
EOF
-{ (eval echo configure:2111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:2374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
ac_cv_func_closedir_void=no
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_func_closedir_void=yes
fi
-fi
rm -fr conftest*
fi
+fi
+
echo "$ac_t""$ac_cv_func_closedir_void" 1>&6
if test $ac_cv_func_closedir_void = yes; then
cat >> confdefs.h <<\EOF
@@ -2126,105 +2393,74 @@ EOF
fi
-echo $ac_n "checking for -lsec""... $ac_c" 1>&6
-ac_lib_var=`echo sec'_'getspnam | tr './+\055' '__p_'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+
+echo $ac_n "checking for library containing getspnam""... $ac_c" 1>&6
+echo "configure:2399: checking for library containing getspnam" >&5
+if eval "test \"`echo '$''{'ac_cv_search_getspnam'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- ac_save_LIBS="$LIBS"
-LIBS="-lsec $LIBS"
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_getspnam="no"
cat > conftest.$ac_ext <<EOF
-#line 2138 "configure"
+#line 2406 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char getspnam();
-int main() { return 0; }
-int t() {
+int main() {
getspnam()
; return 0; }
EOF
-if { (eval echo configure:2150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2417: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
+ ac_cv_search_getspnam="none required"
else
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo sec | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lsec $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-for ac_func in getspnam
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2181 "configure"
+test "$ac_cv_search_getspnam" = "no" && for i in sec gen; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2428 "configure"
#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
+char getspnam();
+int main() {
+getspnam()
; return 0; }
EOF
-if { (eval echo configure:2205: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
+ ac_cv_search_getspnam="-l$i"
+break
else
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
+done
+LIBS="$ac_func_search_save_LIBS"
fi
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
+
+echo "$ac_t""$ac_cv_search_getspnam" 1>&6
+if test "$ac_cv_search_getspnam" != "no"; then
+ test "$ac_cv_search_getspnam" = "none required" || LIBS="$ac_cv_search_getspnam $LIBS"
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETSPNAM 1
EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
+else :
+
+fi
echo $ac_n "checking whether utime accepts a null argument""... $ac_c" 1>&6
+echo "configure:2464: checking whether utime accepts a null argument" >&5
if eval "test \"`echo '$''{'ac_cv_func_utime_null'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2233,8 +2469,8 @@ else
if test "$cross_compiling" = yes; then
ac_cv_func_utime_null=no
else
-cat > conftest.$ac_ext <<EOF
-#line 2238 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 2474 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -2245,14 +2481,18 @@ exit(!(stat ("conftestdata", &s) == 0 && utime("conftestdata", (long *)0) == 0
&& t.st_mtime - s.st_mtime < 120));
}
EOF
-{ (eval echo configure:2249: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:2485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
ac_cv_func_utime_null=yes
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
ac_cv_func_utime_null=no
fi
-fi
rm -fr conftest*
+fi
+
rm -f core core.* *.core
fi
@@ -2265,19 +2505,27 @@ EOF
fi
echo $ac_n "checking for long file names""... $ac_c" 1>&6
+echo "configure:2509: checking for long file names" >&5
if eval "test \"`echo '$''{'ac_cv_sys_long_file_names'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_sys_long_file_names=yes
# Test for long file names in all the places we know might matter:
# . the current directory, where building will happen
-# /tmp where it might want to write temporary files
-# /var/tmp likewise
-# /usr/tmp likewise
# $prefix/lib where we will be installing things
# $exec_prefix/lib likewise
# eval it to expand exec_prefix.
-for ac_dir in `eval echo . /tmp /var/tmp /usr/tmp $prefix/lib $exec_prefix/lib` ; do
+# $TMPDIR if set, where it might want to write temporary files
+# if $TMPDIR is not set:
+# /tmp where it might want to write temporary files
+# /var/tmp likewise
+# /usr/tmp likewise
+if test -n "$TMPDIR" && test -d "$TMPDIR" && test -w "$TMPDIR"; then
+ ac_tmpdirs="$TMPDIR"
+else
+ ac_tmpdirs='/tmp /var/tmp /usr/tmp'
+fi
+for ac_dir in . $ac_tmpdirs `eval echo $prefix/lib $exec_prefix/lib` ; do
test -d $ac_dir || continue
test -w $ac_dir || continue # It is less confusing to not echo anything here.
(echo 1 > $ac_dir/conftest9012345) 2>/dev/null
@@ -2301,287 +2549,276 @@ EOF
fi
-echo $ac_n "checking for working fnmatch function""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ccvs_cv_sys_working_fnmatch'+set}'`\" = set"; then
+echo $ac_n "checking for working fnmatch""... $ac_c" 1>&6
+echo "configure:2554: checking for working fnmatch" >&5
+if eval "test \"`echo '$''{'ac_cv_func_fnmatch_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- if test "$cross_compiling" = yes; then
- ccvs_cv_sys_working_fnmatch=no
+ # Some versions of Solaris or SCO have a broken fnmatch function.
+# So we run a test program. If we are cross-compiling, take no chance.
+# Thanks to John Oleynick and Franc,ois Pinard for this test.
+if test "$cross_compiling" = yes; then
+ ac_cv_func_fnmatch_works=no
else
-cat > conftest.$ac_ext <<EOF
-#line 2313 "configure"
+ cat > conftest.$ac_ext <<EOF
+#line 2565 "configure"
#include "confdefs.h"
-
-#include <fnmatch.h>
-int
-main ()
-{
- exit ((fnmatch ("a", "a", FNM_PATHNAME) == 0
- && fnmatch ("a", "b", FNM_PATHNAME) == FNM_NOMATCH)
- ? 0 : 1);
-}
+main() { exit (fnmatch ("a*", "abc", 0) != 0); }
EOF
-{ (eval echo configure:2325: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- ccvs_cv_sys_working_fnmatch=yes
+if { (eval echo configure:2569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_fnmatch_works=yes
else
- ccvs_cv_sys_working_fnmatch=no
-fi
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_fnmatch_works=no
fi
rm -fr conftest*
fi
-if test $ccvs_cv_sys_working_fnmatch = no; then
+fi
+
+echo "$ac_t""$ac_cv_func_fnmatch_works" 1>&6
+if test $ac_cv_func_fnmatch_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_FNMATCH 1
+EOF
+
+fi
+
+if test "$ac_cv_func_fnmatch_works" = no; then
LIBOBJS="$LIBOBJS fnmatch.o"
fi
-echo "$ac_t""$ccvs_cv_sys_working_fnmatch" 1>&6
-# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
-# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
-# libsocket.so which has a bad implementation of gethostbyname (it
-# only looks in /etc/hosts), so we only look for -lsocket if we need
-# it.
-echo $ac_n "checking for connect""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
+# Try to find connect and gethostbyname.
+echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
+echo "configure:2597: checking for main in -lnsl" >&5
+ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- cat > conftest.$ac_ext <<EOF
-#line 2350 "configure"
+ ac_save_LIBS="$LIBS"
+LIBS="-lnsl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2605 "configure"
#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char connect(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char connect();
-
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_connect) || defined (__stub___connect)
-choke me
-#else
-connect();
-#endif
+int main() {
+main()
; return 0; }
EOF
-if { (eval echo configure:2374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- eval "ac_cv_func_connect=yes"
+ eval "ac_cv_lib_$ac_lib_var=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- eval "ac_cv_func_connect=no"
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
+LIBS="$ac_save_LIBS"
fi
-if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
- :
-else
- echo "$ac_t""no" 1>&6
-case "$LIBS" in
-*-lnsl*) ;;
-*) echo $ac_n "checking for -lnsl_s""... $ac_c" 1>&6
-ac_lib_var=`echo nsl_s'_'printf | tr './+\055' '__p_'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+
+echo $ac_n "checking for library containing connect""... $ac_c" 1>&6
+echo "configure:2629: checking for library containing connect" >&5
+if eval "test \"`echo '$''{'ac_cv_search_connect'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- ac_save_LIBS="$LIBS"
-LIBS="-lnsl_s $LIBS"
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_connect="no"
cat > conftest.$ac_ext <<EOF
-#line 2399 "configure"
+#line 2636 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
-char printf();
+char connect();
-int main() { return 0; }
-int t() {
-printf()
+int main() {
+connect()
; return 0; }
EOF
-if { (eval echo configure:2411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
+ ac_cv_search_connect="none required"
else
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo nsl_s | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lnsl_s $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
- ;;
-esac
-case "$LIBS" in
-*-lnsl*) ;;
-*) echo $ac_n "checking for -lnsl""... $ac_c" 1>&6
-ac_lib_var=`echo nsl'_'printf | tr './+\055' '__p_'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lnsl $LIBS"
+test "$ac_cv_search_connect" = "no" && for i in xnet socket inet; do
+LIBS="-l$i -lnsl $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2446 "configure"
+#line 2658 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
-char printf();
+char connect();
-int main() { return 0; }
-int t() {
-printf()
+int main() {
+connect()
; return 0; }
EOF
-if { (eval echo configure:2458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2669: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
+ ac_cv_search_connect="-l$i"
+break
else
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-LIBS="$ac_save_LIBS"
-
+done
+LIBS="$ac_func_search_save_LIBS"
fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo nsl | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
- LIBS="-lnsl $LIBS"
+echo "$ac_t""$ac_cv_search_connect" 1>&6
+if test "$ac_cv_search_connect" != "no"; then
+ test "$ac_cv_search_connect" = "none required" || LIBS="$ac_cv_search_connect $LIBS"
+ cat >> confdefs.h <<\EOF
+#define HAVE_CONNECT 1
+EOF
+else :
+
+fi
else
echo "$ac_t""no" 1>&6
-fi
- ;;
-esac
-case "$LIBS" in
-*-lsocket*) ;;
-*) echo $ac_n "checking for -lsocket""... $ac_c" 1>&6
-ac_lib_var=`echo socket'_'connect | tr './+\055' '__p_'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+
+echo $ac_n "checking for library containing connect""... $ac_c" 1>&6
+echo "configure:2696: checking for library containing connect" >&5
+if eval "test \"`echo '$''{'ac_cv_search_connect'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- ac_save_LIBS="$LIBS"
-LIBS="-lsocket $LIBS"
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_connect="no"
cat > conftest.$ac_ext <<EOF
-#line 2493 "configure"
+#line 2703 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char connect();
-int main() { return 0; }
-int t() {
+int main() {
connect()
; return 0; }
EOF
-if { (eval echo configure:2505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
+ ac_cv_search_connect="none required"
else
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-LIBS="$ac_save_LIBS"
+test "$ac_cv_search_connect" = "no" && for i in xnet socket inet; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2725 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect();
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo socket | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
+int main() {
+connect()
+; return 0; }
EOF
+if { (eval echo configure:2736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_connect="-l$i"
+break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
- LIBS="-lsocket $LIBS"
+echo "$ac_t""$ac_cv_search_connect" 1>&6
+if test "$ac_cv_search_connect" != "no"; then
+ test "$ac_cv_search_connect" = "none required" || LIBS="$ac_cv_search_connect $LIBS"
+ cat >> confdefs.h <<\EOF
+#define HAVE_CONNECT 1
+EOF
-else
- echo "$ac_t""no" 1>&6
+else :
+
fi
- ;;
-esac
-case "$LIBS" in
-*-linet*) ;;
-*) echo $ac_n "checking for -linet""... $ac_c" 1>&6
-ac_lib_var=`echo inet'_'connect | tr './+\055' '__p_'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+fi
+
+
+echo $ac_n "checking for library containing gethostbyname""... $ac_c" 1>&6
+echo "configure:2763: checking for library containing gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_search_gethostbyname'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- ac_save_LIBS="$LIBS"
-LIBS="-linet $LIBS"
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_gethostbyname="no"
cat > conftest.$ac_ext <<EOF
-#line 2540 "configure"
+#line 2770 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
-char connect();
+char gethostbyname();
-int main() { return 0; }
-int t() {
-connect()
+int main() {
+gethostbyname()
; return 0; }
EOF
-if { (eval echo configure:2552: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2781: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
+ ac_cv_search_gethostbyname="none required"
else
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-LIBS="$ac_save_LIBS"
+test "$ac_cv_search_gethostbyname" = "no" && for i in netinet nsl; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2792 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo inet | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
+int main() {
+gethostbyname()
+; return 0; }
EOF
-
- LIBS="-linet $LIBS"
-
+if { (eval echo configure:2803: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_search_gethostbyname="-l$i"
+break
else
- echo "$ac_t""no" 1>&6
-fi
- ;;
-esac
-if test "$ac_cv_lib_socket_connect" = "yes" || test "$ac_cv_lib_inet_connect" = "yes"; then
- ac_cv_func_connect=yes
- cat >> confdefs.h <<\EOF
-#define HAVE_CONNECT 1
-EOF
-
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
fi
+echo "$ac_t""$ac_cv_search_gethostbyname" 1>&6
+if test "$ac_cv_search_gethostbyname" != "no"; then
+ test "$ac_cv_search_gethostbyname" = "none required" || LIBS="$ac_cv_search_gethostbyname $LIBS"
+
+else :
+
+fi
KRB4=/usr/kerberos
@@ -2595,98 +2832,102 @@ echo "default place for krb4 is $KRB4"
krb_h=
echo $ac_n "checking for krb.h""... $ac_c" 1>&6
+echo "configure:2836: checking for krb.h" >&5
if test "$cross_compiling" != yes && test -r $KRB4/include/krb.h; then
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -I$KRB4/include"
cat > conftest.$ac_ext <<EOF
-#line 2603 "configure"
+#line 2841 "configure"
#include "confdefs.h"
#include <krb.h>
-int main() { return 0; }
-int t() {
+int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2848: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
krb_h=yes krb_incdir=$KRB4/include
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
CFLAGS=$hold_cflags
cat > conftest.$ac_ext <<EOF
-#line 2618 "configure"
+#line 2857 "configure"
#include "confdefs.h"
#include <krb.h>
-int main() { return 0; }
-int t() {
+int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
krb_h=yes krb_incdir=
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
fi
rm -f conftest*
-
CFLAGS=$hold_cflags
else
cat > conftest.$ac_ext <<EOF
-#line 2638 "configure"
+#line 2877 "configure"
#include "confdefs.h"
#include <krb.h>
-int main() { return 0; }
-int t() {
+int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2646: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
krb_h=yes krb_incdir=
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
fi
if test -z "$krb_h"; then
cat > conftest.$ac_ext <<EOF
-#line 2655 "configure"
+#line 2895 "configure"
#include "confdefs.h"
#include <krb.h>
-int main() { return 0; }
-int t() {
+int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
krb_h=yes krb_incdir=
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
if test "$cross_compiling" != yes && test -r $KRB4/include/kerberosIV/krb.h; then
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -I$KRB4/include/kerberosIV"
cat > conftest.$ac_ext <<EOF
-#line 2672 "configure"
+#line 2913 "configure"
#include "confdefs.h"
#include <krb.h>
-int main() { return 0; }
-int t() {
+int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2920: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
krb_h=yes krb_incdir=$KRB4/include/kerberosIV
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
CFLAGS=$hold_cflags
fi
fi
rm -f conftest*
-
fi
echo "$ac_t""$krb_h" 1>&6
@@ -2697,30 +2938,32 @@ if test -n "$krb_h"; then
if test "$cross_compiling" != yes && test -r $KRB4/lib/libkrb.a; then
hold_ldflags=$LDFLAGS
LDFLAGS="-L${KRB4}/lib $LDFLAGS"
- echo $ac_n "checking for -lkrb""... $ac_c" 1>&6
-ac_lib_var=`echo krb'_'printf | tr './+\055' '__p_'`
+ echo $ac_n "checking for printf in -lkrb""... $ac_c" 1>&6
+echo "configure:2943: checking for printf in -lkrb" >&5
+ac_lib_var=`echo krb'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2709 "configure"
+#line 2951 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char printf();
-int main() { return 0; }
-int t() {
+int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
@@ -2736,30 +2979,32 @@ else
LDFLAGS=$hold_ldflags
# Using open here instead of printf so we don't
# get confused by the cached value for printf from above.
- echo $ac_n "checking for -lkrb""... $ac_c" 1>&6
-ac_lib_var=`echo krb'_'open | tr './+\055' '__p_'`
+ echo $ac_n "checking for open in -lkrb""... $ac_c" 1>&6
+echo "configure:2984: checking for open in -lkrb" >&5
+ac_lib_var=`echo krb'_'open | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2748 "configure"
+#line 2992 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char open();
-int main() { return 0; }
-int t() {
+int main() {
open()
; return 0; }
EOF
-if { (eval echo configure:2760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3003: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
@@ -2778,30 +3023,32 @@ fi
LDFLAGS=$hold_ldflags
else
- echo $ac_n "checking for -lkrb""... $ac_c" 1>&6
-ac_lib_var=`echo krb'_'printf | tr './+\055' '__p_'`
+ echo $ac_n "checking for printf in -lkrb""... $ac_c" 1>&6
+echo "configure:3028: checking for printf in -lkrb" >&5
+ac_lib_var=`echo krb'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2790 "configure"
+#line 3036 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char printf();
-int main() { return 0; }
-int t() {
+int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2802: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3047: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
@@ -2829,30 +3076,32 @@ EOF
# the user's setting for LDFLAGS
hold_ldflags=$LDFLAGS
test -n "${krb_libdir}" && LDFLAGS="$LDFLAGS -L${krb_libdir}"
- echo $ac_n "checking for -ldes""... $ac_c" 1>&6
-ac_lib_var=`echo des'_'printf | tr './+\055' '__p_'`
+ echo $ac_n "checking for printf in -ldes""... $ac_c" 1>&6
+echo "configure:3081: checking for printf in -ldes" >&5
+ac_lib_var=`echo des'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-ldes $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2841 "configure"
+#line 3089 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char printf();
-int main() { return 0; }
-int t() {
+int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2853: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
@@ -2876,11 +3125,12 @@ fi
for ac_func in krb_get_err_text
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3129: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2884 "configure"
+#line 3134 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2890,8 +3140,7 @@ else
builtin and then its argument prototype would still apply. */
char $ac_func();
-int main() { return 0; }
-int t() {
+int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
@@ -2904,16 +3153,18 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
-
fi
+
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
@@ -2941,24 +3192,27 @@ hold_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$GSSAPI/include "
for ac_hdr in krb5.h gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h
do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3198: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2951 "configure"
+#line 3203 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2956: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:3208: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_header_$ac_safe=no"
fi
@@ -2966,7 +3220,7 @@ rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
cat >> confdefs.h <<EOF
#define $ac_tr_hdr 1
EOF
@@ -2996,7 +3250,7 @@ EOF
CPPFLAGS="-I$GSSAPI/include $CPPFLAGS"
if test "$ac_cv_header_gssapi_h" = "yes"; then
cat > conftest.$ac_ext <<EOF
-#line 3000 "configure"
+#line 3254 "configure"
#include "confdefs.h"
#include <gssapi.h>
EOF
@@ -3012,7 +3266,7 @@ rm -f conftest*
else
cat > conftest.$ac_ext <<EOF
-#line 3016 "configure"
+#line 3270 "configure"
#include "confdefs.h"
#include <gssapi/gssapi.h>
EOF
@@ -3030,30 +3284,32 @@ rm -f conftest*
CPPFLAGS=$save_CPPFLAGS
# This is necessary on Irix 5.3, in order to link against libkrb5 --
# there, an_to_ln.o refers to things defined only in -lgen.
- echo $ac_n "checking for -lgen""... $ac_c" 1>&6
-ac_lib_var=`echo gen'_'compile | tr './+\055' '__p_'`
+ echo $ac_n "checking for compile in -lgen""... $ac_c" 1>&6
+echo "configure:3289: checking for compile in -lgen" >&5
+ac_lib_var=`echo gen'_'compile | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lgen $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3042 "configure"
+#line 3297 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char compile();
-int main() { return 0; }
-int t() {
+int main() {
compile()
; return 0; }
EOF
-if { (eval echo configure:3054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3308: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
@@ -3063,7 +3319,8 @@ LIBS="$ac_save_LIBS"
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo gen | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ ac_tr_lib=HAVE_LIB`echo gen | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
cat >> confdefs.h <<EOF
#define $ac_tr_lib 1
EOF
@@ -3096,11 +3353,12 @@ EOF
fi
echo $ac_n "checking for gethostname""... $ac_c" 1>&6
+echo "configure:3357: checking for gethostname" >&5
if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3104 "configure"
+#line 3362 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostname(); below. */
@@ -3110,8 +3368,7 @@ else
builtin and then its argument prototype would still apply. */
char gethostname();
-int main() { return 0; }
-int t() {
+int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
@@ -3124,16 +3381,18 @@ gethostname();
; return 0; }
EOF
-if { (eval echo configure:3128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3385: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_gethostname=yes"
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_gethostname=no"
fi
rm -f conftest*
-
fi
+
if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then
echo "$ac_t""yes" 1>&6
:
@@ -3155,7 +3414,7 @@ EOF
fi
else
- if test "$ac_cv_func_connect" = yes; then
+ if test "$ac_cv_search_connect" != no; then
cat >> confdefs.h <<\EOF
#define CLIENT_SUPPORT 1
EOF
@@ -3173,7 +3432,7 @@ EOF
fi
else
- if test "$ac_cv_func_connect" = yes; then
+ if test "$ac_cv_search_connect" != no; then
cat >> confdefs.h <<\EOF
#define SERVER_SUPPORT 1
EOF
@@ -3183,149 +3442,102 @@ fi
fi
-### The auth server needs to be able to check passwords against passwd
-### file entries, so we only #define AUTH_SERVER_SUPPORT if we can
-### find the crypt function.
-###
-### We used to test for crypt in libc first, and only add -lcrypt if
-### we couldn't find it, but that interacts badly with the cache
-### variables, the 'unset' command isn't portable, and I'm not sure
-### there's any harm in just testing for -lcrypt first.
if test "$enable_server" = yes; then
-echo $ac_n "checking for -lcrypt""... $ac_c" 1>&6
-ac_lib_var=`echo crypt'_'crypt | tr './+\055' '__p_'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+
+echo $ac_n "checking for library containing crypt""... $ac_c" 1>&6
+echo "configure:3450: checking for library containing crypt" >&5
+if eval "test \"`echo '$''{'ac_cv_search_crypt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- ac_save_LIBS="$LIBS"
-LIBS="-lcrypt $LIBS"
+ ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_crypt="no"
cat > conftest.$ac_ext <<EOF
-#line 3205 "configure"
+#line 3457 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char crypt();
-int main() { return 0; }
-int t() {
+int main() {
crypt()
; return 0; }
EOF
-if { (eval echo configure:3217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3468: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
+ ac_cv_search_crypt="none required"
else
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo crypt | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lcrypt $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-for ac_func in crypt
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3248 "configure"
+test "$ac_cv_search_crypt" = "no" && for i in crypt; do
+LIBS="-l$i $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3479 "configure"
#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
+char crypt();
+int main() {
+crypt()
; return 0; }
EOF
-if { (eval echo configure:3272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:3490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
+ ac_cv_search_crypt="-l$i"
+break
else
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
-fi
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
done
+LIBS="$ac_func_search_save_LIBS"
+fi
-
-if test "$ac_cv_func_crypt" = yes; then
+echo "$ac_t""$ac_cv_search_crypt" 1>&6
+if test "$ac_cv_search_crypt" != "no"; then
+ test "$ac_cv_search_crypt" = "none required" || LIBS="$ac_cv_search_crypt $LIBS"
cat >> confdefs.h <<\EOF
+#define HAVE_CRYPT 1
+EOF
+ cat >> confdefs.h <<\EOF
#define AUTH_SERVER_SUPPORT 1
EOF
+else :
+
fi
fi # enable_server
-cat >> confdefs.h <<\EOF
-#define PRESERVE_PERMISSIONS_SUPPORT 1
-EOF
-
echo $ac_n "checking for cygwin32""... $ac_c" 1>&6
+echo "configure:3520: checking for cygwin32" >&5
if eval "test \"`echo '$''{'ccvs_cv_sys_cygwin32'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3313 "configure"
+#line 3525 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() {
+int main() {
return __CYGWIN32__;
; return 0; }
EOF
-if { (eval echo configure:3321: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3532: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ccvs_cv_sys_cygwin32=yes
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
ccvs_cv_sys_cygwin32=no
fi
rm -f conftest*
-
fi
echo "$ac_t""$ccvs_cv_sys_cygwin32" 1>&6
@@ -3372,11 +3584,25 @@ cat > confcache <<\EOF
# --recheck option to rerun configure.
#
EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
- sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
- >> confcache
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
if cmp -s $cache_file confcache; then
:
else
@@ -3431,7 +3657,7 @@ do
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.10"
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
@@ -3456,9 +3682,11 @@ sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
+s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
@@ -3477,16 +3705,18 @@ s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
-s%@CC@%$CC%g
-s%@CPP@%$CPP%g
s%@CVS@%$CVS%g
+s%@AWK@%$AWK%g
+s%@CC@%$CC%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@SET_MAKE@%$SET_MAKE%g
s%@RANLIB@%$RANLIB%g
s%@YACC@%$YACC%g
-s%@SET_MAKE@%$SET_MAKE%g
s%@perl_path@%$perl_path%g
s%@csh_path@%$csh_path%g
+s%@CPP@%$CPP%g
s%@LIBOBJS@%$LIBOBJS%g
s%@KRB4@%$KRB4%g
s%@includeopt@%$includeopt%g
@@ -3494,6 +3724,42 @@ s%@GSSAPI@%$GSSAPI%g
CEOF
EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
cat >> $CONFIG_STATUS <<EOF
CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile src/Makefile zlib/Makefile diff/Makefile doc/Makefile \
@@ -3505,14 +3771,14 @@ CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile src/Makefile zlib/Makefile d
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
- # Adjust relative srcdir, etc. for subdirectories.
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
@@ -3540,6 +3806,7 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
[/$]*) INSTALL="$ac_given_INSTALL" ;;
*) INSTALL="$ac_dots$ac_given_INSTALL" ;;
esac
+
echo creating "$ac_file"
rm -f "$ac_file"
configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
@@ -3548,14 +3815,16 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
# $configure_input" ;;
*) ac_comsub= ;;
esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
s%@INSTALL@%$INSTALL%g
-" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
-rm -f conftest.subs
+rm -f conftest.s*
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
@@ -3576,11 +3845,17 @@ ac_eB='$%\1#\2define\3'
ac_eC=' '
ac_eD='%g'
-CONFIG_HEADERS=${CONFIG_HEADERS-"config.h src/options.h"}
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h src/options.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile]", defaulting infile="outfile.in".
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
@@ -3588,7 +3863,8 @@ for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
echo creating $ac_file
rm -f conftest.frag conftest.in conftest.out
- cp $ac_given_srcdir/$ac_file_in conftest.in
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
EOF
@@ -3616,8 +3892,6 @@ EOF
# Break up conftest.vals because some shells have a limit on
# the size of here documents, and old seds have small limits too.
-# Maximum number of lines to put in a single here document.
-ac_max_here_lines=12
rm -f conftest.tail
while :
@@ -3659,7 +3933,11 @@ cat >> $CONFIG_STATUS <<\EOF
fi
fi; done
+EOF
+cat >> $CONFIG_STATUS <<EOF
+EOF
+cat >> $CONFIG_STATUS <<\EOF
exit 0
EOF
diff --git a/contrib/cvs/configure.in b/contrib/cvs/configure.in
index c60e98f..cf35ccd 100644
--- a/contrib/cvs/configure.in
+++ b/contrib/cvs/configure.in
@@ -1,42 +1,15 @@
dnl configure.in for cvs
AC_INIT(src/cvs.h)
-dnl
-AC_PREREQ(2.4)dnl Required Autoconf version.
-dnl Do not use autoconf 2.12; it produces a configure script which produces
-dnl a "internal 2K buffer" error on HPUX when run with /bin/sh.
-dnl autoconf 2.10 seems like a good choice.
-dnl
-dnl It is possible that we should just change the above required version
-dnl to 2.10; it seems like everyone is using 2.10 anyway, and there is
-dnl at least some sentiment that we should be using a version which has
-dnl --bindir (and correspondingly, using @bindir@ and friends in our
-dnl Makefile.in files. Rumor has it that autoconf 2.7
-dnl introduced --bindir but the point is that 2.10 has it.
+AC_PREREQ(2.13)
+AC_PREFIX_PROGRAM(cvs)
AC_CONFIG_HEADER(config.h src/options.h)
+AC_PROG_AWK
AC_PROG_CC
-
-AC_AIX
-AC_MINIX
-AC_ISC_POSIX
-if test "$ISC" = yes; then
-CFLAGS="$CFLAGS -D_SYSV3"
-LIBS="-lcrypt $LIBS"
-fi
-
-AC_PREFIX_PROGRAM(cvs)
-
-dnl FIXME: AC_C_CROSS is considered obsolete by autoconf 2.12, and is
-dnl pretty ugly to start with. But it isn't obvious to me how we should
-dnl be handling the uses of cross_compiling below.
-AC_C_CROSS
-
-AC_C_CONST
-
AC_PROG_INSTALL
+AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_PROG_YACC
-AC_PROG_MAKE_SET
AC_PATH_PROG(perl_path, perl, no)
AC_PATH_PROG(csh_path, csh, no)
@@ -48,23 +21,35 @@ if test X"$ac_cv_sys_interpreter" != X"yes" ; then
AC_MSG_WARN($ac_msg)
fi
+AC_AIX
+AC_MINIX
+AC_ISC_POSIX
+if test "$ISC" = yes; then
+CFLAGS="$CFLAGS -D_SYSV3"
+LIBS="-lcrypt $LIBS"
+fi
+
+AC_HEADER_DIRENT
AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(errno.h unistd.h string.h memory.h utime.h fcntl.h ndbm.h \
limits.h sys/file.h \
sys/param.h sys/select.h sys/time.h sys/timeb.h \
io.h direct.h sys/bsdtypes.h sys/resource.h)
-AC_HEADER_SYS_WAIT
AC_HEADER_STAT
AC_HEADER_TIME
-AC_HEADER_DIRENT
-AC_TYPE_SIGNAL
+
+AC_C_CONST
AC_TYPE_UID_T
AC_TYPE_MODE_T
-AC_TYPE_SIZE_T
AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_SIGNAL
+
AC_STRUCT_ST_BLKSIZE
+AC_STRUCT_ST_RDEV
AC_REPLACE_FUNCS(mkdir rename strstr dup2 strerror valloc waitpid memmove strtoul)
-AC_CHECK_FUNCS(fchmod fsync ftime mktemp putenv vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam tzset readlink wait3)
+AC_CHECK_FUNCS(fchmod fsync ftime mktemp putenv vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam tzset readlink wait3 mknod getpassphrase)
dnl
dnl The CVS coding standard (as specified in HACKING) is that if it exists
@@ -75,6 +60,12 @@ AC_DEFINE(HAVE_STRCHR)
AC_DEFINE(HAVE_MEMCHR)
dnl
+dnl Force lib/regex.c to use malloc instead of messing around with alloca
+dnl and define the old re_comp routines that we use.
+dnl
+AC_DEFINE(REGEX_MALLOC)
+AC_DEFINE(_REGEX_RE_COMP)
+dnl
dnl AC_FUNC_VFORK is rather baroque. It seems to be rather more picky
dnl than, say, the Single Unix Specification (version 2), which simplifies
dnl a lot of cases by saying that the child process can't set any variables
@@ -96,77 +87,21 @@ dnl
dnl We used to try to determine whether shadow passwords were actually in
dnl use or not, but the code has been changed to work right reguardless,
dnl so we can go back to a simple check.
-AC_CHECK_LIB(sec, getspnam)
-AC_CHECK_FUNCS(getspnam)
+AC_SEARCH_LIBS(getspnam, sec gen, AC_DEFINE(HAVE_GETSPNAM))
-dnl We always use CVS's regular expression matcher.
-dnl This is because:
-dnl (1) If memory serves, the syntax of the regular expressions
-dnl handled by re_exec is not consistent from system to system, which
-dnl is a Bad Thing because CVS passes this syntax out to the user.
-dnl We might have better luck with the POSIX interface, if we really
-dnl want to look for a system-supplied matcher.
-dnl (2) It is necessary to make _sure_ that we get a regex.h and regex.c
-dnl that match each other. In particular, rx and the CVS/emacs
-dnl regex.c have a different "struct re_pattern_buffer" and so using
-dnl the system regex.h and our regex.c, or vice versa, will tend to
-dnl cause a core dump.
-dnl (3) Just as a random data point, CVS uses re_exec (a BSD interface);
-dnl libdiff uses re_compile_pattern (a GNU interface, I think). Diff
-dnl should probably be fixed to have the caller (CVS) supply the regexp
-dnl matching.
-dnl
-dnl AC_CHECK_FUNC(re_exec, :, LIBOBJS="$LIBOBJS regex.o")
AC_FUNC_UTIME_NULL
AC_SYS_LONG_FILE_NAMES
-AC_MSG_CHECKING([for working fnmatch function])
-AC_CACHE_VAL(ccvs_cv_sys_working_fnmatch,
-[AC_TRY_RUN([
-#include <fnmatch.h>
-int
-main ()
-{
- exit ((fnmatch ("a", "a", FNM_PATHNAME) == 0
- && fnmatch ("a", "b", FNM_PATHNAME) == FNM_NOMATCH)
- ? 0 : 1);
-}],
-ccvs_cv_sys_working_fnmatch=yes,
-ccvs_cv_sys_working_fnmatch=no,
-ccvs_cv_sys_working_fnmatch=no)])
-if test $ccvs_cv_sys_working_fnmatch = no; then
+AC_FUNC_FNMATCH
+if test "$ac_cv_func_fnmatch_works" = no; then
LIBOBJS="$LIBOBJS fnmatch.o"
fi
-AC_MSG_RESULT($ccvs_cv_sys_working_fnmatch)
-# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
-# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
-# libsocket.so which has a bad implementation of gethostbyname (it
-# only looks in /etc/hosts), so we only look for -lsocket if we need
-# it.
-AC_CHECK_FUNC(connect, :,
-[case "$LIBS" in
-*-lnsl*) ;;
-*) AC_CHECK_LIB(nsl_s, printf) ;;
-esac
-case "$LIBS" in
-*-lnsl*) ;;
-*) AC_CHECK_LIB(nsl, printf) ;;
-esac
-case "$LIBS" in
-*-lsocket*) ;;
-*) AC_CHECK_LIB(socket, connect) ;;
-esac
-case "$LIBS" in
-*-linet*) ;;
-*) AC_CHECK_LIB(inet, connect) ;;
-esac
-dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
-dnl has been cached.
-if test "$ac_cv_lib_socket_connect" = "yes" || test "$ac_cv_lib_inet_connect" = "yes"; then
- ac_cv_func_connect=yes
- AC_DEFINE(HAVE_CONNECT)
-fi])
+# Try to find connect and gethostbyname.
+AC_CHECK_LIB(nsl, main,
+ AC_SEARCH_LIBS(connect, xnet socket inet, AC_DEFINE(HAVE_CONNECT),, -lnsl),
+ AC_SEARCH_LIBS(connect, xnet socket inet, AC_DEFINE(HAVE_CONNECT)))
+AC_SEARCH_LIBS(gethostbyname, netinet nsl)
dnl
dnl set $(KRB4) from --with-krb4=value -- WITH_KRB4
@@ -314,7 +249,7 @@ AC_ARG_ENABLE(client,
[if test "$enable_client" = yes; then
AC_DEFINE(CLIENT_SUPPORT)
fi],
-[if test "$ac_cv_func_connect" = yes; then
+[if test "$ac_cv_search_connect" != no; then
AC_DEFINE(CLIENT_SUPPORT)
fi])
AC_ARG_ENABLE(server,
@@ -323,34 +258,24 @@ AC_ARG_ENABLE(server,
[if test "$enable_server" = yes; then
AC_DEFINE(SERVER_SUPPORT)
fi],
-[if test "$ac_cv_func_connect" = yes; then
+[if test "$ac_cv_search_connect" != no; then
AC_DEFINE(SERVER_SUPPORT)
enable_server=yes
fi])
-### The auth server needs to be able to check passwords against passwd
-### file entries, so we only #define AUTH_SERVER_SUPPORT if we can
-### find the crypt function.
-###
-### We used to test for crypt in libc first, and only add -lcrypt if
-### we couldn't find it, but that interacts badly with the cache
-### variables, the 'unset' command isn't portable, and I'm not sure
-### there's any harm in just testing for -lcrypt first.
+dnl The auth server needs to be able to check passwords against passwd
+dnl file entries, so we only #define AUTH_SERVER_SUPPORT if we can
+dnl find the crypt function.
if test "$enable_server" = yes; then
-AC_CHECK_LIB(crypt, crypt)
-AC_CHECK_FUNCS(crypt)
-
-if test "$ac_cv_func_crypt" = yes; then
- AC_DEFINE(AUTH_SERVER_SUPPORT)
-fi
+AC_SEARCH_LIBS(crypt, crypt, AC_DEFINE(HAVE_CRYPT) AC_DEFINE(AUTH_SERVER_SUPPORT))
fi # enable_server
dnl For the moment we will assume that all systems which have
dnl the unixyness to run configure are unixy enough to do the
dnl PreservePermissions stuff. I have this sinking feeling that
dnl things won't be that simple, before long.
-AC_DEFINE(PRESERVE_PERMISSIONS_SUPPORT)
+dnl AC_DEFINE(PRESERVE_PERMISSIONS_SUPPORT)
dnl On cygwin32, we configure like a Unix system, but we use the
dnl Windows support code in lib/fncase.c to handle the case
diff --git a/contrib/cvs/contrib/ChangeLog b/contrib/cvs/contrib/ChangeLog
index 46cf007..6a2ee13 100644
--- a/contrib/cvs/contrib/ChangeLog
+++ b/contrib/cvs/contrib/ChangeLog
@@ -1,3 +1,20 @@
+2000-09-07 Larry Jones <larry.jones@sdrc.com>
+
+ * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@
+ from autoconf.
+
+2000-02-25 Larry Jones <larry.jones@sdr.com>
+
+ * log.pl: Get committer from command line instead of getlogin
+ so that client/server works correctly.
+ * loc_accum.pl: Ditto.
+
+2000-01-24 K.J. Paradise <kj@sourcegear.com>
+
+ * sccs2rcs.csh: fixed a y2k bug. This was submitted
+ by Ceri Davies <ceri_davies@isdcorp.com>, and looks
+ okay to me.
+
1999-01-19 Graham Stoney <greyham@research.canon.com.au>
* log.pl: The author commited the canonical perl "localtime" Y2K
diff --git a/contrib/cvs/contrib/Makefile.in b/contrib/cvs/contrib/Makefile.in
index 1c56339..3e59cf1 100644
--- a/contrib/cvs/contrib/Makefile.in
+++ b/contrib/cvs/contrib/Makefile.in
@@ -22,13 +22,13 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
# Where to install the executables.
-bindir = $(exec_prefix)/bin
+bindir = @bindir@
# Where to put the system-wide .cvsrc file
-libdir = $(prefix)/lib
+libdir = @libdir@
# Where to put the manual pages.
-mandir = $(prefix)/man
+mandir = @mandir@
# where to find command interpreters
perl_path = @perl_path@
diff --git a/contrib/cvs/contrib/log.pl b/contrib/cvs/contrib/log.pl
index 3a8ad99..ebdd322 100644
--- a/contrib/cvs/contrib/log.pl
+++ b/contrib/cvs/contrib/log.pl
@@ -6,9 +6,10 @@
# XXX -- I HATE Perl! This *will* be re-written in shell/awk/sed soon!
#
-# Usage: log.pl [[-m user] ...] [-s] -f logfile 'dirname file ...'
+# Usage: log.pl [-u user] [[-m mailto] ...] [-s] -f logfile 'dirname file ...'
#
-# -m user - for each user to receive cvs log reports
+# -u user - $USER passed from loginfo
+# -m mailto - for each user to receive cvs log reports
# (multiple -m's permitted)
# -s - to prevent "cvs status -v" messages
# -f logfile - for the logfile to append to (mandatory,
@@ -66,6 +67,8 @@ while (@ARGV) {
if ($arg eq '-m') {
$users = "$users " . shift @ARGV;
+ } elsif ($arg eq '-u') {
+ $login = shift @ARGV;
} elsif ($arg eq '-f') {
($logfile) && die "Too many '-f' args";
$logfile = shift @ARGV;
@@ -95,7 +98,9 @@ $year += 1900;
# get a login name for the guy doing the commit....
#
-$login = getlogin || (getpwuid($<))[0] || "nobody";
+if ($login eq '') {
+ $login = getlogin || (getpwuid($<))[0] || "nobody";
+}
# open log file for appending
#
diff --git a/contrib/cvs/contrib/log_accum.pl b/contrib/cvs/contrib/log_accum.pl
index d299fa6..2520fe1 100644
--- a/contrib/cvs/contrib/log_accum.pl
+++ b/contrib/cvs/contrib/log_accum.pl
@@ -13,7 +13,7 @@
#
# hacked greatly by Greg A. Woods <woods@planix.com>
-# Usage: log_accum.pl [-d] [-s] [-M module] [[-m mailto] ...] [[-R replyto] ...] [-f logfile]
+# Usage: log_accum.pl [-d] [-s] [-w] [-M module] [-u user] [[-m mailto] ...] [[-R replyto] ...] [-f logfile]
# -d - turn on debugging
# -m mailto - send mail to "mailto" (multiple)
# -R replyto - set the "Reply-To:" to "replyto" (multiple)
@@ -21,6 +21,7 @@
# -f logfile - write commit messages to logfile too
# -s - *don't* run "cvs status -v" for each file
# -w - show working directory with log message
+# -u user - $USER passed from loginfo
#
# Configurable options
@@ -251,7 +252,6 @@ sub write_commitlog {
$debug = 0;
$id = getpgrp(); # note, you *must* use a shell which does setpgrp()
$state = $STATE_NONE;
-$login = getlogin || (getpwuid($<))[0] || "nobody";
chop($hostname = `hostname`);
chop($domainname = `domainname`);
if ($domainname !~ '^\..*') {
@@ -285,6 +285,8 @@ while (@ARGV) {
}
} elsif ($arg eq '-M') {
$modulename = shift @ARGV;
+ } elsif ($arg eq '-u') {
+ $login = shift @ARGV;
} elsif ($arg eq '-s') {
$do_status = 0;
} elsif ($arg eq '-w') {
@@ -298,6 +300,9 @@ while (@ARGV) {
@files = split(/ /, $arg);
}
}
+if ($login eq '') {
+ $login = getlogin || (getpwuid($<))[0] || "nobody";
+}
($mailto) || die("No mail recipient specified (use -m)\n");
if ($replyto eq '') {
$replyto = $login;
diff --git a/contrib/cvs/contrib/sccs2rcs.csh b/contrib/cvs/contrib/sccs2rcs.csh
index a1dea01..15ebc9f 100644
--- a/contrib/cvs/contrib/sccs2rcs.csh
+++ b/contrib/cvs/contrib/sccs2rcs.csh
@@ -177,6 +177,11 @@ foreach sfile (SCCS/s.*)
if ($status != 0) goto ERROR
# get file into current dir and get stats
+ set year = `echo $date | cut -c3-4`
+ if ($year < 70) then
+ # Y2K Bug, change century to 20
+ set date = `echo $date | sed -e s/19/20/`
+ endif
set date = `sccs prs -r$rev $file | grep "^D " | awk '{printf("19%s %s", $3, $4); exit}'`
set author = `sccs prs -r$rev $file | grep "^D " | awk '{print $5; exit}'`
echo ""
diff --git a/contrib/cvs/diff/ChangeLog b/contrib/cvs/diff/ChangeLog
index a435182..e3272e8 100644
--- a/contrib/cvs/diff/ChangeLog
+++ b/contrib/cvs/diff/ChangeLog
@@ -1,3 +1,33 @@
+2000-08-03 Larry Jones <larry.jones@sdrc.com>
+
+ * diff3.c (read_diff): Use cvs_temp_name () instead of tmpnam () so
+ there's at least a chance of getting the file in the correct tmp dir.
+
+2000-07-10 Larry Jones <larry.jones@sdrc.com>
+
+ * util.c (printf_output): Fix type clashes.
+
+2000-06-15 Larry Jones <larry.jones@sdrc.com>
+
+ * diff3.c (diff3_run, make_3way_diff): Plug memory leaks.
+
+1999-12-29 Jim Kingdon <http://developer.redhat.com/>
+
+ * diff.c (compare_files): Use explicit braces with if-if-else, per
+ GNU coding standards and gcc -Wall.
+
+1999-11-23 Larry Jones <larry.jones@sdrc.com>
+
+ * diff3.c: Explicitly initialize zero_diff3 to placate neurotic
+ compilers that gripe about implicitly initialized const variables.
+ Reported by Eric Veum <sysv@yahoo.com>.
+
+1999-09-15 Larry Jones <larry.jones@sdrc.com>
+
+ * diff.c (diff_run): Move the setjmp call before the options
+ processing since option errors can call fatal which in turn
+ calls longjmp.
+
1999-05-06 Jim Kingdon <http://www.cyclic.com>
* Makefile.in (DISTFILES): Remove libdiff.mak.
diff --git a/contrib/cvs/diff/diff.c b/contrib/cvs/diff/diff.c
index e5f7e42..aa91913 100644
--- a/contrib/cvs/diff/diff.c
+++ b/contrib/cvs/diff/diff.c
@@ -247,11 +247,21 @@ diff_run (argc, argv, out, callbacks_arg)
/* Do our initializations. */
initialize_main (&argc, &argv);
-
- /* Decode the options. */
-
optind_old = optind;
optind = 0;
+
+ /* Set the jump buffer, so that diff may abort execution without
+ terminating the process. */
+ val = setjmp (diff_abort_buf);
+ if (val != 0)
+ {
+ optind = optind_old;
+ if (opened_file)
+ fclose (outfile);
+ return val;
+ }
+
+ /* Decode the options. */
while ((c = getopt_long (argc, argv,
"0123456789abBcC:dD:efF:hHiI:lL:nNpPqrsS:tTuU:vwW:x:X:y",
longopts, 0)) != EOF)
@@ -686,17 +696,6 @@ diff_run (argc, argv, out, callbacks_arg)
}
}
- /* Set the jump buffer, so that diff may abort execution without
- terminating the process. */
- val = setjmp (diff_abort_buf);
- if (val != 0)
- {
- optind = optind_old;
- if (opened_file)
- fclose (outfile);
- return val;
- }
-
val = compare_files (0, argv[optind], 0, argv[optind + 1], 0);
/* Print any messages that were saved up for last. */
@@ -1147,13 +1146,15 @@ compare_files (dir0, name0, dir1, name1, depth)
failed = 1;
}
if (inf[1].desc == -2)
- if (same_files)
- inf[1].desc = inf[0].desc;
- else if ((inf[1].desc = open (inf[1].name, O_RDONLY, 0)) < 0)
- {
- perror_with_name (inf[1].name);
- failed = 1;
- }
+ {
+ if (same_files)
+ inf[1].desc = inf[0].desc;
+ else if ((inf[1].desc = open (inf[1].name, O_RDONLY, 0)) < 0)
+ {
+ perror_with_name (inf[1].name);
+ failed = 1;
+ }
+ }
#if HAVE_SETMODE
if (binary_I_O)
diff --git a/contrib/cvs/diff/diff3.c b/contrib/cvs/diff/diff3.c
index e3be150..2f05d16 100644
--- a/contrib/cvs/diff/diff3.c
+++ b/contrib/cvs/diff/diff3.c
@@ -41,6 +41,8 @@ void printf_output PARAMS((char const *, ...))
;
void flush_output PARAMS((void));
+char * cvs_temp_name PARAMS((void));
+
/*
* Internal data structures and macros for the diff3 program; includes
* data structures for both diff3 diffs and normal diffs.
@@ -475,8 +477,6 @@ diff3_run (argc, argv, out, callbacks_arg)
free(content0);
free(content1);
- free_diff_blocks(thread0);
- free_diff_blocks(thread1);
free_diff3_blocks(diff3);
if (! callbacks || ! callbacks->write_output)
@@ -676,7 +676,7 @@ make_3way_diff (thread0, thread1)
struct diff3_block const *last_diff3;
- static struct diff3_block const zero_diff3;
+ static struct diff3_block const zero_diff3 = { 0 };
/* Initialization */
result = 0;
@@ -765,6 +765,8 @@ make_3way_diff (thread0, thread1)
tmpblock = using_to_diff3_block (using, last_using,
base_water_thread, high_water_thread,
last_diff3);
+ free_diff_blocks(using[0]);
+ free_diff_blocks(using[1]);
if (!tmpblock)
diff3_fatal ("internal error: screwup in format of diff blocks");
@@ -1274,7 +1276,7 @@ read_diff (filea, fileb, output_placement)
*ap++ = fileb;
*ap = 0;
- diffout = tmpnam(NULL);
+ diffout = cvs_temp_name ();
outfile_hold = outfile;
callbacks_hold = callbacks;
diff --git a/contrib/cvs/diff/util.c b/contrib/cvs/diff/util.c
index c4d2d71..ff9cceb 100644
--- a/contrib/cvs/diff/util.c
+++ b/contrib/cvs/diff/util.c
@@ -366,7 +366,7 @@ printf_output (format, va_alist)
char *str;
int num;
int ch;
- unsigned char buf[100];
+ char buf[100];
while ((q = strchr (p, '%')) != NULL)
{
diff --git a/contrib/cvs/doc/ChangeLog b/contrib/cvs/doc/ChangeLog
index 33b7f91..6a9206d 100644
--- a/contrib/cvs/doc/ChangeLog
+++ b/contrib/cvs/doc/ChangeLog
@@ -1,3 +1,193 @@
+2000-09-07 Larry Jones <larry.jones@sdrc.com>
+
+ * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@
+ from autoconf.
+
+2000-08-21 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo (Removing directories, export): Note that export always
+ prunes directories and remove references to the non-existent -P flag.
+
+2000-07-28 Larry Jones <larry.jones@sdrc.com>
+
+ * cvsclient.texi (Requests): Ensure that all rootless requests say
+ that they're rootless.
+
+2000-07-12 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo (Module program options): Remove note that commit and
+ update programs only working locally; they've worked client/server
+ for quite some time.
+
+2000-07-10 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo (Invoking CVS): Document new version command.
+ * cvsclient.texi (Requests): Document new version request.
+
+2000-07-06 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo (admin options): Remove note about -t not working
+ in client/server.
+
+2000-04-03 Pavel Roskin <pavel_roskin@geocities.com>
+
+ * cvs.texinfo (Telling CVS to notify you): Remove backslashes
+ before quotes.
+
+2000-05-24 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo (From files): Clean up @var{wdir}/@var{rdir} vs.
+ @var{dir} usage.
+
+2000-05-19 Larry Jones <larry.jones@sdrc.com>
+
+ * cvsclient.texi (Requests): Note that Global_option is now
+ valid without Root.
+
+2000-04-17 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo (Variables): Clarify what USER means in pserver.
+
+2000-03-08 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo (Connection): Add note about inetd rate limit.
+ (ErrorMessages): Add root home directory permission messages.
+
+2000-02-12 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo: Clean up text/formatting of previous change.
+
+2000-02-21 K.J. Paradise <kj@sourcegear.com>
+
+ * cvs.texinfo : Adding John Cavanaugh's patch to allow
+ the history file to log actions based on the CVSROOT/config
+ file. (To limit which cvs actions actually make it into the
+ history file)
+
+2000-02-17 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo: Remove references to PreservePermissions.
+
+ * cvs.texinfo (history options): Note default report type.
+
+2000-01-18 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo (Global options): Document compression levels.
+
+2000-01-18 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo: Minor editorial changes from Ken Foskey
+ <waratah@zip.com.au>.
+
+2000-01-11 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo: Add index entries for "Compression" and "Gzip".
+ Correct typography in many index entries (English phrases should
+ have initial caps, subcommands/files/etc. should be as-is).
+
+2000-01-10 Karl Fogel <kfogel@red-bean.com>
+
+ * cvs.texinfo (loginfo): correctly describe CVSROOT/loginfo's
+ %-expansion behavior. Thanks to Karl Heinz Marbaise
+ <kama@hippo.fido.de> for noticing the error.
+
+2000-01-07 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo (Password authentication server): Use -f in example
+ inetd.conf line.
+ (Connection): Add advice about using shell script or env to avoid
+ problems with inetd setting HOME in the server's environment.
+ (various): Use @file for inetd.conf.
+
+2000-01-02 John P Cavanaugh <cavanaug@sr.hp.com>
+
+ * cvs.texinfo: document new -C option to update, now that it works
+ both remotely and locally.
+ (Re-applied by Karl Fogel <kfogel@red-bean.com>.)
+
+1999-12-11 Karl Fogel <kfogel@red-bean.com>
+
+ * Revert previous change -- it doesn't work remotely yet.
+
+1999-12-10 John P Cavanaugh <cavanaug@sr.hp.com>
+
+ * cvs.texinfo: document new -C option to update.
+ (Applied by Karl Fogel <kfogel@red-bean.com>.)
+
+1999-11-20 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo(history options): Document -f, -n, and -z.
+
+1999-11-09 Jim Kingdon <http://developer.redhat.com/>
+
+ * cvsclient.texi (Requests): Document the arguments to "log", now
+ that I've changed log.c to be more specific in terms of what it
+ will send.
+
+1999-11-05 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo: Revert Karl's change once again since the code is now
+ fixed. Add "Variables" and "User variables" to index.
+
+1999-11-04 Karl Fogel <kfogel@red-bean.com>
+
+ * log.c (log_usage): Revert Jim Kingdon's reversion of my change
+ of 1999-11-03. Allowing a space between option and argument
+ results in lossage; here is a reproduction recipe: run this from
+ the top of a remote copy of the cvs source tree
+
+ cvs log -d '>1999-03-01' > log-out.with-space
+
+ and then run this (note there's no space after -d now):
+
+ cvs log -d'>1999-03-01' > log-out.no-space
+
+ The resulting files differ; furthermore, a glance at the output of
+ cvs shows that the first command failed to recurse into
+ subdirectories. Until this misbehavior can be fixed in the source
+ code, the documentation should reflect the true state of affairs:
+ if one simply omits the space, everything works fine.
+
+1999-11-04 Jim Kingdon <http://developer.redhat.com/>
+
+ * cvs.texinfo (log options): Revert Karl's change regarding -d and
+ -s. A space is allowed (see sanity.sh for example).
+
+ * cvs.texinfo (Password authentication server): The name of the
+ file is "passwd" not "password".
+
+ * cvsclient.texi (Top): Add @dircategory and @direntry.
+
+1999-11-04 Karl Fogel <kfogel@red-bean.com>
+
+ * cvs.texinfo (Password authentication server, Password
+ authentication client): Rewritten to accommodate the [new]
+ possibility of empty passwords.
+
+1999-11-03 Karl Fogel <kfogel@red-bean.com>
+
+ * cvs.texinfo (Invoking CVS): correct documentation for -d and -s
+ options (as did elsewhere, earlier today).
+
+1999-11-03 Karl Fogel <kfogel@red-bean.com>
+
+ * cvs.texinfo (Setting a watch): describe `watch off' behavior
+ more accurately.
+
+1999-11-03 Karl Fogel <kfogel@red-bean.com>
+
+ * cvs.texinfo (log options): correct documentation for -d and -s
+ options. There can be no space between these options and their
+ arguments.
+
+ Also, make sure all @sc{cvs} codes refer to "cvs" in lower case;
+ this avoids makeinfo warnings. And use @code for the CVSEDITOR
+ environment variable, not @sc.
+
+1999-09-24 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.texinfo: Misc. formatting cleanups.
+
1999-07-16 Tom Tromey <tromey@cygnus.com>
* cvs.texinfo (admin): Mention admin -k exception. Add cvsadmin
diff --git a/contrib/cvs/doc/Makefile.in b/contrib/cvs/doc/Makefile.in
index 29eb565..b5da032 100644
--- a/contrib/cvs/doc/Makefile.in
+++ b/contrib/cvs/doc/Makefile.in
@@ -21,7 +21,7 @@ VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
-infodir = $(prefix)/info
+infodir = @infodir@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
diff --git a/contrib/cvs/doc/cvs.texinfo b/contrib/cvs/doc/cvs.texinfo
index 4d8b949..8d5de53 100644
--- a/contrib/cvs/doc/cvs.texinfo
+++ b/contrib/cvs/doc/cvs.texinfo
@@ -252,7 +252,7 @@ free download from the internet. For more information
on downloading @sc{cvs} and other @sc{cvs} topics, see:
@example
-http://www.cyclic.com/
+http://www.cvshome.org/
http://www.loria.fr/~molli/cvs-index.html
@end example
@@ -728,7 +728,7 @@ they should be in separate locations.
@c as it is; need a little reorganization...
@cindex :local:, setting up
-@sc{Cvs} can access a repository by a variety of
+@sc{cvs} can access a repository by a variety of
means. It might be on the local computer, or it might
be on a computer across the room or across the world.
To distinguish various ways to access a repository, the
@@ -859,8 +859,8 @@ the file permissions appropriate for the repository.
@node Repository files
@subsection Where files are stored within the repository
-@c @cindex filenames, legal
-@c @cindex legal filenames
+@c @cindex Filenames, legal
+@c @cindex Legal filenames
@c Somewhere we need to say something about legitimate
@c characters in filenames in working directory and
@c repository. Not "/" (not even on non-unix). And
@@ -989,12 +989,12 @@ rules see @ref{Tags}.
@c -- Move this to @node Creating a repository or similar
@cindex Security, file permissions in repository
@cindex File permissions, general
-@cindex permissions, general
+@cindex Permissions, general
@c FIXME: we need to somehow reflect "permissions in
@c repository" versus "permissions in working
@c directory" in the index entries.
@cindex Group
-@cindex read-only files, in repository
+@cindex Read-only files, in repository
All @samp{,v} files are created read-only, and you
should not change the permission of those files. The
directories inside the repository should be writable by
@@ -1019,7 +1019,7 @@ out files, because @sc{cvs} needs to create lock files
@c Like val-tags gets created by someone who doesn't
@c have CVSUMASK set right?
Also note that users must have write access to the
-@file{CVSROOT/val-tags} file. @sc{Cvs} uses it to keep
+@file{CVSROOT/val-tags} file. @sc{cvs} uses it to keep
track of what tags are valid tag names (it is sometimes
updated when tags are used, as well as when they are
created).
@@ -1029,7 +1029,7 @@ checked it in. This has little significance; what
really matters is who owns the directories.
@cindex CVSUMASK, environment variable
-@cindex umask, for repository files
+@cindex Umask, for repository files
@sc{cvs} tries to set up reasonable file permissions
for new directories that are added inside the tree, but
you must fix the permissions manually when a new
@@ -1043,7 +1043,7 @@ directory; such files have the permissions which are
typical for newly created files, except that sometimes
@sc{cvs} creates them read-only (see the sections on
watches, @ref{Setting a watch}; -r, @ref{Global
-options}; or CVSREAD, @ref{Environment variables}).
+options}; or @code{CVSREAD}, @ref{Environment variables}).
@c FIXME: Need more discussion of which
@c group should own the file in the repository.
@c Include a somewhat detailed example of the usual
@@ -1091,10 +1091,10 @@ permissions on the @sc{cvsroot} directory and
directories above it in the tree; see @ref{Password
authentication security}.
-@cindex setuid
-@cindex setgid
-@cindex security, setuid
-@cindex installed images (VMS)
+@cindex Setuid
+@cindex Setgid
+@cindex Security, setuid
+@cindex Installed images (VMS)
Some operating systems have features which allow a
particular program to run with the ability to perform
operations which the caller of the program could not.
@@ -1118,7 +1118,7 @@ carefully if you are considering this option
@subsection File Permission issues specific to Windows
@cindex Windows, and permissions
@cindex File permissions, Windows-specific
-@cindex permissions, Windows-specific
+@cindex Permissions, Windows-specific
Some file permission issues are specific to Windows
operating systems (Windows 95, Windows NT, and
@@ -1140,7 +1140,7 @@ something out, please let us know as described in
@node Attic
@subsection The attic
-@cindex attic
+@cindex Attic
You will notice that sometimes @sc{cvs} stores an
@sc{rcs} file in the @code{Attic}. For example, if the
@@ -1159,7 +1159,7 @@ but if it goes in the attic, it would be in
/usr/local/cvsroot/yoyodyne/tc/Attic/backend.c,v
@end example
-@cindex dead state
+@cindex Dead state
instead. It should not matter from a user point of
view whether a file is in the attic; @sc{cvs} keeps
track of this and looks in the attic when it needs to.
@@ -1276,7 +1276,7 @@ there must be a single tab character there and no spaces.
@cindex #cvs.rfl, technical details
@cindex #cvs.wfl, technical details
@cindex #cvs.lock, technical details
-@cindex locks, cvs, technical details
+@cindex Locks, cvs, technical details
For an introduction to CVS locks focusing on
user-visible behavior, see @ref{Concurrency}. The
following section is aimed at people who are writing
@@ -1907,7 +1907,7 @@ in the repository; for the most part it is possible to
back them up just like any other files. However, there
are a few issues to consider.
-@cindex locks, cvs, and backups
+@cindex Locks, cvs, and backups
@cindex #cvs.rfl, and backups
The first is that to be paranoid, one should either not
use @sc{cvs} during the backup, or have the backup
@@ -1953,9 +1953,9 @@ the changes into the repository.
@node Moving a repository
@section Moving a repository
-@cindex repository, moving
-@cindex moving a repository
-@cindex copying a repository
+@cindex Repository, moving
+@cindex Moving a repository
+@cindex Copying a repository
Just as backing up the files in the repository is
pretty much like backing up any other files, if you
@@ -1990,7 +1990,7 @@ isn't worth it.
@cindex Repositories, remote
@cindex Remote repositories
@cindex Client/Server Operation
-@cindex server, CVS
+@cindex Server, CVS
Your working copy of the sources can be on a
different machine than the repository. Using @sc{cvs}
@@ -2171,7 +2171,7 @@ for example @file{/usr/local/bin/cvs-1.6}.
@c different ones for different roots. e.g. ":server;cvs=cvs-1.6:"
@c instead of ":server:".
-There is no need to edit @code{inetd.conf} or start a
+There is no need to edit @file{inetd.conf} or start a
@sc{cvs} server daemon.
@cindex :server:, setting up
@@ -2179,7 +2179,7 @@ There is no need to edit @code{inetd.conf} or start a
@cindex Kerberos, using kerberized rsh
@cindex SSH (rsh replacement)
@cindex rsh replacements (Kerberized, SSH, &c)
-There are two access methods that you use in CVSROOT
+There are two access methods that you use in @code{CVSROOT}
for rsh. @code{:server:} specifies an internal rsh
client, which is supported only by some CVS ports.
@code{:ext:} specifies an external rsh program. By
@@ -2252,9 +2252,9 @@ permissions on the @file{$CVSROOT} and
@file{$CVSROOT/CVSROOT} directories. See @ref{Password
authentication security}, for more details.
-@cindex Pserver (subcommand)
-@cindex password server, setting up
-@cindex authenticating server, setting up
+@cindex pserver (subcommand)
+@cindex Password server, setting up
+@cindex Authenticating server, setting up
@c FIXME: this isn't quite right regarding port
@c numbers; CVS looks up "cvspserver" in
@c /etc/services (on unix, but what about non-unix?).
@@ -2272,7 +2272,7 @@ single line in @file{inetd.conf}) should be sufficient:
@example
2401 stream tcp nowait root /usr/local/bin/cvs
-cvs --allow-root=/usr/cvsroot pserver
+cvs -f --allow-root=/usr/cvsroot pserver
@end example
You could also use the
@@ -2312,86 +2312,126 @@ If you are having trouble setting this up, see
Because the client stores and transmits passwords in
cleartext (almost---see @ref{Password authentication
security}, for details), a separate @sc{cvs} password
-file may be used, so people don't compromise their
-regular passwords when they access the repository.
-This file is @file{$CVSROOT/CVSROOT/passwd}
-(@pxref{Intro administrative files}). Its format is
-similar to @file{/etc/passwd}, except that it only has
-two or three fields, username, password, and optional
-username for the server to use. For example:
-
-@example
+file is generally used, so people don't compromise
+their regular passwords when they access the
+repository. This file is
+@file{$CVSROOT/CVSROOT/passwd} (@pxref{Intro
+administrative files}). It uses a colon-separated
+format, similar to @file{/etc/passwd} on Unix systems,
+except that it has fewer fields: @sc{cvs} username,
+optional password, and an optional system username for
+@sc{cvs} to run as if authentication succeeds. Here is
+an example @file{passwd} file with five entries:
+
+@example
+anonymous:
bach:ULtgRLXo7NRxs
-cwang:1sOp854gDF3DY
+spwang:1sOp854gDF3DY
+melissa:tGX1fS8sun6rY:pubcvs
+qproj:XR4EZcEs0szik:pubcvs
@end example
-The password is encrypted according to the standard
+(The passwords are encrypted according to the standard
Unix @code{crypt()} function, so it is possible to
paste in passwords directly from regular Unix
-@file{passwd} files.
-
+@file{/etc/passwd} files.)
+
+The first line in the example will grant access to any
+@sc{cvs} client attempting to authenticate as user
+@code{anonymous}, no matter what password they use,
+including an empty password. (This is typical for
+sites granting anonymous read-only access; for
+information on how to do the "read-only" part, see
+@xref{Read-only access}.)
+
+The second and third lines will grant access to
+@code{bach} and @code{spwang} if they supply their
+respective plaintext passwords.
+
+@cindex User aliases
+The fourth line will grant access to @code{melissa}, if
+she supplies the correct password, but her @sc{cvs}
+operations will actually run on the server side under
+the system user @code{pubcvs}. Thus, there need not be
+any system user named @code{melissa}, but there
+@emph{must} be one named @code{pubcvs}.
+
+The fifth line shows that system user identities can be
+shared: any client who successfully authenticates as
+@code{qproj} will actually run as @code{pubcvs}, just
+as @code{melissa} does. That way you could create a
+single, shared system user for each project in your
+repository, and give each developer their own line in
+the @file{$CVSROOT/CVSROOT/passwd} file. The @sc{cvs}
+username on each line would be different, but the
+system username would be the same. The reason to have
+different @sc{cvs} usernames is that CVS will log their
+actions under those names: when @code{melissa} commits
+a change to a project, the checkin is recorded in the
+project's history under the name @code{melissa}, not
+@code{pubcvs}. And the reason to have them share a
+system username is so that you can arrange permissions
+in the relevant area of the repository such that only
+that account has write-permission there.
+
+If the system-user field is present, all
+password-authenticated @sc{cvs} commands run as that
+user; if no system user is specified, @sc{cvs} simply
+takes the @sc{cvs} username as the system username and
+runs commands as that user. In either case, if there
+is no such user on the system, then the @sc{cvs}
+operation will fail (regardless of whether the client
+supplied a valid password).
+
+The password and system-user fields can both be omitted
+(and if the system-user field is omitted, then also
+omit the colon that would have separated it from the
+encrypted password). For example, this would be a
+valid @file{$CVSROOT/CVSROOT/passwd} file:
+
+@example
+anonymous::pubcvs
+fish:rKa5jzULzmhOo:kfogel
+sussman:1sOp854gDF3DY
+@end example
+
+When the password field is omitted or empty, then the
+client's authentication attempt will succeed with any
+password, including the empty string. However, the
+colon after the @sc{cvs} username is always necessary,
+even if the password is empty.
+
+CVS can also fall back to use system authentication.
When authenticating a password, the server first checks
-for the user in the @sc{cvs} @file{passwd} file. If it
-finds the user, it compares against that password. If
-it does not find the user, or if the @sc{cvs}
-@file{passwd} file does not exist, then the server
-tries to match the password using the system's
-user-lookup routine (using the system's user-lookup
-routine can be disabled by setting @code{SystemAuth=no}
-in the config file, @pxref{config}). When using the @sc{cvs}
-@file{passwd} file, the server runs as the
-username specified in the third argument in the
-entry, or as the first argument if there is no third
-argument (in this way @sc{cvs} allows imaginary
-usernames provided the @sc{cvs} @file{passwd} file
-indicates corresponding valid system usernames). In
-any case, @sc{cvs} will have no privileges which the
-(valid) user would not have.
-
-@cindex user aliases
- It is possible to ``map'' cvs-specific
-usernames onto system usernames (i.e., onto system
-login names) in the @file{$CVSROOT/CVSROOT/passwd} file
-by appending a colon and the system username after the
-password. For example:
-
-@example
-cvs:ULtgRLXo7NRxs:kfogel
-generic:1sOp854gDF3DY:spwang
-anyone:1sOp854gDF3DY:spwang
-@end example
-
- Thus, someone remotely accessing the repository
-on @file{faun.example.org} with the following
-command:
-
-@example
-cvs -d :pserver:cvs@@faun.example.org:/usr/local/cvsroot checkout foo
-@end example
-
- would end up running the server under the
-system identity kfogel, assuming successful
-authentication. However, the remote user would not
-necessarily need to know kfogel's system password, as
-the @file{$CVSROOT/CVSROOT/passwd} file might contain a
-different password, used only for @sc{cvs}. And as the
-example above indicates, it is permissible to map
-multiple cvs usernames onto a single system username.
-
- This feature is designed to allow people
-repository access without full system access (in
-particular, see @ref{Read-only access}); however, also
-see @ref{Password authentication security}. Any sort of
-repository access very likely implies a degree of
-general system access as well.
+for the user in the @file{$CVSROOT/CVSROOT/passwd}
+file. If it finds the user, it will use that entry for
+authentication as described above. But if it does not
+find the user, or if the @sc{cvs} @file{passwd} file
+does not exist, then the server can try to authenticate
+the username and password using the operating system's
+user-lookup routines (this "fallback" behavior can be
+disabled by setting @code{SystemAuth=no} in the
+@sc{cvs} @file{config} file, @pxref{config}). Be
+aware, however, that falling back to system
+authentication might be a security risk: @sc{cvs}
+operations would then be authenticated with that user's
+regular login password, and the password flies across
+the network in plaintext. See @ref{Password
+authentication security} for more on this.
Right now, the only way to put a password in the
@sc{cvs} @file{passwd} file is to paste it there from
somewhere else. Someday, there may be a @code{cvs
passwd} command.
-Unlike many of the files in @file{$CVSROOT/CVSROOT},
-you edit the @file{passwd} file directly, rather than
-via @sc{cvs}.
+
+Unlike many of the files in @file{$CVSROOT/CVSROOT}, it
+is normal to edit the @file{passwd} file in-place,
+rather than via @sc{cvs}. This is because of the
+possible security risks of having the @file{passwd}
+file checked out to people's working copies. If you do
+want to include the @file{passwd} file in checkouts of
+@file{$CVSROOT/CVSROOT}, see @xref{checkoutlist}.
+
@c We might also suggest using the @code{htpasswd} command
@c from freely available web servers as well, but that
@c would open up a can of worms in that the users next
@@ -2403,74 +2443,98 @@ via @sc{cvs}.
@node Password authentication client
@subsubsection Using the client with password authentication
@cindex Login (subcommand)
-@cindex password client, using
-@cindex authenticated client, using
+@cindex Password client, using
+@cindex Authenticated client, using
@cindex :pserver:, setting up
-Before connecting to the server, the client must @dfn{log
-in} with the command @code{cvs login}. Logging in
-verifies a password with the server, and also records
-the password for later transactions with the server.
-The @code{cvs login} command needs to know the
-username, server hostname, and full repository path,
-and it gets this information from the repository
-argument or the @code{CVSROOT} environment variable.
+To run a @sc{cvs} command on a remote repository via
+the password-authenticating server, one specifies the
+@code{pserver} protocol, username, repository host, and
+path to the repository. For example:
-@code{cvs login} is interactive --- it prompts for a
-password:
+@example
+cvs -d :pserver:bach@@faun.example.org:/usr/local/cvsroot checkout someproj
+@end example
+
+or
+
+@example
+CVSROOT=:pserver:bach@@faun.example.org:/usr/local/cvsroot
+cvs checkout someproj
+@end example
+
+However, unless you're connecting to a public-access
+repository (i.e., one where that username doesn't
+require a password), you'll need to @dfn{log in} first.
+Logging in verifies your password with the repository.
+It's done with the @code{login} command, which will
+prompt you interactively for the password:
@example
cvs -d :pserver:bach@@faun.example.org:/usr/local/cvsroot login
CVS password:
@end example
-The password is checked with the server; if it is
-correct, the @code{login} succeeds, else it fails,
-complaining that the password was incorrect.
-
-Once you have logged in, you can force @sc{cvs} to
-connect directly to the server and authenticate with
-the stored password:
+After you enter the password, @sc{cvs} verifies it with
+the server. If the verification succeeds, then that
+combination of username, host, repository, and password
+is permanently recorded, so future transactions with
+that repository won't require you to run @code{cvs
+login}. (If verification fails, @sc{cvs} will exit
+complaining that the password was incorrect, and
+nothing will be recorded.)
+
+The records are stored, by default, in the file
+@file{$HOME/.cvspass}. That file's format is
+human-readable, and to a degree human-editable, but
+note that the passwords are not stored in
+cleartext---they are trivially encoded to protect them
+from "innocent" compromise (i.e., inadvertent viewing
+by a system administrator or other non-malicious
+person).
+@cindex CVS_PASSFILE, environment variable
+You can change the default location of this file by
+setting the @code{CVS_PASSFILE} environment variable.
+If you use this variable, make sure you set it
+@emph{before} @code{cvs login} is run. If you were to
+set it after running @code{cvs login}, then later
+@sc{cvs} commands would be unable to look up the
+password for transmission to the server.
+
+Once you have logged in, all @sc{cvs} commands using
+that remote repository and username will authenticate
+with the stored password. So, for example
+
@example
cvs -d :pserver:bach@@faun.example.org:/usr/local/cvsroot checkout foo
@end example
-The @samp{:pserver:} is necessary because without it,
-@sc{cvs} will assume it should use @code{rsh} to
-connect with the server (@pxref{Connecting via rsh}).
-(Once you have a working copy checked out and are
-running @sc{cvs} commands from within it, there is no
-longer any need to specify the repository explicitly,
-because @sc{cvs} records it in the working copy's
-@file{CVS} subdirectory.)
+should just work (unless the password changes on the
+server side, in which case you'll have to re-run
+@code{cvs login}).
-@cindex CVS_PASSFILE, environment variable
-Passwords are stored by default in the file
-@file{$HOME/.cvspass}. Its format is human-readable,
-but don't edit it unless you know what you are doing.
-The passwords are not stored in cleartext, but are
-trivially encoded to protect them from "innocent"
-compromise (i.e., inadvertently being seen by a system
-administrator who happens to look at that file).
+Note that if the @samp{:pserver:} were not present in
+the repository specification, @sc{cvs} would assume it
+should use @code{rsh} to connect with the server
+instead (@pxref{Connecting via rsh}).
+
+Of course, once you have a working copy checked out and
+are running @sc{cvs} commands from within it, there is
+no longer any need to specify the repository
+explicitly, because @sc{cvs} can deduce the repository
+from the working copy's @file{CVS} subdirectory.
@c FIXME: seems to me this needs somewhat more
@c explanation.
@cindex Logout (subcommand)
-The password for the currently chosen remote repository
-can be removed from the CVS_PASSFILE by using the
+The password for a given remote repository can be
+removed from the @code{CVS_PASSFILE} by using the
@code{cvs logout} command.
-The @code{CVS_PASSFILE} environment variable overrides
-this default. If you use this variable, make sure you
-set it @emph{before} @code{cvs login} is run. If you
-were to set it after running @code{cvs login}, then
-later @sc{cvs} commands would be unable to look up the
-password for transmission to the server.
-
@node Password authentication security
@subsubsection Security considerations with password authentication
-@cindex security, of pserver
+@cindex Security, of pserver
The passwords are stored on the client side in a
trivial encoding of the cleartext, and transmitted in
the same encoding. The encoding is done only to
@@ -2534,7 +2598,7 @@ security, get Kerberos.
@subsection Direct connection with GSSAPI
@cindex GSSAPI
-@cindex security, GSSAPI
+@cindex Security, GSSAPI
@cindex :gserver:, setting up
@cindex Kerberos, using :gserver:
GSSAPI is a generic interface to network security
@@ -2588,7 +2652,7 @@ cvs -d :gserver:faun.example.org:/usr/local/cvsroot checkout foo
@subsection Direct connection with kerberos
@cindex Kerberos, using :kserver:
-@cindex security, kerberos
+@cindex Security, kerberos
@cindex :kserver:, setting up
The easiest way to use kerberos is to use the kerberos
@code{rsh}, as described in @ref{Connecting via rsh}.
@@ -2616,7 +2680,7 @@ on. You must then use the @code{-x} global option to
request encryption.
@cindex CVS_CLIENT_PORT
-You need to edit @code{inetd.conf} on the server
+You need to edit @file{inetd.conf} on the server
machine to run @code{cvs kserver}. The client uses
port 1999 by default; if you want to use another port
specify it in the @code{CVS_CLIENT_PORT} environment
@@ -2673,7 +2737,7 @@ environment variable.
@c ---------------------------------------------------------------------
@node Read-only access
@section Read-only repository access
-@cindex read-only repository access
+@cindex Read-only repository access
@cindex readers (admin file)
@cindex writers (admin file)
@@ -2762,8 +2826,8 @@ read-only access.
@node Server temporary directory
@section Temporary directories for the server
-@cindex temporary directories, and server
-@cindex server, temporary directories
+@cindex Temporary directories, and server
+@cindex Server, temporary directories
While running, the @sc{cvs} server creates temporary
directories. They are named
@@ -2775,7 +2839,7 @@ cvs-serv@var{pid}
@noindent
where @var{pid} is the process identification number of
the server. They are located in the directory
-specified by the @samp{TMPDIR} environment variable
+specified by the @code{TMPDIR} environment variable
(@pxref{Environment variables}), the @samp{-T} global
option (@pxref{Global options}), or failing that
@file{/tmp}.
@@ -2879,15 +2943,14 @@ original source directory.
@example
$ cd ..
-$ mv @var{dir} @var{dir}.orig
-$ cvs checkout yoyodyne/@var{dir} # @r{Explanation below}
-$ diff -r @var{dir}.orig yoyodyne/@var{dir}
-$ rm -r @var{dir}.orig
+$ cvs checkout yoyodyne/@var{rdir} # @r{Explanation below}
+$ diff -r @var{wdir} yoyodyne/@var{rdir}
+$ rm -r @var{wdir}
@end example
@noindent
Erasing the original sources is a good idea, to make sure that you do
-not accidentally edit them in @var{dir}, bypassing @sc{cvs}.
+not accidentally edit them in @var{wdir}, bypassing @sc{cvs}.
Of course, it would be wise to make sure that you have
a backup of the sources before you remove them.
@@ -2897,7 +2960,7 @@ examples) or a path name relative to @code{$CVSROOT},
as it did in the example above.
It is a good idea to check that the permissions
-@sc{cvs} sets on the directories inside @samp{$CVSROOT}
+@sc{cvs} sets on the directories inside @code{$CVSROOT}
are reasonable, and that they belong to the proper
groups. @xref{File permissions}.
@@ -3033,7 +3096,7 @@ Then, use @code{add} to add files (and new directories)
as they appear.
Check that the permissions @sc{cvs} sets on the
-directories inside @samp{$CVSROOT} are reasonable.
+directories inside @code{$CVSROOT} are reasonable.
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Defining the module
@@ -3296,7 +3359,7 @@ taginfo file (@pxref{user-defined logging}).
@c issues which arise.
@cindex Adding a tag
-@cindex tag, example
+@cindex Tag, example
The following example shows how you can add a tag to a
file. The commands must be issued inside your working
directory. That is, you should issue the
@@ -3407,7 +3470,7 @@ like this:
@node Tagging the working directory
@section Specifying what to tag from the working directory
-@cindex Tag (subcommand)
+@cindex tag (subcommand)
The example in the previous section demonstrates one of
the most common ways to choose which revisions to tag.
Namely, running the @code{cvs tag} command without
@@ -3439,7 +3502,7 @@ cvs [tag aborted]: correct the above errors first!
@node Tagging by date/tag
@section Specifying what to tag by date or revision
-@cindex Rtag (subcommand)
+@cindex rtag (subcommand)
The @code{cvs rtag} command tags the repository as of a
certain date or time (or can be used to tag the latest
@@ -3501,9 +3564,9 @@ recover from errors. If you are a @sc{cvs}
administrator, you may consider restricting these
commands with taginfo (@pxref{user-defined logging}).
-@cindex deleting tags
-@cindex removing tags
-@cindex tags, deleting
+@cindex Deleting tags
+@cindex Removing tags
+@cindex Tags, deleting
To delete a tag, specify the @samp{-d} option to either
@code{cvs tag} or @code{cvs rtag}. For example:
@@ -3513,8 +3576,8 @@ cvs rtag -d rel-0-4 tc
deletes the tag @code{rel-0-4} from the module @code{tc}.
-@cindex moving tags
-@cindex tags, moving
+@cindex Moving tags
+@cindex Tags, moving
When we say @dfn{move} a tag, we mean to make the same
name point to different revisions. For example, the
@code{stable} tag may currently point to revision 1.4
@@ -3528,8 +3591,8 @@ accomplished as:
cvs tag -r 1.6 -F stable backend.c
@end example
-@cindex renaming tags
-@cindex tags, renaming
+@cindex Renaming tags
+@cindex Tags, renaming
When we say @dfn{rename} a tag, we mean to make a
different name point to the same revisions as the old
tag. For example, one may have misspelled the tag name
@@ -3631,7 +3694,7 @@ you delete them with @samp{cvs update -A}. The
the head of the trunk, and forgets any sticky tags,
dates, or options.
-@cindex sticky date
+@cindex Sticky date
The most common use of sticky tags is to identify which
branch one is working on, as described in
@ref{Accessing branches}. However, non-branch
@@ -4760,8 +4823,8 @@ later merge the removals to another branch if you want
@node Removing directories
@section Removing directories
-@cindex removing directories
-@cindex directories, removing
+@cindex Removing directories
+@cindex Directories, removing
In concept removing directories is somewhat similar to
removing files---you want the directory to not exist in
@@ -4773,9 +4836,11 @@ The way that you remove a directory is to remove all
the files in it. You don't remove the directory
itself; there is no way to do that.
Instead you specify the @samp{-P} option to
-@code{cvs update}, @code{cvs checkout}, or @code{cvs
-export}, which will cause @sc{cvs} to remove empty
-directories from working directories. Probably the
+@code{cvs update} or @code{cvs checkout},
+which will cause @sc{cvs} to remove empty
+directories from working directories.
+(Note that @code{cvs export} always removes empty directories.)
+Probably the
best way to do this is to always specify @samp{-P}; if
you want an empty directory then put a dummy file (for
example @file{.keepme}) in it to prevent @samp{-P} from
@@ -4788,7 +4853,7 @@ removing it.
@c need for -P and so that a file can be a directory in
@c one revision and a regular file in another.
Note that @samp{-P} is implied by the @samp{-r} or @samp{-D}
-options of @code{checkout} and @code{export}. This way
+options of @code{checkout}. This way
@sc{cvs} will be able to correctly create the directory
or not depending on whether the particular version you
are checking out contains any files in that directory.
@@ -5120,6 +5185,11 @@ You can use the history file (@pxref{history file}) to
log various @sc{cvs} actions. To retrieve the
information from the history file, use the @code{cvs
history} command (@pxref{history}).
+
+Note: you can control what is logged to this file by using the
+@samp{LogHistory} keyword in the @file{CVSROOT/config} file
+(@pxref{config}).
+
@c
@c The history database has many problems:
@c * It is very unclear what field means what. This
@@ -5213,7 +5283,7 @@ Notified}); this command is useful even if you are not
using @code{cvs watch on}.
@cindex taginfo
-@cindex exit status, of taginfo
+@cindex Exit status, of taginfo
The @file{taginfo} file defines programs to execute
when someone executes a @code{tag} or @code{rtag}
command. The @file{taginfo} file has the standard form
@@ -5481,8 +5551,8 @@ considerably with the operating system.
@cindex File locking
@cindex Locking files
@cindex Working copy
-@cindex reserved checkouts
-@cindex unreserved checkouts
+@cindex Reserved checkouts
+@cindex Unreserved checkouts
@cindex RCS-style locking
When more than one person works on a software project
@@ -5525,7 +5595,7 @@ is almost automatic.
@c FIXME? should probably use the word "watch" here, to
@c tie this into the text below and above.
-@sc{Cvs} also supports mechanisms which facilitate
+@sc{cvs} also supports mechanisms which facilitate
various kinds of communication, without actually
enforcing rules like reserved checkouts do.
@@ -5703,7 +5773,7 @@ resolve the conflict as described in @ref{Conflicts example}.
@item Unknown
@cindex Unknown
-@sc{Cvs} doesn't know anything about this file. For
+@sc{cvs} doesn't know anything about this file. For
example, you have created a new file and have not run
@code{add}.
@c
@@ -5782,7 +5852,7 @@ these options, see @ref{Invoking CVS}.
@cindex Bringing a file up to date
@cindex Updating a file
@cindex Merging a file
-@cindex update, introduction
+@cindex Update, introduction
When you want to update or merge a file, use the @code{update}
command. For files that are not up to date this is roughly equivalent
@@ -6026,7 +6096,7 @@ newsgroup.
@node Concurrency
@section Several developers simultaneously attempting to run CVS
-@cindex locks, cvs, introduction
+@cindex Locks, cvs, introduction
@c For a discussion of *why* CVS creates locks, see
@c the comment at the start of src/lock.c
If several developers try to run @sc{cvs} at the same
@@ -6163,7 +6233,7 @@ certain files are to be watched.
@cindex watch on (subcommand)
@deffn Command {cvs watch on} [@code{-lR}] files @dots{}
-@cindex read-only files, and watches
+@cindex Read-only files, and watches
Specify that developers should run @code{cvs edit}
before editing @var{files}. CVS will create working
copies of @var{files} read-only, to remind developers
@@ -6187,8 +6257,16 @@ If @var{files} is omitted, it defaults to the current directory.
@deffn Command {cvs watch off} [@code{-lR}] files @dots{}
-Do not provide notification about work on @var{files}. CVS will create
-working copies of @var{files} read-write.
+Do not create @var{files} read-only on checkout; thus,
+developers will not be reminded to use @code{cvs edit}
+and @code{cvs unedit}.
+@ignore
+CVS will check out @var{files}
+read-write as usual, unless other permissions override
+due to the @code{PreservePermissions} option being
+enabled in the @file{config} administrative file
+(@pxref{Special Files}, @pxref{config})
+@end ignore
The @var{files} and options are processed as for @code{cvs
watch on}.
@@ -6271,7 +6349,7 @@ standard thing to put in the @code{notify} file is the
single line:
@example
-ALL mail %s -s \"CVS notification\"
+ALL mail %s -s "CVS notification"
@end example
This causes users to be notified by electronic mail.
@@ -6295,7 +6373,7 @@ instead of passing the name of the user to be notified
to @file{notify}, @sc{cvs} will pass the @var{value}
(normally an email address on some other machine).
-@sc{Cvs} does not notify you for your own changes.
+@sc{cvs} does not notify you for your own changes.
Currently this check is done based on whether the user
name of the person taking the action which triggers
notification matches the user name of the person
@@ -6317,7 +6395,7 @@ changing.
@node Editing files
@subsection How to edit a file which is being watched
-@cindex checkout, as term for getting ready to edit
+@cindex Checkout, as term for getting ready to edit
Since a file which is being watched is checked out
read-only, you cannot simply edit it. To make it
read-write, and inform others that you are planning to
@@ -6355,6 +6433,7 @@ receive notifications, she should specify @code{-a none}.
The @var{files} and options are processed as for the @code{cvs
watch} commands.
+@ignore
@strong{Caution:} If the @code{PreservePermissions}
option is enabled in the repository (@pxref{config}),
CVS will not change the permissions on any of the
@@ -6362,6 +6441,7 @@ CVS will not change the permissions on any of the
that using @samp{cvs edit} does not interfere with the
ability to store file permissions in the CVS
repository.
+@end ignore
@end deffn
@@ -6373,8 +6453,8 @@ your changes, or not to make any changes, you can use
the @code{cvs unedit} command.
@cindex unedit (subcommand)
-@cindex abandoning work
-@cindex reverting to repository version
+@cindex Abandoning work
+@cindex Reverting to repository version
@deffn Command {cvs unedit} [@code{-lR}] files @dots{}
Abandon work on the working files @var{files}, and revert them to the
@@ -6457,7 +6537,7 @@ that will restore the repository to a state which
@node Choosing a model
@section Choosing between reserved or unreserved checkouts
-@cindex choosing, reserved or unreserved checkouts
+@cindex Choosing, reserved or unreserved checkouts
Reserved and unreserved checkouts each have pros and
cons. Let it be said that a lot of this is a matter of
@@ -6980,7 +7060,7 @@ directory; if you want to work with the sources import
them first and then check them out into a different
directory (@pxref{Getting the source}).
-@cindex Wdiff (import example)
+@cindex wdiff (import example)
Suppose you have the sources to a program called
@code{wdiff} in a directory @file{wdiff-0.04},
and are going to make private modifications that you
@@ -7158,7 +7238,7 @@ an error in some future release.
@c "Revision management" section.
@node Builds
@chapter How your build system interacts with CVS
-@cindex builds
+@cindex Builds
@cindex make
As mentioned in the introduction, @sc{cvs} does not
@@ -7191,7 +7271,7 @@ periodically (in between changes, using the approach
just described) updating your entire tree, you ensure
that your sources are sufficiently up to date.
-@cindex bill of materials
+@cindex Bill of materials
One common need is to record which versions of which
source files went into a particular build. This kind
of functionality is sometimes called @dfn{bill of
@@ -7251,12 +7331,12 @@ is Odin (see
@node Special Files
@chapter Special Files
-@cindex special files
-@cindex device nodes
-@cindex ownership, saving in CVS
-@cindex permissions, saving in CVS
-@cindex hard links
-@cindex symbolic links
+@cindex Special files
+@cindex Device nodes
+@cindex Ownership, saving in CVS
+@cindex Permissions, saving in CVS
+@cindex Hard links
+@cindex Symbolic links
In normal circumstances, CVS works only with regular
files. Every file in a project is assumed to be
@@ -7269,6 +7349,7 @@ if the device file cannot be opened, CVS will refuse to
handle it. Files also lose their ownerships and
permissions during repository transactions.
+@ignore
If the configuration variable @code{PreservePermissions}
(@pxref{config}) is set in the repository, CVS will
save the following file characteristics in the
@@ -7347,6 +7428,7 @@ with client/server @sc{cvs}. Another limitation is
that hard links must be to other files within the same
directory; hard links across directories are not
supported.
+@end ignore
@c ---------------------------------------------------------------------
@node CVS commands
@@ -7438,7 +7520,7 @@ the documentation instead.
@node Exit status
@appendixsec CVS's exit status
-@cindex exit status, of CVS
+@cindex Exit status, of CVS
CVS can indicate to the calling environment whether it
succeeded or failed by setting its @dfn{exit status}.
@@ -7474,7 +7556,7 @@ other @sc{cvs} commands.
@node ~/.cvsrc
@appendixsec Default options and the ~/.cvsrc file
@cindex .cvsrc file
-@cindex option defaults
+@cindex Option defaults
There are some @code{command_options} that are used so
often that you might have set up an alias or some other
@@ -7548,8 +7630,8 @@ left of @samp{cvs_command}) are:
Specify legal @sc{cvsroot} directory. See
@ref{Password authentication server}.
-@cindex authentication, stream
-@cindex stream authentication
+@cindex Authentication, stream
+@cindex Stream authentication
@item -a
Authenticate all communication between the client and
the server. Only has an effect on the @sc{cvs} client.
@@ -7637,7 +7719,7 @@ Cause the command to be somewhat quiet; informational messages,
such as reports of recursion through subdirectories, are
suppressed.
-@cindex read-only files, and -r
+@cindex Read-only files, and -r
@item -r
Make new working files read-only. Same effect
as if the @code{$CVSREAD} environment variable is set
@@ -7672,8 +7754,8 @@ set or @samp{-r} is given.
@c be the same as a get and a cvs edit?), but I'm not
@c completely sure whether to document it this way.
-@cindex encryption
@item -x
+@cindex Encryption
Encrypt all communication between the client and the
server. Only has an effect on the @sc{cvs} client. As
of this writing, this is only implemented when using a
@@ -7686,8 +7768,13 @@ special configure option, @file{--enable-encryption},
when you build @sc{cvs}.
@item -z @var{gzip-level}
-Set the compression level. Only has an effect on the
-@sc{cvs} client.
+@cindex Compression
+@cindex Gzip
+Set the compression level.
+Valid levels are 1 (high speed, low compression) to
+9 (low speed, high compression), or 0 to disable
+compression (the default).
+Only has an effect on the @sc{cvs} client.
@end table
@@ -7796,8 +7883,8 @@ slightly different way; @pxref{history options}).
@c Headers Issue 4, Version 2 (September 1994), in the
@c entry for getdate() on page 231
-@cindex timezone, in input
-@cindex zone, time, in input
+@cindex Timezone, in input
+@cindex Zone, time, in input
A wide variety of date formats are supported by
@sc{cvs}. The most standard ones are ISO8601 (from the
International Standards Organization) and the Internet
@@ -8124,7 +8211,7 @@ There can be no space between @samp{-b} and its argument.
@c work, as of 17 Sep 1997, but probably will once "cvs
@c admin" is internal to CVS.
-@cindex comment leader
+@cindex Comment leader
@item -c@var{string}
Sets the comment leader to @var{string}. The comment
leader is not used by current versions of @sc{cvs} or
@@ -8360,13 +8447,7 @@ If @var{file} is omitted,
obtain the text from standard input, terminated by
end-of-file or by a line containing @samp{.} by itself.
Prompt for the text if interaction is possible; see
-@samp{-I}. Reading from standard input does not work
-for client/server @sc{cvs} and may change in a future
-release of @sc{cvs}.
-@c Changing it to doeditor() is the most obvious thing
-@c (but with a different syntax, as we would like to
-@c phase out optional arguments). I don't know. I'm
-@c tempted to say the whole concept is unnecessary.
+@samp{-I}.
@item -t-@var{string}
Similar to @samp{-t@var{file}}. Write descriptive text
@@ -8425,8 +8506,8 @@ this option has never done anything useful.
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node checkout
@appendixsec checkout---Check out sources for editing
-@cindex Checkout (subcommand)
-@cindex Co (subcommand)
+@cindex checkout (subcommand)
+@cindex co (subcommand)
@itemize @bullet
@item
@@ -8658,7 +8739,7 @@ $ cvs checkout -D yesterday tc
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node commit
@appendixsec commit---Check files into the repository
-@cindex Commit (subcommand)
+@cindex commit (subcommand)
@itemize @bullet
@item
@@ -8858,7 +8939,7 @@ $ cvs checkout -r EXPR1 whatever_module
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node diff
@appendixsec diff---Show differences between revisions
-@cindex Diff (subcommand)
+@cindex diff (subcommand)
@itemize @bullet
@item
@@ -9038,7 +9119,7 @@ $ cvs diff -u | less
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node export
@appendixsec export---Export sources from CVS, similar to checkout
-@cindex Export (subcommand)
+@cindex export (subcommand)
@itemize @bullet
@item
@@ -9055,7 +9136,8 @@ the @sc{cvs} administrative directories. For example, you
might use @code{export} to prepare source for shipment
off-site. This command requires that you specify a
date or tag (with @samp{-D} or @samp{-r}), so that you
-can count on reproducing the source you ship to others.
+can count on reproducing the source you ship to others
+(and thus it always prunes empty directories).
One often would like to use @samp{-kv} with @code{cvs
export}. This causes any keywords to be
@@ -9133,7 +9215,7 @@ Contributed examples are gratefully accepted.
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node history
@appendixsec history---Show status of files and users
-@cindex History (subcommand)
+@cindex history (subcommand)
@itemize @bullet
@item
@@ -9186,7 +9268,7 @@ Report on a particular module. (You can meaningfully
use @samp{-m} more than once on the command line.)
@item -o
-Report on checked-out modules.
+Report on checked-out modules. This is the default report type.
@item -T
Report on all tags.
@@ -9269,6 +9351,15 @@ Show data since @var{date}. This is slightly different
from the normal use of @samp{-D @var{date}}, which
selects the newest revision older than @var{date}.
+@item -f @var{file}
+Show data for a particular file
+(you can specify several @samp{-f} options on the same command line).
+This is equivalent to specifying the file on the command line.
+
+@item -n @var{module}
+Show data for a particular module
+(you can specify several @samp{-n} options on the same command line).
+
@item -p @var{repository}
Show data for a particular source repository (you
can specify several @samp{-p} options on the same command
@@ -9288,6 +9379,10 @@ above in that it reads only the history file, not the
@item -u @var{name}
Show records for user @var{name}.
+
+@item -z @var{timezone}
+Show times in the selected records using the specified
+time zone instead of UTC.
@end table
@ignore
@@ -9302,7 +9397,7 @@ Contributed examples will gratefully be accepted.
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node import
@appendixsec import---Import sources into CVS, using vendor branches
-@cindex Import (subcommand)
+@cindex import (subcommand)
@c FIXME: This node is way too long for one which has subnodes.
@@ -9444,8 +9539,8 @@ you will have to merge the changes.
@item I @var{file}
The file is being ignored (@pxref{cvsignore}).
-@cindex symbolic link, importing
-@cindex link, symbolic, importing
+@cindex Symbolic link, importing
+@cindex Link, symbolic, importing
@c FIXME: also (somewhere else) probably
@c should be documenting what happens if you "cvs add"
@c a symbolic link. Also maybe what happens if
@@ -9471,7 +9566,7 @@ See @ref{Tracking sources}, and @ref{From files}.
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node log
@appendixsec log---Print out log information for files
-@cindex Log (subcommand)
+@cindex log (subcommand)
@itemize @bullet
@item
@@ -9489,8 +9584,8 @@ determines the format of the output and the options,
which are not quite in the style of the other @sc{cvs}
commands.
-@cindex timezone, in output
-@cindex zone, time, in output
+@cindex Timezone, in output
+@cindex Zone, time, in output
@c Kind of a funny place to document the timezone used
@c in output from commands other than @code{log}.
@c There is also more we need to say about this,
@@ -9672,7 +9767,7 @@ Contributed examples are gratefully accepted.
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node rdiff
@appendixsec rdiff---'patch' format diffs between releases
-@cindex Rdiff (subcommand)
+@cindex rdiff (subcommand)
@itemize @bullet
@item
@@ -9802,7 +9897,7 @@ File bar.h,v changed from revision 1.29.2.1 to 1.2
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node release
@appendixsec release---Indicate that a Module is no longer in use
-@cindex Release (subcommand)
+@cindex release (subcommand)
@itemize @bullet
@item
@@ -9928,7 +10023,7 @@ $
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node update
@appendixsec update---Bring work tree in sync with repository
-@cindex Update (subcommand)
+@cindex update (subcommand)
@itemize @bullet
@item
@@ -10010,6 +10105,11 @@ These special options are also available with
Reset any sticky tags, dates, or @samp{-k} options.
See @ref{Sticky tags}, for more information on sticky tags/dates.
+@item -C
+Overwrite locally modified files with clean copies from
+the repository (the modified file is saved in
+@file{.#@var{file}.@var{revision}}, however).
+
@item -d
Create any directories that exist in the repository if
they're missing from the working directory. Normally,
@@ -10199,7 +10299,7 @@ options}.
Print a help message. See @ref{Global options}.
@item -l
-Do not log in CVSROOT/history file. See @ref{Global
+Do not log in @file{$CVSROOT/CVSROOT/history} file. See @ref{Global
options}.
@item -n
@@ -10233,15 +10333,14 @@ Make new working files read-write. See @ref{Global
options}.
@item -x
-Encrypt all communication (client only). See
-@ref{Global options}.
+Encrypt all communication (client only).
+See @ref{Global options}.
@item -z @var{gzip-level}
+@cindex Compression
+@cindex Gzip
Set the compression level (client only).
-@c FIXME: what are the valid values for gzip-level.
-@c And shouldn't this be documented in at least a
-@c little bit of detail somewhere?
-
+See @ref{Global options}.
@end table
Keyword expansion modes (@pxref{Substitution modes}):
@@ -10884,6 +10983,11 @@ Bring work tree in sync with repository. See
Reset any sticky tags/date/options. See @ref{Sticky
tags} and @ref{Keyword substitution}.
+@item -C
+Overwrite locally modified files with clean copies from
+the repository (the modified file is saved in
+@file{.#@var{file}.@var{revision}}, however).
+
@item -D @var{date}
Check out revisions as of @var{date} (is sticky). See
@ref{Common options}.
@@ -10929,6 +11033,11 @@ Checkout revision @var{tag} (is sticky). See @ref{Common options}.
More wrappers. See @ref{import options}.
@end table
+@item version
+
+Display the version of @sc{cvs} being used. If the repository
+is remote, display both the client and server versions.
+
@item watch [on|off|add|remove] [@var{options}] [@var{files}@dots{}]
on/off: turn on/off read-only checkouts of files. See
@@ -11045,6 +11154,8 @@ a file @file{sfile}.
* Ampersand modules::
* Excluding directories:: Excluding directories from a module
* Module options:: Regular and ampersand modules can take options
+* Module program options:: How the modules ``program options'' programs
+ are run.
@end menu
@node Alias modules
@@ -11218,7 +11329,7 @@ a future release of @sc{cvs}.
@node Excluding directories
@appendixsubsec Excluding directories
-@cindex excluding directories, in modules file
+@cindex Excluding directories, in modules file
@cindex !, in modules file
An alias module may exclude particular directories from
@@ -11241,7 +11352,7 @@ the subdirectory @samp{first-dir/sdir}.
@node Module options
@appendixsubsec Module options
-@cindex options, in modules file
+@cindex Options, in modules file
Either regular modules or ampersand modules can contain
options, which supply additional information concerning
@@ -11327,6 +11438,49 @@ this module.
@c they are no good for security-type stuff.
@end table
+You should also see @pxref{Module program options} about how the
+``program options'' programs are run.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+@node Module program options
+@appendixsubsec How the modules file ``program options'' programs are run
+@cindex Modules file program options
+@cindex -u, in modules file
+@cindex -t, in modules file
+@cindex -o, in modules file
+@cindex -i, in modules file
+@cindex -e, in modules file
+
+@noindent
+For checkout, rtag, and export, the program is server-based, and as such the
+following applies:-
+
+If using remote access methods (pserver, ext, etc.),
+CVS will execute this program on the server from a temporary
+directory. The path is searched for this program.
+
+If using ``local access'' (on a local or remote NFS filesystem, i.e.
+repository set just to a path),
+the program will be executed from the newly checked-out tree, if
+found there, or alternatively searched for in the path if not.
+
+@noindent
+The commit and update programs are locally-based, and are run as
+follows:-
+
+The program is always run locally. One must
+re-checkout the tree one is using if these options are updated in the
+modules administrative file. The file CVS/Checkin.prog contains the
+value of the option `-i' set in the modules file, and similarly for
+the file CVS/Update.prog and `-u'. The program is always executed from
+the top level of the checked-out copy on the client. Again, the program
+is first searched for in the checked-out copy and then using the path.
+
+The programs are all run after the operation has effectively
+completed.
+
+
@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node Wrappers
@appendixsec The cvswrappers file
@@ -11573,7 +11727,7 @@ all have a common format. The purpose of the files are
described later on. The common syntax is described
here.
-@cindex regular expression syntax
+@cindex Regular expression syntax
Each line contains the following:
@itemize @bullet
@item
@@ -11643,7 +11797,7 @@ repository is appended to the template, followed by the
file names of any files involved in the commit (added,
removed, and modified files).
-@cindex exit status, of commitinfo
+@cindex Exit status, of commitinfo
The first line with a regular expression matching the
directory within the repository will be used. If the
command returns a non-zero exit status the commit will
@@ -11661,7 +11815,7 @@ All occurrences of the name @samp{ALL} appearing as a
regular expression are used in addition to the first
matching regular expression or the name @samp{DEFAULT}.
-Note: when @sc{CVS} is accessing a remote repository,
+Note: when @sc{cvs} is accessing a remote repository,
@file{commitinfo} will be run on the @emph{remote}
(i.e., server) side, not the client side (@pxref{Remote
repositories}).
@@ -11686,7 +11840,7 @@ repositories}).
@node verifymsg
@appendixsec Verifying log messages
@cindex verifymsg (admin file)
-@cindex log message, verifying
+@cindex Log message, verifying
Once you have entered a log message, you can evaluate
that message to check for specific content, such as
@@ -11716,7 +11870,7 @@ If the repository name does not match any of the
regular expressions in this file, the @samp{DEFAULT}
line is used, if it is specified.
-@cindex exit status, of verifymsg
+@cindex Exit status, of verifymsg
If the verification script exits with a non-zero exit status,
the commit is aborted.
@@ -11829,7 +11983,7 @@ line is used, if it is specified.
If the edit script exits with a non-zero exit status,
the commit is aborted.
-Note: when @sc{CVS} is accessing a remote repository,
+Note: when @sc{cvs} is accessing a remote repository,
or when the @samp{-m} or @samp{-F} options to @code{cvs
commit} are used, @file{editinfo} will not be consulted.
There is no good workaround for this; use
@@ -11950,22 +12104,22 @@ For example, some valid format strings are @samp{%},
The output will be a string of tokens separated by
spaces. For backwards compatibility, the first
-token will be the repository name. The rest of the
+token will be the repository subdirectory. The rest of the
tokens will be comma-delimited lists of the information
requested in the format string. For example, if
-@samp{/u/src/master} is the repository, @samp{%@{sVv@}}
+@samp{/u/src/master/yoyodyne/tc} is the repository, @samp{%@{sVv@}}
is the format string, and three files (@t{ChangeLog},
@t{Makefile}, @t{foo.c}) were modified, the output
might be:
@example
-/u/src/master ChangeLog,1.1,1.2 Makefile,1.3,1.4 foo.c,1.12,1.13
+yoyodyne/tc ChangeLog,1.1,1.2 Makefile,1.3,1.4 foo.c,1.12,1.13
@end example
As another example, @samp{%@{@}} means that only the
name of the repository will be generated.
-Note: when @sc{CVS} is accessing a remote repository,
+Note: when @sc{cvs} is accessing a remote repository,
@file{loginfo} will be run on the @emph{remote}
(i.e., server) side, not the client side (@pxref{Remote
repositories}).
@@ -12017,9 +12171,9 @@ like this:
@c What other index entries? It seems like
@c people might want to use a lot of different
@c words for this functionality.
-@cindex keeping a checked out copy
-@cindex checked out copy, keeping
-@cindex web pages, maintaining with CVS
+@cindex Keeping a checked out copy
+@cindex Checked out copy, keeping
+@cindex Web pages, maintaining with CVS
It is often useful to maintain a directory tree which
contains files which correspond to the latest version
@@ -12107,7 +12261,7 @@ template.
@xref{verifymsg}, for an example @file{rcsinfo}
file.
-When @sc{CVS} is accessing a remote repository,
+When @sc{cvs} is accessing a remote repository,
the contents of @file{rcsinfo} at the time a directory
is first checked out will specify a template which does
not then change. If you edit @file{rcsinfo} or its
@@ -12290,6 +12444,8 @@ format changes with future releases of @sc{cvs}.
@node Variables
@appendixsec Expansions in administrative files
+@cindex Internal variables
+@cindex Variables
Sometimes in writing an administrative file, you might
want the file to be able to know various things based
@@ -12321,11 +12477,13 @@ internal variables are:
@table @code
@item CVSROOT
+@cindex CVSROOT, internal variable
This is the value of the @sc{cvs} root in use.
@xref{Repository}, for a description of the various
ways to specify this.
@item RCSBIN
+@cindex RCSBIN, internal variable
In @sc{cvs} 1.9.18 and older, this specified the
directory where @sc{cvs} was looking for @sc{rcs}
programs. Because @sc{cvs} no longer runs @sc{rcs}
@@ -12333,20 +12491,29 @@ programs, specifying this internal variable is now an
error.
@item CVSEDITOR
+@cindex CVSEDITOR, internal variable
@itemx VISUAL
+@cindex VISUAL, internal variable
@itemx EDITOR
+@cindex EDITOR, internal variable
These all expand to the same value, which is the editor
that @sc{cvs} is using. @xref{Global options}, for how
to specify this.
@item USER
+@cindex USER, internal variable
Username of the user running @sc{cvs} (on the @sc{cvs}
server machine).
+When using pserver, this is the user specified in the repository
+specification which need not be the same as the username the
+server is running as (@pxref{Password authentication server}).
@end table
If you want to pass a value to the administrative files
which the user who is running @sc{cvs} can specify,
-use a user variable. To expand a user variable, the
+use a user variable.
+@cindex User variables
+To expand a user variable, the
administrative file contains
@code{$@{=@var{variable}@}}. To set a user variable,
specify the global option @samp{-s} to @sc{cvs}, with
@@ -12413,6 +12580,7 @@ pserver users must exist in @file{CVSROOT/passwd}.
The default is @samp{yes}. For more on pserver, see
@ref{Password authenticated}.
+@ignore
@cindex PreservePermissions, in CVSROOT/config
@item PreservePermissions=@var{value}
Enable support for saving special device files,
@@ -12420,6 +12588,7 @@ symbolic links, file permissions and ownerships in the
repository. The default value is @samp{no}.
@xref{Special Files}, for the full implications of using
this keyword.
+@end ignore
@cindex TopLevelAdmin, in CVSROOT/config
@item TopLevelAdmin=@var{value}
@@ -12432,10 +12601,10 @@ The default value is @samp{no}.
This option is useful if you find yourself performing
many commands at the top level of your working
directory, rather than in one of the checked out
-subdirectories. The @samp{CVS} directory created there
-will mean you don't have to specify @samp{CVSROOT} for
+subdirectories. The @file{CVS} directory created there
+will mean you don't have to specify @code{CVSROOT} for
each command. It also provides a place for the
-@samp{CVS/Template} file (@pxref{Working directory
+@file{CVS/Template} file (@pxref{Working directory
storage}).
@cindex LockDir, in CVSROOT/config
@@ -12460,6 +12629,14 @@ put them another place, and therefore the repository
could become corrupted. CVS 1.10 does not support
LockDir but it will print a warning if run on a
repository with LockDir enabled.
+
+@cindex LogHistory, in CVSROOT/config
+@item LogHistory=@var{value}
+Control what is logged to the @file{CVSROOT/history} file.
+Default of @samp{TOFEWGCMAR} (or simply @samp{all}) will log
+all transactions. Any subset of the default is
+legal. (For example, to only log transactions that modify the
+@file{*,v} files, use @samp{LogHistory=TMAR}.)
@end table
@c ---------------------------------------------------------------------
@@ -12483,7 +12660,7 @@ A whitespace-separated list of file name patterns that
@sc{cvs} should treat as wrappers. @xref{Wrappers}.
@cindex CVSREAD, environment variable
-@cindex read-only files, and CVSREAD
+@cindex Read-only files, and CVSREAD
@item $CVSREAD
If this is set, @code{checkout} and @code{update} will
try hard to make the files in your working directory
@@ -12528,10 +12705,10 @@ programs it uses.
@item $HOMEDRIVE
Used to locate the directory where the @file{.cvsrc}
file, and other such files, are searched. On Unix, CVS
-just checks for HOME. On Windows NT, the system will
-set HOMEDRIVE, for example to @samp{d:} and HOMEPATH,
+just checks for @code{HOME}. On Windows NT, the system will
+set @code{HOMEDRIVE}, for example to @samp{d:} and @code{HOMEPATH},
for example to @file{\joe}. On Windows 95, you'll
-probably need to set HOMEDRIVE and HOMEPATH yourself.
+probably need to set @code{HOMEDRIVE} and @code{HOMEPATH} yourself.
@c We are being vague about whether HOME works on
@c Windows; see long comment in windows-NT/filesubr.c.
@@ -12567,9 +12744,9 @@ the server side. (Currently not used for Unix clients).
@cindex CVS_CLIENT_LOG, environment variable
@item $CVS_CLIENT_LOG
Used for debugging only in client-server
-mode. If set, everything send to the server is logged
+mode. If set, everything sent to the server is logged
into @file{@code{$CVS_CLIENT_LOG}.in} and everything
-send from the server is logged into
+sent from the server is logged into
@file{@code{$CVS_CLIENT_LOG}.out}.
@cindex CVS_SERVER_SLEEP, environment variable
@@ -12585,7 +12762,7 @@ For @sc{cvs} 1.10 and older, setting this variable
prevents @sc{cvs} from overwriting the @file{CVS/Root}
file when the @samp{-d} global option is specified.
Later versions of @sc{cvs} do not rewrite
-@file{CVS/Root}, so CVS_IGNORE_REMOTE_ROOT has no
+@file{CVS/Root}, so @code{CVS_IGNORE_REMOTE_ROOT} has no
effect.
@cindex COMSPEC, environment variable
@@ -12599,7 +12776,7 @@ command interpreter and defaults to @sc{cmd.exe}.
@itemx $TMP
@cindex TEMP, environment variable
@itemx $TEMP
-@cindex temporary files, location of
+@cindex Temporary files, location of
@c This is quite nuts. We don't talk about tempnam
@c or mkstemp which we sometimes use. The discussion
@c of "Global options" is semi-incoherent.
@@ -12628,8 +12805,8 @@ if your server and client are both running @sc{cvs}
@appendix Compatibility between CVS Versions
@cindex CVS, versions of
-@cindex versions, of CVS
-@cindex compatibility, between CVS versions
+@cindex Versions, of CVS
+@cindex Compatibility, between CVS versions
@c We don't mention versions older than CVS 1.3
@c on the theory that it would clutter it up for the vast
@c majority of people, who don't have anything that old.
@@ -12760,8 +12937,8 @@ This is a generic response when trying to connect to a
pserver server which chooses not to provide a
specific reason for denying authorization. Check that
the username and password specified are correct and
-that the CVSROOT specified is allowed by --allow-root
-in inetd.conf. See @ref{Password authenticated}.
+that the @code{CVSROOT} specified is allowed by @samp{--allow-root}
+in @file{inetd.conf}. See @ref{Password authenticated}.
@item @var{file}:@var{line}: Assertion '@var{text}' failed
The exact format of this message may vary depending on
@@ -12880,7 +13057,7 @@ bug (@pxref{BUGS}).
@item cvs [login aborted]: could not find out home directory
This means that you need to set the environment
variables that CVS uses to locate your home directory.
-See the discussion of HOME, HOMEDRIVE, and HOMEPATH in
+See the discussion of @code{HOME}, @code{HOMEDRIVE}, and @code{HOMEPATH} in
@ref{Environment variables}.
@item cvs update: could not merge revision @var{rev} of @var{file}: No such file or directory
@@ -13011,8 +13188,9 @@ other than CVS. If not, it indicates a CVS bug
This message will be followed by a usage message for
@sc{rcs}. It means that you have an old version of
@sc{rcs} (probably supplied with your operating
-system). CVS only works with @sc{rcs} version 5 and
-later.
+system), as well as an old version of @sc{cvs}.
+@sc{cvs} 1.9.18 and earlier only work with @sc{rcs} version 5 and
+later; current versions of @sc{cvs} do not run @sc{rcs} programs.
@c For more information on installing @sc{cvs}, see
@c (FIXME: where? it depends on whether you are
@c getting binaries or sources or what).
@@ -13056,6 +13234,10 @@ find the log file which inetd writes
your system). For details, see @ref{Connection}, and
@ref{Password authentication server}.
+@item cvs server: cannot open /root/.cvsignore: Permission denied
+@itemx cvs [server aborted]: can't chdir(/root): Permission denied
+See @ref{Connection}.
+
@item cvs commit: Up-to-date check failed for `@var{file}'
This means that someone else has committed a change to
that file since the last time that you did a @code{cvs
@@ -13063,9 +13245,9 @@ update}. So before proceeding with your @code{cvs
commit} you need to @code{cvs update}. CVS will merge
the changes that you made and the changes that the
other person made. If it does not detect any conflicts
-it will report @samp{M cacErrCodes.h} and you are ready
+it will report @samp{M @var{file}} and you are ready
to @code{cvs commit}. If it detects conflicts it will
-print a message saying so, will report @samp{C cacErrCodes.h},
+print a message saying so, will report @samp{C @var{file}},
and you need to manually resolve the
conflict. For more details on this process see
@ref{Conflicts example}.
@@ -13105,11 +13287,11 @@ This is a normal message, not an error. See
@ref{Concurrency}, for more details.
@item cvs commit: warning: editor session failed
-@cindex exit status, of editor
+@cindex Exit status, of editor
This means that the editor which @sc{cvs} is using exits with a nonzero
exit status. Some versions of vi will do this even when there was not
a problem editing the file. If so, point the
-@sc{CVSEDITOR} environment variable to a small script
+@code{CVSEDITOR} environment variable to a small script
such as:
@example
@@ -13166,7 +13348,7 @@ cvs [pserver aborted]: bad auth protocol start: foo
@end example
If this fails to work, then make sure inetd is working
-right. Change the invocation in inetd.conf to run the
+right. Change the invocation in @file{inetd.conf} to run the
echo program instead of cvs. For example:
@example
@@ -13189,6 +13371,29 @@ to address this problem.
Another good debugging tool is the @samp{-d}
(debugging) option to inetd. Consult your system
documentation for more information.
+
+If you seem to be connecting but get errors like:
+
+@example
+cvs server: cannot open /root/.cvsignore: Permission denied
+cvs [server aborted]: can't chdir(/root): Permission denied
+@end example
+
+then either you haven't specified @samp{-f} in @file{inetd.conf}
+or your system is setting the @code{HOME} environment variable
+for programs being run by inetd. In the latter case, you can either
+have inetd run a shell script that unsets @code{HOME} and then runs
+@sc{cvs}, or you can use @code{env} to run @sc{cvs} with a pristine
+environment.
+
+If you can connect successfully for a while but then can't,
+you've probably hit inetd's rate limit.
+(If inetd receives too many requests for the same service
+in a short period of time, it assumes that something is wrong
+and temporarily disables the service.)
+Check your inetd documentation to find out how to adjust the
+rate limit (some versions of inetd have a single rate limit,
+others allow you to set the limit for each service separately.)
@end table
@node Other problems
@@ -13288,7 +13493,6 @@ report, there are companies which will do that for a
fee. Two such companies are:
@cindex Signum Support
-@cindex Cyclic Software
@cindex Support, getting CVS support
@example
Signum Support AB
@@ -13300,10 +13504,6 @@ Phone: +46 (0)13 - 21 46 00
Fax: +46 (0)13 - 21 47 00
http://www.signum.se/
-Cyclic Software
-United States of America
-http://www.cyclic.com/
-info@@cyclic.com
@end example
@item
@@ -13327,7 +13527,7 @@ There may be resources on the net which can help. Two
good places to start are:
@example
-http://www.cyclic.com
+http://www.cvshome.org
http://www.loria.fr/~molli/cvs-index.html
@end example
diff --git a/contrib/cvs/doc/cvsclient.texi b/contrib/cvs/doc/cvsclient.texi
index 394c0ca..5ba7ed6 100644
--- a/contrib/cvs/doc/cvsclient.texi
+++ b/contrib/cvs/doc/cvsclient.texi
@@ -3,6 +3,11 @@
@setfilename cvsclient.info
@include CVSvn.texi
+@dircategory Programming
+@direntry
+* cvsclient: (cvsclient). The CVS client/server protocol.
+@end direntry
+
@node Top
@top CVS Client/Server
@@ -492,7 +497,7 @@ command line client (versions 1.5 through at least 1.9).
For the @samp{-d} option to the @code{log} request, servers should at
least support RFC 822/1123 format. Clients are encouraged to use this
-format too (traditionally the command line CVS client has just passed
+format too (the command line CVS client, version 1.10 and older, just passed
along the date format specified by the user, however).
The @code{Mod-time} response and @code{Checkin-time} request use RFC
@@ -537,16 +542,19 @@ in use, connection, authentication, etc., are already taken care of.
The @code{Root} request must be sent only once, and it must be sent
before any requests other than @code{Valid-responses},
-@code{valid-requests}, @code{UseUnchanged}, @code{Set} or @code{init}.
+@code{valid-requests}, @code{UseUnchanged}, @code{Set},
+@code{Global_option}, @code{init}, @code{noop}, or @code{version}.
@item Valid-responses @var{request-list} \n
Response expected: no.
Tell the server what responses the client will accept.
request-list is a space separated list of tokens.
+The @code{Root} request need not have been previously sent.
@item valid-requests \n
Response expected: yes.
Ask the server to send back a @code{Valid-requests} response.
+The @code{Root} request need not have been previously sent.
@item Directory @var{local-directory} \n
Additional data: @var{repository} \n. Response expected: no.
@@ -859,6 +867,7 @@ must not contain @samp{/}.
Response expected: no. To specify the version of the protocol described
in this document, servers must support this request (although it need
not do anything) and clients must issue it.
+The @code{Root} request need not have been previously sent.
@item Notify @var{filename} \n
Response expected: no.
@@ -950,6 +959,7 @@ strings, no variations (such as combining of options) are allowed. For
graceful handling of @code{valid-requests}, it is probably better to
make new global options separate requests, rather than trying to add
them to this request.
+The @code{Root} request need not have been previously sent.
@item Gzip-stream @var{level} \n
Response expected: no.
@@ -1007,6 +1017,7 @@ connection between the initial authentication and the
@item Set @var{variable}=@var{value} \n
Response expected: no.
Set a user variable @var{variable} to @var{value}.
+The @code{Root} request need not have been previously sent.
@item expand-modules \n
Response expected: yes. Expand the modules which are specified in the
@@ -1064,7 +1075,6 @@ directory.
@itemx diff \n
@itemx tag \n
@itemx status \n
-@itemx log \n
@itemx admin \n
@itemx history \n
@itemx watchers \n
@@ -1078,6 +1088,56 @@ of the operation. No provision is made for any input from the user.
This means that @code{ci} must use a @code{-m} argument if it wants to
specify a log message.
+@item log \n
+Response expected: yes. Show information for past revisions. This uses
+any previous @code{Directory}, @code{Entry}, or @code{Modified}
+requests, if they have been sent. The last @code{Directory} sent
+specifies the working directory at the time of the operation. Also uses
+previous @code{Argument}'s of which the canonical forms are the
+following (@sc{cvs} 1.10 and older clients sent what the user specified,
+but clients are encouraged to use the canonical forms and other forms
+are deprecated):
+
+@table @code
+@item -b, -h, -l, -N, -R, -t
+These options go by themselves, one option per @code{Argument} request.
+
+@item -d @var{date1}<@var{date2}
+Select revisions between @var{date1} and @var{date2}. Either date
+may be omitted in which case there is no date limit at that end of the
+range (clients may specify dates such as 1 Jan 1970 or 1 Jan 2038 for
+similar purposes but this is problematic as it makes assumptions about
+what dates the server supports). Dates are in RFC822/1123 format. The
+@samp{-d} is one @code{Argument} request and the date range is a second
+one.
+
+@item -d @var{date1}<=@var{date2}
+Likewise but compare dates for equality.
+
+@item -d @var{singledate}
+Select the single, latest revision dated @var{singledate} or earlier.
+
+To include several date ranges and/or singledates, repeat the @samp{-d}
+option as many times as necessary.
+
+@item -r@var{rev1}:@var{rev2}
+@itemx -r@var{branch}
+@itemx -r@var{branch}.
+@itemx -r
+Specify revisions (note that @var{rev1} or @var{rev2} can be omitted, or
+can refer to branches). Send both the @samp{-r} and the revision
+information in a single @code{Argument} request. To include several
+revision selections, repeat the @samp{-r} option.
+
+@item -s @var{state}
+@itemx -w
+@itemx -w@var{login}
+Select on states or users. To include more than one state or user,
+repeat the option. Send the @samp{-s} option as a separate argument
+from the state being selected. Send the @samp{-w} option as part of the
+same argument as the user being selected.
+@end table
+
@item co \n
Response expected: yes. Get files from the repository. This uses any
previous @code{Argument}, @code{Directory}, @code{Entry}, or
@@ -1111,8 +1171,8 @@ commands are module names, as described for @code{co}.
@item init @var{root-name} \n
Response expected: yes. If it doesn't already exist, create a @sc{cvs}
repository @var{root-name}. Note that @var{root-name} is a local
-directory and @emph{not} a fully qualified @code{CVSROOT} variable. The
-@code{Root} request need not have been previously sent.
+directory and @emph{not} a fully qualified @code{CVSROOT} variable.
+The @code{Root} request need not have been previously sent.
@item update \n
Response expected: yes. Actually do a @code{cvs update} command. This
@@ -1245,6 +1305,7 @@ Response expected: yes. This request is a null command in the sense
that it doesn't do anything, but merely (as with any other requests
expecting a response) sends back any responses pertaining to pending
errors, pending @code{Notified} responses, etc.
+The @code{Root} request need not have been previously sent.
@item update-patches \n
Response expected: yes.
@@ -1277,6 +1338,11 @@ Response expected: yes.
Request that the server transmit mappings from filenames to keyword
expansion modes in @code{Wrapper-rcsOption} responses.
+@item version \n
+Response expected: yes.
+Request that the server transmit its version message.
+The @code{Root} request need not have been previously sent.
+
@item @var{other-request} @var{text} \n
Response expected: yes.
Any unrecognized request expects a response, and does not
@@ -1934,8 +2000,8 @@ working directory, and the meaning of sending @code{Entries} without
A number of enhancements are possible. Also see the file @sc{todo} in
the @sc{cvs} source distribution, which has further ideas concerning
various aspects of @sc{cvs}, some of which impact the protocol.
-Similarly, the @code{http://www.cyclic.com} site, in particular the
-@cite{Development of CVS} page.
+Similarly, the @code{http://www.cvshome.org} site, in particular the
+@cite{Development} pages.
@itemize @bullet
@item
diff --git a/contrib/cvs/install-sh b/contrib/cvs/install-sh
index ab74c88..402d456 100755
--- a/contrib/cvs/install-sh
+++ b/contrib/cvs/install-sh
@@ -10,6 +10,7 @@
# This script is compatible with the BSD install script, but was written
# from scratch.
#
+#
# set DOITPROG to echo to test this script
diff --git a/contrib/cvs/lib/ChangeLog b/contrib/cvs/lib/ChangeLog
index 37cc6ab..102ca4c 100644
--- a/contrib/cvs/lib/ChangeLog
+++ b/contrib/cvs/lib/ChangeLog
@@ -1,3 +1,46 @@
+2000-07-10 Larry Jones <larry.jones@sdrc.com>
+
+ * savecwd.c: #include <sys/types.h> before <fcntl.h>.
+
+2000-07-04 Karl Fogel <kfogel@red-bean.com>
+
+ * getline.h, getline.c (getstr): take new limit arg.
+ (GETLINE_NO_LIMIT): new #define.
+ (getline_safe): new function, takes limit arg and passes it on.
+ (getline): pass GETLINE_NO_LIMIT to getstr().
+
+ See related change of same date in ../src/ChangeLog.
+
+2000-06-19 Larry Jones <larry.jones@sdrc.com>
+
+ * regex.c, regex.h: Version from emacs 20.7 to plug memory leaks
+ and avoid potential portability problems.
+
+2000-03-22 Larry Jones <larry.jones@sdrc.com>
+
+ * getdate.y: Add logic to allow yyyy/mm/dd in addition to mm/dd/yy
+ (since that is the format CVS frequently uses).
+ * getdate.c: Regenerated.
+
+2000-02-16 Jim Meyering <meyering@lucent.com>
+
+ * sighandle.c (SIG_inCrSect): New function.
+
+2000-01-03 Larry Jones <larry.jones@sdrc.com>
+
+ * getdate.y (Convert): Add window to determine whether 2-digit dates
+ are 19xx (69-99) or 20xx (00-68).
+ (get_date): Fix y2k bug: initialize yyYear to tm_year + 1900,
+ not just tm_year.
+ * getdate.c: Regenerated.
+
+1999-12-29 Jim Kingdon <http://developer.redhat.com/>
+
+ * Makefile.in: There was a comment here which referred to a long
+ comment in configure.in about regex.o (the configure.in comment
+ isn't there any more). Replace our comment with a conciser
+ version of the former configure.in comment.
+
1999-03-26 Jim Kingdon <http://www.cyclic.com>
* getopt.h: Don't declare the arguments to getopt.
diff --git a/contrib/cvs/lib/Makefile.in b/contrib/cvs/lib/Makefile.in
index f35baae..736f131 100644
--- a/contrib/cvs/lib/Makefile.in
+++ b/contrib/cvs/lib/Makefile.in
@@ -52,7 +52,16 @@ SOURCES = \
HEADERS = getline.h getopt.h fnmatch.h regex.h system.h wait.h md5.h savecwd.h
-# See long comment in ../configure.in concerning inclusion of regex.o.
+# Always use CVS's regular expression matcher regex.o, because of
+# variations in regular expression syntax - we want to be the same
+# across systems and (probably) compared with old versions of CVS too.
+#
+# On a more mundane/detail level, having regex.h match regex.c can be
+# an issue if we aren't careful.
+#
+# Also should look into unifying regular expression matching in CVS
+# with the diff library (perhaps to have the caller, CVS, do the
+# matching?)
OBJECTS = \
@LIBOBJS@ \
argmatch.o \
diff --git a/contrib/cvs/lib/getdate.y b/contrib/cvs/lib/getdate.y
index 9a4a8fa..c3f18c6 100644
--- a/contrib/cvs/lib/getdate.y
+++ b/contrib/cvs/lib/getdate.y
@@ -281,9 +281,15 @@ date : tUNUMBER '/' tUNUMBER {
yyDay = $3;
}
| tUNUMBER '/' tUNUMBER '/' tUNUMBER {
- yyMonth = $1;
- yyDay = $3;
- yyYear = $5;
+ if ($1 >= 100) {
+ yyYear = $1;
+ yyMonth = $3;
+ yyDay = $5;
+ } else {
+ yyMonth = $1;
+ yyDay = $3;
+ yyYear = $5;
+ }
}
| tUNUMBER tSNUMBER tSNUMBER {
/* ISO 8601 format. yyyy-mm-dd. */
@@ -643,7 +649,9 @@ Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
if (Year < 0)
Year = -Year;
- if (Year < 100)
+ if (Year < 69)
+ Year += 2000;
+ else if (Year < 100)
Year += 1900;
DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
? 29 : 28;
@@ -957,7 +965,7 @@ get_date(p, now)
}
tm = localtime(&nowtime);
- yyYear = tm->tm_year;
+ yyYear = tm->tm_year + 1900;
yyMonth = tm->tm_mon + 1;
yyDay = tm->tm_mday;
yyTimezone = now->timezone;
diff --git a/contrib/cvs/lib/getline.c b/contrib/cvs/lib/getline.c
index 5b63fc1..84d7fce 100644
--- a/contrib/cvs/lib/getline.c
+++ b/contrib/cvs/lib/getline.c
@@ -22,6 +22,7 @@ General Public License for more details. */
#include <stdio.h>
#include <assert.h>
#include <errno.h>
+#include "getline.h"
#if STDC_HEADERS
#include <stdlib.h>
@@ -33,20 +34,25 @@ char *malloc (), *realloc ();
#define MIN_CHUNK 64
/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
- + OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
- malloc (or NULL), pointing to *N characters of space. It is realloc'd
- as necessary. Return the number of characters read (not including the
- null terminator), or -1 on error or EOF. On a -1 return, the caller
- should check feof(), if not then errno has been set to indicate
- the error. */
+ + OFFSET (and null-terminate it). If LIMIT is non-negative, then
+ read no more than LIMIT chars.
+
+ *LINEPTR is a pointer returned from malloc (or NULL), pointing to
+ *N characters of space. It is realloc'd as necessary.
+
+ Return the number of characters read (not including the null
+ terminator), or -1 on error or EOF. On a -1 return, the caller
+ should check feof(), if not then errno has been set to indicate the
+ error. */
int
-getstr (lineptr, n, stream, terminator, offset)
+getstr (lineptr, n, stream, terminator, offset, limit)
char **lineptr;
size_t *n;
FILE *stream;
char terminator;
int offset;
+ int limit;
{
int nchars_avail; /* Allocated but unused chars in *LINEPTR. */
char *read_pos; /* Where we're reading into *LINEPTR. */
@@ -75,7 +81,19 @@ getstr (lineptr, n, stream, terminator, offset)
for (;;)
{
int save_errno;
- register int c = getc (stream);
+ register int c;
+
+ if (limit == 0)
+ break;
+ else
+ {
+ c = getc (stream);
+
+ /* If limit is negative, then we shouldn't pay attention to
+ it, so decrement only if positive. */
+ if (limit > 0)
+ limit--;
+ }
save_errno = errno;
@@ -141,5 +159,15 @@ getline (lineptr, n, stream)
size_t *n;
FILE *stream;
{
- return getstr (lineptr, n, stream, '\n', 0);
+ return getstr (lineptr, n, stream, '\n', 0, GETLINE_NO_LIMIT);
+}
+
+int
+getline_safe (lineptr, n, stream, limit)
+ char **lineptr;
+ size_t *n;
+ FILE *stream;
+ int limit;
+{
+ return getstr (lineptr, n, stream, '\n', 0, limit);
}
diff --git a/contrib/cvs/lib/getline.h b/contrib/cvs/lib/getline.h
index d061b7c..93a30eb 100644
--- a/contrib/cvs/lib/getline.h
+++ b/contrib/cvs/lib/getline.h
@@ -9,10 +9,15 @@
#define __PROTO(args) ()
#endif /* GCC. */
+#define GETLINE_NO_LIMIT -1
+
int
getline __PROTO ((char **_lineptr, size_t *_n, FILE *_stream));
int
+ getline_safe __PROTO ((char **_lineptr, size_t *_n, FILE *_stream,
+ int limit));
+int
getstr __PROTO ((char **_lineptr, size_t *_n, FILE *_stream,
- char _terminator, int _offset));
+ char _terminator, int _offset, int limit));
#endif /* _getline_h_ */
diff --git a/contrib/cvs/lib/regex.c b/contrib/cvs/lib/regex.c
index 38b31f4..1c3ab8d 100644
--- a/contrib/cvs/lib/regex.c
+++ b/contrib/cvs/lib/regex.c
@@ -2,7 +2,7 @@
0.12. (Implements POSIX draft P10003.2/D11.2, except for
internationalization features.)
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -11,25 +11,50 @@
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. */
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-/* Trying to define this in the makefile would get hairy, unless we can
- more gracefully do it for NT, OS/2, unix, etc. */
-#define REGEX_MALLOC 1
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
/* AIX requires this to be the first thing in the file. */
#if defined (_AIX) && !defined (REGEX_MALLOC)
#pragma alloca
#endif
+#undef _GNU_SOURCE
#define _GNU_SOURCE
-/* We need this for `regex.h', and perhaps for the Emacs include files. */
-#include <sys/types.h>
+#ifdef emacs
+/* Converts the pointer to the char to BEG-based offset from the start. */
+#define PTR_TO_OFFSET(d) \
+ POS_AS_IN_BUFFER (MATCHING_IN_FIRST_STRING \
+ ? (d) - string1 : (d) - (string2 - size1))
+#define POS_AS_IN_BUFFER(p) ((p) + (NILP (re_match_object) || BUFFERP (re_match_object)))
+#else
+#define PTR_TO_OFFSET(d) 0
+#endif
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
+#endif
+
+/* We need this for `regex.h', and perhaps for the Emacs include files. */
+#include <sys/types.h>
+
+/* This is for other GNU distributions with internationalized messages. */
+#if HAVE_LIBINTL_H || defined (_LIBC)
+# include <libintl.h>
+#else
+# define gettext(msgid) (msgid)
+#endif
+
+#ifndef gettext_noop
+/* This define is so xgettext can find the internationalizable
+ strings. */
+#define gettext_noop(String) String
#endif
/* The `emacs' switch turns on certain matching commands
@@ -47,13 +72,38 @@
#include "category.h"
#define malloc xmalloc
+#define realloc xrealloc
#define free xfree
#else /* not emacs */
-/* 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
+/* If we are not linking with Emacs proper,
+ we can't use the relocating allocator
+ even if config.h says that we can. */
+#undef REL_ALLOC
+
+#if defined (STDC_HEADERS) || defined (_LIBC)
+#include <stdlib.h>
+#else
+char *malloc ();
+char *realloc ();
+#endif
+
+/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
+ If nothing else has been done, use the method below. */
+#ifdef INHIBIT_STRING_HEADER
+#if !(defined (HAVE_BZERO) && defined (HAVE_BCOPY))
+#if !defined (bzero) && !defined (bcopy)
+#undef INHIBIT_STRING_HEADER
+#endif
+#endif
+#endif
+
+/* This is the normal way of making sure we have a bcopy and a bzero.
+ This is used in most programs--a few other programs avoid this
+ by defining INHIBIT_STRING_HEADER. */
+#ifndef INHIBIT_STRING_HEADER
+#if defined (HAVE_STRING_H) || defined (STDC_HEADERS) || defined (_LIBC)
#include <string.h>
#ifndef bcmp
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
@@ -67,15 +117,8 @@
#else
#include <strings.h>
#endif
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#else
-char *malloc ();
-char *realloc ();
#endif
-
/* Define the syntax stuff for \<, \>, etc. */
/* This must be nonzero for the wordchar and notwordchar pattern
@@ -84,6 +127,12 @@ char *realloc ();
#define Sword 1
#endif
+#ifdef SWITCH_ENUM_BUG
+#define SWITCH_ENUM_CAST(x) ((int)(x))
+#else
+#define SWITCH_ENUM_CAST(x) (x)
+#endif
+
#ifdef SYNTAX_TABLE
extern char *re_syntax_table;
@@ -124,6 +173,19 @@ init_syntax_once ()
#define SYNTAX(c) re_syntax_table[c]
+/* Dummy macros for non-Emacs environments. */
+#define BASE_LEADING_CODE_P(c) (0)
+#define WORD_BOUNDARY_P(c1, c2) (0)
+#define CHAR_HEAD_P(p) (1)
+#define SINGLE_BYTE_CHAR_P(c) (1)
+#define SAME_CHARSET_P(c1, c2) (1)
+#define MULTIBYTE_FORM_LENGTH(p, s) (1)
+#define STRING_CHAR(p, s) (*(p))
+#define STRING_CHAR_AND_LENGTH(p, s, actual_len) ((actual_len) = 1, *(p))
+#define GET_CHAR_AFTER_2(c, p, str1, end1, str2, end2) \
+ (c = ((p) == (end1) ? *(str2) : *(p)))
+#define GET_CHAR_BEFORE_2(c, p, str1, end1, str2, end2) \
+ (c = ((p) == (str2) ? *((end1) - 1) : *((p) - 1)))
#endif /* not emacs */
/* Get the interface, including the syntax bits. */
@@ -132,34 +194,47 @@ init_syntax_once ()
/* isalpha etc. are used for the character classes. */
#include <ctype.h>
-#ifndef isascii
-#define isascii(c) 1
+/* Jim Meyering writes:
+
+ "... Some ctype macros are valid only for character codes that
+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
+ using /bin/cc or gcc but without giving an ansi option). So, all
+ ctype uses should be through macros like ISPRINT... If
+ STDC_HEADERS is defined, then autoconf has verified that the ctype
+ macros don't need to be guarded with references to isascii. ...
+ Defining isascii to 1 should let any compiler worth its salt
+ eliminate the && through constant folding." */
+
+#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
+#define ISASCII(c) 1
+#else
+#define ISASCII(c) isascii(c)
#endif
#ifdef isblank
-#define ISBLANK(c) (isascii (c) && isblank (c))
+#define ISBLANK(c) (ISASCII (c) && isblank (c))
#else
#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
#ifdef isgraph
-#define ISGRAPH(c) (isascii (c) && isgraph (c))
+#define ISGRAPH(c) (ISASCII (c) && isgraph (c))
#else
-#define ISGRAPH(c) (isascii (c) && isprint (c) && !isspace (c))
+#define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
#endif
-#define ISPRINT(c) (isascii (c) && isprint (c))
-#define ISDIGIT(c) (isascii (c) && isdigit (c))
-#define ISALNUM(c) (isascii (c) && isalnum (c))
-#define ISALPHA(c) (isascii (c) && isalpha (c))
-#define ISCNTRL(c) (isascii (c) && iscntrl (c))
-#define ISLOWER(c) (isascii (c) && islower (c))
-#define ISPUNCT(c) (isascii (c) && ispunct (c))
-#define ISSPACE(c) (isascii (c) && isspace (c))
-#define ISUPPER(c) (isascii (c) && isupper (c))
-#define ISXDIGIT(c) (isascii (c) && isxdigit (c))
+#define ISPRINT(c) (ISASCII (c) && isprint (c))
+#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
+#define ISALNUM(c) (ISASCII (c) && isalnum (c))
+#define ISALPHA(c) (ISASCII (c) && isalpha (c))
+#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
+#define ISLOWER(c) (ISASCII (c) && islower (c))
+#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
+#define ISSPACE(c) (ISASCII (c) && isspace (c))
+#define ISUPPER(c) (ISASCII (c) && isupper (c))
+#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
#ifndef NULL
-#define NULL 0
+#define NULL (void *)0
#endif
/* We remove any previous definition of `SIGN_EXTEND_CHAR',
@@ -188,6 +263,7 @@ init_syntax_once ()
#define REGEX_ALLOCATE malloc
#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
+#define REGEX_FREE free
#else /* not REGEX_MALLOC */
@@ -201,10 +277,12 @@ init_syntax_once ()
#if HAVE_ALLOCA_H
#include <alloca.h>
#else /* not __GNUC__ or HAVE_ALLOCA_H */
-#ifndef _AIX /* Already did AIX, up at the top. */
+#if 0 /* It is a bad idea to declare alloca. We always cast the result. */
+#ifndef _AIX /* Already did AIX, up at the top. */
char *alloca ();
#endif /* not _AIX */
-#endif /* not HAVE_ALLOCA_H */
+#endif
+#endif /* not HAVE_ALLOCA_H */
#endif /* not __GNUC__ */
#endif /* not alloca */
@@ -217,21 +295,57 @@ char *alloca ();
bcopy (source, destination, osize), \
destination)
+/* No need to do anything to free, after alloca. */
+#define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */
+
+#endif /* not REGEX_MALLOC */
+
+/* Define how to allocate the failure stack. */
+
+#if defined (REL_ALLOC) && defined (REGEX_MALLOC)
+
+#define REGEX_ALLOCATE_STACK(size) \
+ r_alloc (&failure_stack_ptr, (size))
+#define REGEX_REALLOCATE_STACK(source, osize, nsize) \
+ r_re_alloc (&failure_stack_ptr, (nsize))
+#define REGEX_FREE_STACK(ptr) \
+ r_alloc_free (&failure_stack_ptr)
+
+#else /* not using relocating allocator */
+
+#ifdef REGEX_MALLOC
+
+#define REGEX_ALLOCATE_STACK malloc
+#define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
+#define REGEX_FREE_STACK free
+
+#else /* not REGEX_MALLOC */
+
+#define REGEX_ALLOCATE_STACK alloca
+
+#define REGEX_REALLOCATE_STACK(source, osize, nsize) \
+ REGEX_REALLOCATE (source, osize, nsize)
+/* No need to explicitly free anything. */
+#define REGEX_FREE_STACK(arg)
+
#endif /* not REGEX_MALLOC */
+#endif /* not using relocating allocator */
/* True if `size1' is non-NULL and PTR is pointing anywhere inside
`string1' or just past its end. This works if PTR is NULL, which is
a good thing. */
-#define FIRST_STRING_P(ptr) \
+#define FIRST_STRING_P(ptr) \
(size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
/* (Re)Allocate N items of type T using malloc, or fail. */
#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
+#define RETALLOC_IF(addr, n, t) \
+ if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
-#define BYTEWIDTH 8 /* In bits. */
+#define BYTEWIDTH 8 /* In bits. */
#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
@@ -243,122 +357,123 @@ char *alloca ();
typedef char boolean;
#define false 0
#define true 1
+
+static int re_match_2_internal ();
/* These are the command codes that appear in compiled regular
- expressions. Some opcodes are followed by argument bytes. A
+ expressions. Some opcodes 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. */
+ arguments. Zero bytes may appear in the compiled regular expression. */
typedef enum
{
no_op = 0,
- /* Followed by one byte giving n, then by n literal bytes. */
- exactn = 1,
+ /* Succeed right away--no more backtracking. */
+ succeed,
- /* Matches any (more or less) character. */
+ /* Followed by one byte giving n, then by n literal bytes. */
+ exactn,
+
+ /* Matches any (more or less) character. */
anychar,
- /* 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. */
+ /* 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,
- /* Same parameters as charset, but match any character that is
- not one of those specified. */
+ /* Same parameters as charset, but match any character that is
+ not one of those specified. */
charset_not,
- /* Start remembering the text that is matched, for storing in a
- register. Followed by one byte with the register number, in
- the range 0 to one less than the pattern buffer's re_nsub
- field. Then followed by one byte with the number of groups
- inner to this one. (This last has to be part of the
- start_memory only because we need it in the on_failure_jump
- of re_match_2.) */
+ /* Start remembering the text that is matched, for storing in a
+ register. Followed by one byte with the register number, in
+ the range 0 to one less than the pattern buffer's re_nsub
+ field. Then followed by one byte with the number of groups
+ inner to this one. (This last has to be part of the
+ start_memory only because we need it in the on_failure_jump
+ of re_match_2.) */
start_memory,
- /* Stop remembering the text that is matched and store it in a
- memory register. Followed by one byte with the register
- number, in the range 0 to one less than `re_nsub' in the
- pattern buffer, and one byte with the number of inner groups,
- just like `start_memory'. (We need the number of inner
- groups here because we don't have any easy way of finding the
- corresponding start_memory when we're at a stop_memory.) */
+ /* Stop remembering the text that is matched and store it in a
+ memory register. Followed by one byte with the register
+ number, in the range 0 to one less than `re_nsub' in the
+ pattern buffer, and one byte with the number of inner groups,
+ just like `start_memory'. (We need the number of inner
+ groups here because we don't have any easy way of finding the
+ corresponding start_memory when we're at a stop_memory.) */
stop_memory,
- /* Match a duplicate of something remembered. Followed by one
- byte containing the register number. */
+ /* Match a duplicate of something remembered. Followed by one
+ byte containing the register number. */
duplicate,
- /* Fail unless at beginning of line. */
+ /* Fail unless at beginning of line. */
begline,
- /* Fail unless at end of line. */
+ /* Fail unless at end of line. */
endline,
- /* Succeeds if at beginning of buffer (if emacs) or at beginning
- of string to be matched (if not). */
+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
+ of string to be matched (if not). */
begbuf,
- /* Analogously, for end of buffer/string. */
+ /* Analogously, for end of buffer/string. */
endbuf,
- /* Followed by two byte relative address to which to jump. */
+ /* Followed by two byte relative address to which to jump. */
jump,
/* Same as jump, but marks the end of an alternative. */
jump_past_alt,
- /* Followed by two-byte relative address of place to resume at
- in case of failure. */
+ /* Followed by two-byte relative address of place to resume at
+ in case of failure. */
on_failure_jump,
- /* Like on_failure_jump, but pushes a placeholder instead of the
- current string position when executed. */
+ /* Like on_failure_jump, but pushes a placeholder instead of the
+ current string position when executed. */
on_failure_keep_string_jump,
- /* Throw away latest failure point and then jump to following
- two-byte relative address. */
+ /* Throw away latest failure point and then jump to following
+ two-byte relative address. */
pop_failure_jump,
- /* Change to pop_failure_jump if know won't have to backtrack to
- match; otherwise change to jump. This is used to jump
- back to the beginning of a repeat. If what follows this jump
- clearly won't match what the repeat does, such that we can be
- sure that there is no use backtracking out of repetitions
- already matched, then we change it to a pop_failure_jump.
- Followed by two-byte address. */
+ /* Change to pop_failure_jump if know won't have to backtrack to
+ match; otherwise change to jump. This is used to jump
+ back to the beginning of a repeat. If what follows this jump
+ clearly won't match what the repeat does, such that we can be
+ sure that there is no use backtracking out of repetitions
+ already matched, then we change it to a pop_failure_jump.
+ Followed by two-byte address. */
maybe_pop_jump,
- /* Jump to following two-byte address, 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 used as an intermediary kind
- of jump when compiling an alternative. */
+ /* Jump to following two-byte address, 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 used as an intermediary kind
+ of jump when compiling an alternative. */
dummy_failure_jump,
/* Push a dummy failure point and continue. Used at the end of
alternatives. */
push_dummy_failure,
- /* Followed by two-byte relative address and two-byte number n.
- After matching N times, jump to the address upon failure. */
+ /* Followed by two-byte relative address and two-byte number n.
+ After matching N times, jump to the address upon failure. */
succeed_n,
- /* Followed by two-byte relative address, and two-byte number n.
- Jump to the address N times, then fail. */
+ /* Followed by two-byte relative address, and two-byte number n.
+ Jump to the address N times, then fail. */
jump_n,
- /* Set the following two-byte relative address to the
- subsequent two-byte number. The address *includes* the two
- bytes of number. */
+ /* Set the following two-byte relative address to the
+ subsequent two-byte number. The address *includes* the two
+ bytes of number. */
set_number_at,
wordchar, /* Matches any word-constituent character. */
@@ -368,7 +483,7 @@ typedef enum
wordend, /* Succeeds if at word end. */
wordbound, /* Succeeds if at a word boundary. */
- notwordbound /* Succeeds if not at a word boundary. */
+ notwordbound /* Succeeds if not at a word boundary. */
#ifdef emacs
,before_dot, /* Succeeds if before point. */
@@ -376,11 +491,21 @@ typedef enum
after_dot, /* Succeeds if after point. */
/* Matches any character whose syntax is specified. Followed by
- a byte which contains a syntax code, e.g., Sword. */
+ a byte which contains a syntax code, e.g., Sword. */
syntaxspec,
/* Matches any character whose syntax is not that specified. */
- notsyntaxspec
+ notsyntaxspec,
+
+ /* Matches any character whose category-set contains the specified
+ category. The operator is followed by a byte which contains a
+ category code (mnemonic ASCII character). */
+ categoryspec,
+
+ /* Matches any character whose category-set does not contain the
+ specified category. The operator is followed by a byte which
+ contains the category code (mnemonic ASCII character). */
+ notcategoryspec
#endif /* emacs */
} re_opcode_t;
@@ -424,7 +549,7 @@ extract_number (dest, source)
*dest += temp << 8;
}
-#ifndef EXTRACT_MACROS /* To debug the macros. */
+#ifndef EXTRACT_MACROS /* To debug the macros. */
#undef EXTRACT_NUMBER
#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
#endif /* not EXTRACT_MACROS */
@@ -437,7 +562,7 @@ extract_number (dest, source)
#define EXTRACT_NUMBER_AND_INCR(destination, source) \
do { \
EXTRACT_NUMBER (destination, source); \
- (source) += 2; \
+ (source) += 2; \
} while (0)
#ifdef DEBUG
@@ -458,11 +583,98 @@ extract_number_and_incr (destination, source)
#endif /* DEBUG */
+/* Store a multibyte character in three contiguous bytes starting
+ DESTINATION, and increment DESTINATION to the byte after where the
+ character is stored. Therefore, DESTINATION must be an lvalue. */
+
+#define STORE_CHARACTER_AND_INCR(destination, character) \
+ do { \
+ (destination)[0] = (character) & 0377; \
+ (destination)[1] = ((character) >> 8) & 0377; \
+ (destination)[2] = (character) >> 16; \
+ (destination) += 3; \
+ } while (0)
+
+/* Put into DESTINATION a character stored in three contiguous bytes
+ starting at SOURCE. */
+
+#define EXTRACT_CHARACTER(destination, source) \
+ do { \
+ (destination) = ((source)[0] \
+ | ((source)[1] << 8) \
+ | ((source)[2] << 16)); \
+ } while (0)
+
+
+/* Macros for charset. */
+
+/* Size of bitmap of charset P in bytes. P is a start of charset,
+ i.e. *P is (re_opcode_t) charset or (re_opcode_t) charset_not. */
+#define CHARSET_BITMAP_SIZE(p) ((p)[1] & 0x7F)
+
+/* Nonzero if charset P has range table. */
+#define CHARSET_RANGE_TABLE_EXISTS_P(p) ((p)[1] & 0x80)
+
+/* Return the address of range table of charset P. But not the start
+ of table itself, but the before where the number of ranges is
+ stored. `2 +' means to skip re_opcode_t and size of bitmap. */
+#define CHARSET_RANGE_TABLE(p) (&(p)[2 + CHARSET_BITMAP_SIZE (p)])
+
+/* Test if C is listed in the bitmap of charset P. */
+#define CHARSET_LOOKUP_BITMAP(p, c) \
+ ((c) < CHARSET_BITMAP_SIZE (p) * BYTEWIDTH \
+ && (p)[2 + (c) / BYTEWIDTH] & (1 << ((c) % BYTEWIDTH)))
+
+/* Return the address of end of RANGE_TABLE. COUNT is number of
+ ranges (which is a pair of (start, end)) in the RANGE_TABLE. `* 2'
+ is start of range and end of range. `* 3' is size of each start
+ and end. */
+#define CHARSET_RANGE_TABLE_END(range_table, count) \
+ ((range_table) + (count) * 2 * 3)
+
+/* Test if C is in RANGE_TABLE. A flag NOT is negated if C is in.
+ COUNT is number of ranges in RANGE_TABLE. */
+#define CHARSET_LOOKUP_RANGE_TABLE_RAW(not, c, range_table, count) \
+ do \
+ { \
+ int range_start, range_end; \
+ unsigned char *p; \
+ unsigned char *range_table_end \
+ = CHARSET_RANGE_TABLE_END ((range_table), (count)); \
+ \
+ for (p = (range_table); p < range_table_end; p += 2 * 3) \
+ { \
+ EXTRACT_CHARACTER (range_start, p); \
+ EXTRACT_CHARACTER (range_end, p + 3); \
+ \
+ if (range_start <= (c) && (c) <= range_end) \
+ { \
+ (not) = !(not); \
+ break; \
+ } \
+ } \
+ } \
+ while (0)
+
+/* Test if C is in range table of CHARSET. The flag NOT is negated if
+ C is listed in it. */
+#define CHARSET_LOOKUP_RANGE_TABLE(not, c, charset) \
+ do \
+ { \
+ /* Number of ranges in range table. */ \
+ int count; \
+ unsigned char *range_table = CHARSET_RANGE_TABLE (charset); \
+ \
+ EXTRACT_NUMBER_AND_INCR (count, range_table); \
+ CHARSET_LOOKUP_RANGE_TABLE_RAW ((not), (c), range_table, count); \
+ } \
+ while (0)
+
/* If DEBUG is defined, Regex prints many voluminous messages about what
it is doing (if the variable `debug' is nonzero). If linked with the
main program in `iregex.c', you can enter patterns and strings
interactively. And if linked with the main program in `main.c' and
- the other test files, you can run the already-written tests. */
+ the other test files, you can run the already-written tests. */
#ifdef DEBUG
@@ -479,14 +691,12 @@ static int debug = 0;
#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
-#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
if (debug) print_partial_compiled_pattern (s, e)
#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
if (debug) print_double_string (w, s1, sz1, s2, sz2)
-extern void printchar ();
-
/* Print the fastmap in human-readable form. */
void
@@ -501,18 +711,18 @@ print_fastmap (fastmap)
if (fastmap[i++])
{
was_a_range = 0;
- printchar (i - 1);
- while (i < (1 << BYTEWIDTH) && fastmap[i])
- {
- was_a_range = 1;
- i++;
- }
+ putchar (i - 1);
+ while (i < (1 << BYTEWIDTH) && fastmap[i])
+ {
+ was_a_range = 1;
+ i++;
+ }
if (was_a_range)
- {
- printf ("-");
- printchar (i - 1);
- }
- }
+ {
+ printf ("-");
+ putchar (i - 1);
+ }
+ }
}
putchar ('\n');
}
@@ -539,32 +749,34 @@ print_partial_compiled_pattern (start, end)
/* Loop over pattern commands. */
while (p < pend)
{
+ printf ("%d:\t", p - start);
+
switch ((re_opcode_t) *p++)
{
- case no_op:
- printf ("/no_op");
- break;
+ case no_op:
+ printf ("/no_op");
+ break;
case exactn:
mcnt = *p++;
- printf ("/exactn/%d", mcnt);
- do
+ printf ("/exactn/%d", mcnt);
+ do
{
- putchar ('/');
- printchar (*p++);
- }
- while (--mcnt);
- break;
+ putchar ('/');
+ putchar (*p++);
+ }
+ while (--mcnt);
+ break;
case start_memory:
- mcnt = *p++;
- printf ("/start_memory/%d/%d", mcnt, *p++);
- break;
+ mcnt = *p++;
+ printf ("/start_memory/%d/%d", mcnt, *p++);
+ break;
case stop_memory:
- mcnt = *p++;
+ mcnt = *p++;
printf ("/stop_memory/%d/%d", mcnt, *p++);
- break;
+ break;
case duplicate:
printf ("/duplicate/%d", *p++);
@@ -575,102 +787,120 @@ print_partial_compiled_pattern (start, end)
break;
case charset:
- case charset_not:
- {
- register int c;
-
- printf ("/charset%s",
- (re_opcode_t) *(p - 1) == charset_not ? "_not" : "");
-
- assert (p + *p < pend);
-
- for (c = 0; c < *p; c++)
- {
- unsigned bit;
- unsigned char map_byte = p[1 + c];
-
- putchar ('/');
-
- for (bit = 0; bit < BYTEWIDTH; bit++)
- if (map_byte & (1 << bit))
- printchar (c * BYTEWIDTH + bit);
- }
+ case charset_not:
+ {
+ register int c, last = -100;
+ register int in_range = 0;
+
+ printf ("/charset [%s",
+ (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
+
+ assert (p + *p < pend);
+
+ for (c = 0; c < 256; c++)
+ if (c / 8 < *p
+ && (p[1 + (c/8)] & (1 << (c % 8))))
+ {
+ /* Are we starting a range? */
+ if (last + 1 == c && ! in_range)
+ {
+ putchar ('-');
+ in_range = 1;
+ }
+ /* Have we broken a range? */
+ else if (last + 1 != c && in_range)
+ {
+ putchar (last);
+ in_range = 0;
+ }
+
+ if (! in_range)
+ putchar (c);
+
+ last = c;
+ }
+
+ if (in_range)
+ putchar (last);
+
+ putchar (']');
+
p += 1 + *p;
- break;
}
+ break;
case begline:
printf ("/begline");
- break;
+ break;
case endline:
- printf ("/endline");
- break;
+ printf ("/endline");
+ break;
case on_failure_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/on_failure_jump/0/%d", mcnt);
- break;
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_jump to %d", p + mcnt - start);
+ break;
case on_failure_keep_string_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/on_failure_keep_string_jump/0/%d", mcnt);
- break;
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_keep_string_jump to %d", p + mcnt - start);
+ break;
case dummy_failure_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/dummy_failure_jump/0/%d", mcnt);
- break;
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/dummy_failure_jump to %d", p + mcnt - start);
+ break;
case push_dummy_failure:
- printf ("/push_dummy_failure");
- break;
-
- case maybe_pop_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/maybe_pop_jump/0/%d", mcnt);
+ printf ("/push_dummy_failure");
break;
- case pop_failure_jump:
+ case maybe_pop_jump:
extract_number_and_incr (&mcnt, &p);
- printf ("/pop_failure_jump/0/%d", mcnt);
- break;
-
- case jump_past_alt:
+ printf ("/maybe_pop_jump to %d", p + mcnt - start);
+ break;
+
+ case pop_failure_jump:
extract_number_and_incr (&mcnt, &p);
- printf ("/jump_past_alt/0/%d", mcnt);
- break;
-
- case jump:
+ printf ("/pop_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case jump_past_alt:
extract_number_and_incr (&mcnt, &p);
- printf ("/jump/0/%d", mcnt);
+ printf ("/jump_past_alt to %d", p + mcnt - start);
break;
- case succeed_n:
- extract_number_and_incr (&mcnt, &p);
- extract_number_and_incr (&mcnt2, &p);
- printf ("/succeed_n/0/%d/0/%d", mcnt, mcnt2);
- break;
+ case jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump to %d", p + mcnt - start);
+ break;
- case jump_n:
- extract_number_and_incr (&mcnt, &p);
- extract_number_and_incr (&mcnt2, &p);
- printf ("/jump_n/0/%d/0/%d", mcnt, mcnt2);
- break;
+ case succeed_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/succeed_n to %d, %d times", p + mcnt - start, mcnt2);
+ break;
- case set_number_at:
- extract_number_and_incr (&mcnt, &p);
- extract_number_and_incr (&mcnt2, &p);
- printf ("/set_number_at/0/%d/0/%d", mcnt, mcnt2);
- break;
+ case jump_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/jump_n to %d, %d times", p + mcnt - start, mcnt2);
+ break;
- case wordbound:
+ case set_number_at:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/set_number_at location %d to %d", p + mcnt - start, mcnt2);
+ break;
+
+ case wordbound:
printf ("/wordbound");
break;
case notwordbound:
printf ("/notwordbound");
- break;
+ break;
case wordbeg:
printf ("/wordbeg");
@@ -682,24 +912,24 @@ print_partial_compiled_pattern (start, end)
#ifdef emacs
case before_dot:
printf ("/before_dot");
- break;
+ break;
case at_dot:
printf ("/at_dot");
- break;
+ break;
case after_dot:
printf ("/after_dot");
- break;
+ break;
case syntaxspec:
- printf ("/syntaxspec");
+ printf ("/syntaxspec");
mcnt = *p++;
printf ("/%d", mcnt);
- break;
+ break;
case notsyntaxspec:
- printf ("/notsyntaxspec");
+ printf ("/notsyntaxspec");
mcnt = *p++;
printf ("/%d", mcnt);
break;
@@ -707,25 +937,28 @@ print_partial_compiled_pattern (start, end)
case wordchar:
printf ("/wordchar");
- break;
+ break;
case notwordchar:
printf ("/notwordchar");
- break;
+ break;
case begbuf:
printf ("/begbuf");
- break;
+ break;
case endbuf:
printf ("/endbuf");
- break;
+ break;
- default:
- printf ("?%d", *(p-1));
+ default:
+ printf ("?%d", *(p-1));
}
+
+ putchar ('\n');
}
- printf ("/\n");
+
+ printf ("%d:\tend of pattern.\n", p - start);
}
@@ -771,15 +1004,15 @@ print_double_string (where, string1, size1, string2, size2)
else
{
if (FIRST_STRING_P (where))
- {
- for (this_char = where - string1; this_char < size1; this_char++)
- printchar (string1[this_char]);
+ {
+ for (this_char = where - string1; this_char < size1; this_char++)
+ putchar (string1[this_char]);
- where = string2;
- }
+ where = string2;
+ }
for (this_char = where - string2; this_char < size2; this_char++)
- printchar (string2[this_char]);
+ putchar (string2[this_char]);
}
}
@@ -801,7 +1034,9 @@ print_double_string (where, string1, size1, string2, size2)
/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
also be assigned to arbitrarily: each pattern buffer stores its own
syntax, so it can be changed between regex compilations. */
-reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS;
+/* This has no initializer because initialized variables in Emacs
+ become read-only after dumping. */
+reg_syntax_t re_syntax_options;
/* Specify the precise syntax of regexps for compilation. This provides
@@ -809,7 +1044,7 @@ reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS;
different, incompatible syntaxes.
The argument SYNTAX is a bit mask comprised of the various bits
- defined in regex.h. We return the old syntax. */
+ defined in regex.h. We return the old syntax. */
reg_syntax_t
re_set_syntax (syntax)
@@ -822,28 +1057,477 @@ re_set_syntax (syntax)
}
/* This table gives an error message for each of the error codes listed
- in regex.h. Obviously the order here has to be same as there. */
-
-static const char *re_error_msg[] =
- { NULL, /* REG_NOERROR */
- "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 */
+ in regex.h. Obviously the order here has to be same as there.
+ POSIX doesn't require that we do anything for REG_NOERROR,
+ but why not be nice? */
+
+static const char *re_error_msgid[] =
+ {
+ gettext_noop ("Success"), /* REG_NOERROR */
+ gettext_noop ("No match"), /* REG_NOMATCH */
+ gettext_noop ("Invalid regular expression"), /* REG_BADPAT */
+ gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */
+ gettext_noop ("Invalid character class name"), /* REG_ECTYPE */
+ gettext_noop ("Trailing backslash"), /* REG_EESCAPE */
+ gettext_noop ("Invalid back reference"), /* REG_ESUBREG */
+ gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */
+ gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */
+ gettext_noop ("Unmatched \\{"), /* REG_EBRACE */
+ gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */
+ gettext_noop ("Invalid range end"), /* REG_ERANGE */
+ gettext_noop ("Memory exhausted"), /* REG_ESPACE */
+ gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */
+ gettext_noop ("Premature end of regular expression"), /* REG_EEND */
+ gettext_noop ("Regular expression too big"), /* REG_ESIZE */
+ gettext_noop ("Unmatched ) or \\)"), /* REG_ERPAREN */
};
+/* Avoiding alloca during matching, to placate r_alloc. */
+
+/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
+ searching and matching functions should not call alloca. On some
+ systems, alloca is implemented in terms of malloc, and if we're
+ using the relocating allocator routines, then malloc could cause a
+ relocation, which might (if the strings being searched are in the
+ ralloc heap) shift the data out from underneath the regexp
+ routines.
+
+ Here's another reason to avoid allocation: Emacs
+ processes input from X in a signal handler; processing X input may
+ call malloc; if input arrives while a matching routine is calling
+ malloc, then we're scrod. But Emacs can't just block input while
+ calling matching routines; then we don't notice interrupts when
+ they come in. So, Emacs blocks input around all regexp calls
+ except the matching calls, which it leaves unprotected, in the
+ faith that they will not malloc. */
+
+/* Normally, this is fine. */
+#define MATCH_MAY_ALLOCATE
+
+/* When using GNU C, we are not REALLY using the C alloca, no matter
+ what config.h may say. So don't take precautions for it. */
+#ifdef __GNUC__
+#undef C_ALLOCA
+#endif
+
+/* The match routines may not allocate if (1) they would do it with malloc
+ and (2) it's not safe for them to use malloc.
+ Note that if REL_ALLOC is defined, matching would not use malloc for the
+ failure stack, but we would still use it for the register vectors;
+ so REL_ALLOC should not affect this. */
+#if (defined (C_ALLOCA) || defined (REGEX_MALLOC)) && defined (emacs)
+#undef MATCH_MAY_ALLOCATE
+#endif
+
+
+/* Failure stack declarations and macros; both re_compile_fastmap and
+ re_match_2 use a failure stack. These have to be macros because of
+ REGEX_ALLOCATE_STACK. */
+
+
+/* Approximate number of failure points for which to initially allocate space
+ when matching. If this number is exceeded, we allocate more
+ space, so it is not a hard limit. */
+#ifndef INIT_FAILURE_ALLOC
+#define INIT_FAILURE_ALLOC 20
+#endif
+
+/* Roughly the maximum number of failure points on the stack. Would be
+ exactly that if always used TYPICAL_FAILURE_SIZE items each time we failed.
+ This is a variable only so users of regex can assign to it; we never
+ change it ourselves. */
+#if defined (MATCH_MAY_ALLOCATE)
+/* Note that 4400 is enough to cause a crash on Alpha OSF/1,
+ whose default stack limit is 2mb. In order for a larger
+ value to work reliably, you have to try to make it accord
+ with the process stack limit. */
+int re_max_failures = 40000;
+#else
+int re_max_failures = 4000;
+#endif
+
+union fail_stack_elt
+{
+ unsigned char *pointer;
+ int integer;
+};
+
+typedef union fail_stack_elt fail_stack_elt_t;
+
+typedef struct
+{
+ fail_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} fail_stack_type;
+
+#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
+#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
+#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
+
+
+/* Define macros to initialize and free the failure stack.
+ Do `return -2' if the alloc fails. */
+
+#ifdef MATCH_MAY_ALLOCATE
+#define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.stack = (fail_stack_elt_t *) \
+ REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * TYPICAL_FAILURE_SIZE \
+ * sizeof (fail_stack_elt_t)); \
+ \
+ if (fail_stack.stack == NULL) \
+ return -2; \
+ \
+ fail_stack.size = INIT_FAILURE_ALLOC; \
+ fail_stack.avail = 0; \
+ } while (0)
+
+#define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack)
+#else
+#define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.avail = 0; \
+ } while (0)
+
+#define RESET_FAIL_STACK()
+#endif
+
+
+/* Double the size of FAIL_STACK, up to a limit
+ which allows approximately `re_max_failures' items.
+
+ Return 1 if succeeds, and 0 if either ran out of memory
+ allocating space for it or it was already too large.
+
+ REGEX_REALLOCATE_STACK requires `destination' be declared. */
+
+/* Factor to increase the failure stack size by
+ when we increase it.
+ This used to be 2, but 2 was too wasteful
+ because the old discarded stacks added up to as much space
+ were as ultimate, maximum-size stack. */
+#define FAIL_STACK_GROWTH_FACTOR 4
+
+#define GROW_FAIL_STACK(fail_stack) \
+ (((fail_stack).size * sizeof (fail_stack_elt_t) \
+ >= re_max_failures * TYPICAL_FAILURE_SIZE) \
+ ? 0 \
+ : ((fail_stack).stack \
+ = (fail_stack_elt_t *) \
+ REGEX_REALLOCATE_STACK ((fail_stack).stack, \
+ (fail_stack).size * sizeof (fail_stack_elt_t), \
+ MIN (re_max_failures * TYPICAL_FAILURE_SIZE, \
+ ((fail_stack).size * sizeof (fail_stack_elt_t) \
+ * FAIL_STACK_GROWTH_FACTOR))), \
+ \
+ (fail_stack).stack == NULL \
+ ? 0 \
+ : ((fail_stack).size \
+ = (MIN (re_max_failures * TYPICAL_FAILURE_SIZE, \
+ ((fail_stack).size * sizeof (fail_stack_elt_t) \
+ * FAIL_STACK_GROWTH_FACTOR)) \
+ / sizeof (fail_stack_elt_t)), \
+ 1)))
+
+
+/* Push pointer POINTER on FAIL_STACK.
+ Return 1 if was able to do so and 0 if ran out of memory allocating
+ space to do so. */
+#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \
+ ((FAIL_STACK_FULL () \
+ && !GROW_FAIL_STACK (FAIL_STACK)) \
+ ? 0 \
+ : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \
+ 1))
+
+/* Push a pointer value onto the failure stack.
+ Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_POINTER(item) \
+ fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item)
+
+/* This pushes an integer-valued item onto the failure stack.
+ Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_INT(item) \
+ fail_stack.stack[fail_stack.avail++].integer = (item)
+
+/* Push a fail_stack_elt_t value onto the failure stack.
+ Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_ELT(item) \
+ fail_stack.stack[fail_stack.avail++] = (item)
+
+/* These three POP... operations complement the three PUSH... operations.
+ All assume that `fail_stack' is nonempty. */
+#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
+#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
+#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
+
+/* Used to omit pushing failure point id's when we're not debugging. */
+#ifdef DEBUG
+#define DEBUG_PUSH PUSH_FAILURE_INT
+#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
+#else
+#define DEBUG_PUSH(item)
+#define DEBUG_POP(item_addr)
+#endif
+
+
+/* Push the information about the state we will need
+ if we ever fail back to it.
+
+ Requires variables fail_stack, regstart, regend, reg_info, and
+ num_regs be declared. GROW_FAIL_STACK requires `destination' be
+ declared.
+
+ Does `return FAILURE_CODE' if runs out of memory. */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
+ do { \
+ char *destination; \
+ /* Must be int, so when we don't save any registers, the arithmetic \
+ of 0 + -1 isn't done as unsigned. */ \
+ int this_reg; \
+ \
+ DEBUG_STATEMENT (failure_id++); \
+ DEBUG_STATEMENT (nfailure_points_pushed++); \
+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
+ \
+ DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \
+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
+ \
+ /* Ensure we have enough space allocated for what we will push. */ \
+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
+ { \
+ if (!GROW_FAIL_STACK (fail_stack)) \
+ return failure_code; \
+ \
+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
+ (fail_stack).size); \
+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
+ } \
+ \
+ /* Push the info, starting with the registers. */ \
+ DEBUG_PRINT1 ("\n"); \
+ \
+ if (1) \
+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
+ this_reg++) \
+ { \
+ DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \
+ DEBUG_STATEMENT (num_regs_pushed++); \
+ \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ PUSH_FAILURE_POINTER (regstart[this_reg]); \
+ \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ PUSH_FAILURE_POINTER (regend[this_reg]); \
+ \
+ DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \
+ DEBUG_PRINT2 (" match_null=%d", \
+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" matched_something=%d", \
+ MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" ever_matched=%d", \
+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT1 ("\n"); \
+ PUSH_FAILURE_ELT (reg_info[this_reg].word); \
+ } \
+ \
+ DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\
+ PUSH_FAILURE_INT (lowest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\
+ PUSH_FAILURE_INT (highest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
+ PUSH_FAILURE_POINTER (pattern_place); \
+ \
+ DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \
+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
+ size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ PUSH_FAILURE_POINTER (string_place); \
+ \
+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
+ DEBUG_PUSH (failure_id); \
+ } while (0)
+
+/* This is the number of items that are pushed and popped on the stack
+ for each register. */
+#define NUM_REG_ITEMS 3
+
+/* Individual items aside from the registers. */
+#ifdef DEBUG
+#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
+#else
+#define NUM_NONREG_ITEMS 4
+#endif
+
+/* Estimate the size of data pushed by a typical failure stack entry.
+ An estimate is all we need, because all we use this for
+ is to choose a limit for how big to make the failure stack. */
+
+#define TYPICAL_FAILURE_SIZE 20
+
+/* This is how many items we actually use for a failure point.
+ It depends on the regexp. */
+#define NUM_FAILURE_ITEMS \
+ (((0 \
+ ? 0 : highest_active_reg - lowest_active_reg + 1) \
+ * NUM_REG_ITEMS) \
+ + NUM_NONREG_ITEMS)
+
+/* How many items can still be added to the stack without overflowing it. */
+#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
+
+
+/* Pops what PUSH_FAIL_STACK pushes.
+
+ We restore into the parameters, all of which should be lvalues:
+ STR -- the saved data position.
+ PAT -- the saved pattern position.
+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
+ REGSTART, REGEND -- arrays of string positions.
+ REG_INFO -- array of information about each subexpression.
+
+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
+ `pend', `string1', `size1', `string2', and `size2'. */
+
+#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
+{ \
+ DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \
+ int this_reg; \
+ const unsigned char *string_temp; \
+ \
+ assert (!FAIL_STACK_EMPTY ()); \
+ \
+ /* Remove failure points and point to how many regs pushed. */ \
+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
+ \
+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
+ \
+ DEBUG_POP (&failure_id); \
+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
+ \
+ /* If the saved string location is NULL, it came from an \
+ on_failure_keep_string_jump opcode, and we want to throw away the \
+ saved NULL, thus retaining our current position in the string. */ \
+ string_temp = POP_FAILURE_POINTER (); \
+ if (string_temp != NULL) \
+ str = (const char *) string_temp; \
+ \
+ DEBUG_PRINT2 (" Popping string 0x%x: `", str); \
+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ \
+ pat = (unsigned char *) POP_FAILURE_POINTER (); \
+ DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
+ \
+ /* Restore register info. */ \
+ high_reg = (unsigned) POP_FAILURE_INT (); \
+ DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \
+ \
+ low_reg = (unsigned) POP_FAILURE_INT (); \
+ DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \
+ \
+ if (1) \
+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
+ { \
+ DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \
+ \
+ reg_info[this_reg].word = POP_FAILURE_ELT (); \
+ DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \
+ \
+ regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ \
+ regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ } \
+ else \
+ { \
+ for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
+ { \
+ reg_info[this_reg].word.integer = 0; \
+ regend[this_reg] = 0; \
+ regstart[this_reg] = 0; \
+ } \
+ highest_active_reg = high_reg; \
+ } \
+ \
+ set_regs_matched_done = 0; \
+ DEBUG_STATEMENT (nfailure_points_popped++); \
+} /* POP_FAILURE_POINT */
+
+
+
+/* Structure for per-register (a.k.a. per-group) information.
+ Other register information, such as the
+ starting and ending positions (which are addresses), and the list of
+ inner groups (which is a bits list) are maintained in separate
+ variables.
+
+ We are making a (strictly speaking) nonportable assumption here: that
+ the compiler will pack our bit fields into something that fits into
+ the type of `word', i.e., is something that fits into one item on the
+ failure stack. */
+
+typedef union
+{
+ fail_stack_elt_t word;
+ struct
+ {
+ /* This field is one if this group can match the empty string,
+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
+#define MATCH_NULL_UNSET_VALUE 3
+ unsigned match_null_string_p : 2;
+ unsigned is_active : 1;
+ unsigned matched_something : 1;
+ unsigned ever_matched_something : 1;
+ } bits;
+} register_info_type;
+
+#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
+#define IS_ACTIVE(R) ((R).bits.is_active)
+#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
+#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
+
+
+/* Call this when have matched a real character; it sets `matched' flags
+ for the subexpressions which we are currently inside. Also records
+ that those subexprs have matched. */
+#define SET_REGS_MATCHED() \
+ do \
+ { \
+ if (!set_regs_matched_done) \
+ { \
+ unsigned r; \
+ set_regs_matched_done = 1; \
+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
+ { \
+ MATCHED_SOMETHING (reg_info[r]) \
+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
+ = 1; \
+ } \
+ } \
+ } \
+ while (0)
+
+/* Registers are set to a sentinel when they haven't yet matched. */
+static char reg_unset_dummy;
+#define REG_UNSET_VALUE (&reg_unset_dummy)
+#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
+
/* Subroutine declarations and macros for regex_compile. */
static void store_op1 (), store_op2 ();
@@ -852,21 +1536,23 @@ static boolean at_begline_loc_p (), at_endline_loc_p ();
static boolean group_in_compile_stack ();
static reg_errcode_t compile_range ();
-/* Fetch the next character in the uncompiled pattern---translating it
+/* 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'). */
+#ifndef PATFETCH
#define PATFETCH(c) \
do {if (p == pend) return REG_EEND; \
c = (unsigned char) *p++; \
- if (translate) c = translate[c]; \
+ if (RE_TRANSLATE_P (translate)) c = RE_TRANSLATE (translate, c); \
} while (0)
+#endif
/* Fetch the next character in the uncompiled pattern, with no
- translation. */
+ translation. */
#define PATFETCH_RAW(c) \
do {if (p == pend) return REG_EEND; \
- c = (unsigned char) *p++; \
+ c = (unsigned char) *p++; \
} while (0)
/* Go backwards one character in the pattern. */
@@ -877,7 +1563,11 @@ static reg_errcode_t compile_range ();
cast the subscript to translate because some data is declared as
`char *', to avoid warnings when a string constant is passed. But
when we use a character as a subscript we must make it unsigned. */
-#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d))
+#ifndef TRANSLATE
+#define TRANSLATE(d) \
+ (RE_TRANSLATE_P (translate) \
+ ? (unsigned) RE_TRANSLATE (translate, (unsigned) (d)) : (d))
+#endif
/* Macros for outputting the compiled pattern into `buffer'. */
@@ -885,7 +1575,7 @@ static reg_errcode_t compile_range ();
/* If the buffer isn't allocated when it comes in, use this. */
#define INIT_BUF_SIZE 32
-/* Make sure we have at least N more bytes of space in buffer. */
+/* 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 ()
@@ -907,7 +1597,7 @@ static reg_errcode_t compile_range ();
} while (0)
-/* As with BUF_PUSH_2, except for three bytes. */
+/* As with BUF_PUSH_2, except for three bytes. */
#define BUF_PUSH_3(c1, c2, c3) \
do { \
GET_BUFFER_SPACE (3); \
@@ -918,7 +1608,7 @@ static reg_errcode_t compile_range ();
/* Store a jump with opcode OP at LOC to location TO. We store a
- relative address offset by the three bytes the jump itself occupies. */
+ relative address offset by the three bytes the jump itself occupies. */
#define STORE_JUMP(op, loc, to) \
store_op1 (op, loc, (to) - (loc) - 3)
@@ -926,7 +1616,7 @@ static reg_errcode_t compile_range ();
#define STORE_JUMP2(op, loc, to, arg) \
store_op2 (op, loc, (to) - (loc) - 3, arg)
-/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
#define INSERT_JUMP(op, loc, to) \
insert_op1 (op, loc, (to) - (loc) - 3, b)
@@ -936,7 +1626,7 @@ static reg_errcode_t compile_range ();
/* This is not an arbitrary limit: the arguments which represent offsets
- into the pattern are two bytes long. So if 2^16 bytes turns out to
+ into the pattern are two bytes long. So if 2^16 bytes turns out to
be too small, many things would have to change. */
#define MAX_BUF_SIZE (1L << 16)
@@ -944,29 +1634,29 @@ static reg_errcode_t compile_range ();
/* Extend the buffer by twice its current size via realloc and
reset the pointers that pointed into the old block to point to the
correct places in the new one. If extending the buffer results in it
- being larger than MAX_BUF_SIZE, then flag memory exhausted. */
+ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
#define EXTEND_BUFFER() \
- do { \
+ do { \
unsigned char *old_buffer = bufp->buffer; \
- if (bufp->allocated == MAX_BUF_SIZE) \
+ if (bufp->allocated == MAX_BUF_SIZE) \
return REG_ESIZE; \
bufp->allocated <<= 1; \
if (bufp->allocated > MAX_BUF_SIZE) \
- bufp->allocated = MAX_BUF_SIZE; \
+ bufp->allocated = MAX_BUF_SIZE; \
bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\
if (bufp->buffer == NULL) \
return REG_ESPACE; \
/* If the buffer moved, move all the pointers into it. */ \
if (old_buffer != bufp->buffer) \
{ \
- b = (b - old_buffer) + bufp->buffer; \
- begalt = (begalt - old_buffer) + bufp->buffer; \
- if (fixup_alt_jump) \
- fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
- if (laststart) \
- laststart = (laststart - old_buffer) + bufp->buffer; \
- if (pending_exact) \
- pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+ b = (b - old_buffer) + bufp->buffer; \
+ begalt = (begalt - old_buffer) + bufp->buffer; \
+ if (fixup_alt_jump) \
+ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
+ if (laststart) \
+ laststart = (laststart - old_buffer) + bufp->buffer; \
+ if (pending_exact) \
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
} \
} while (0)
@@ -984,7 +1674,7 @@ typedef unsigned regnum_t;
/* Macros for the compile stack. */
/* 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. */
+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
typedef int pattern_offset_t;
typedef struct
@@ -1010,31 +1700,76 @@ typedef struct
#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
-/* The next available element. */
+/* The next available element. */
#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
+/* Structure to manage work area for range table. */
+struct range_table_work_area
+{
+ int *table; /* actual work area. */
+ int allocated; /* allocated size for work area in bytes. */
+ int used; /* actually used size in words. */
+};
+
+/* Make sure that WORK_AREA can hold more N multibyte characters. */
+#define EXTEND_RANGE_TABLE_WORK_AREA(work_area, n) \
+ do { \
+ if (((work_area).used + (n)) * sizeof (int) > (work_area).allocated) \
+ { \
+ (work_area).allocated += 16 * sizeof (int); \
+ if ((work_area).table) \
+ (work_area).table \
+ = (int *) realloc ((work_area).table, (work_area).allocated); \
+ else \
+ (work_area).table \
+ = (int *) malloc ((work_area).allocated); \
+ if ((work_area).table == 0) \
+ FREE_STACK_RETURN (REG_ESPACE); \
+ } \
+ } while (0)
+
+/* Set a range (RANGE_START, RANGE_END) to WORK_AREA. */
+#define SET_RANGE_TABLE_WORK_AREA(work_area, range_start, range_end) \
+ do { \
+ EXTEND_RANGE_TABLE_WORK_AREA ((work_area), 2); \
+ (work_area).table[(work_area).used++] = (range_start); \
+ (work_area).table[(work_area).used++] = (range_end); \
+ } while (0)
+
+/* Free allocated memory for WORK_AREA. */
+#define FREE_RANGE_TABLE_WORK_AREA(work_area) \
+ do { \
+ if ((work_area).table) \
+ free ((work_area).table); \
+ } while (0)
+
+#define CLEAR_RANGE_TABLE_WORK_USED(work_area) ((work_area).used = 0)
+#define RANGE_TABLE_WORK_USED(work_area) ((work_area).used)
+#define RANGE_TABLE_WORK_ELT(work_area, i) ((work_area).table[i])
+
+
/* Set the bit for character C in a list. */
-#define SET_LIST_BIT(c) \
- (b[((unsigned char) (c)) / BYTEWIDTH] \
+#define SET_LIST_BIT(c) \
+ (b[((unsigned char) (c)) / BYTEWIDTH] \
|= 1 << (((unsigned char) c) % BYTEWIDTH))
/* Get the next unsigned number in the uncompiled pattern. */
-#define GET_UNSIGNED_NUMBER(num) \
+#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); \
- } \
- } \
+ 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'. */
@@ -1047,6 +1782,54 @@ typedef struct
|| STREQ (string, "punct") || STREQ (string, "graph") \
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
+#ifndef MATCH_MAY_ALLOCATE
+
+/* If we cannot allocate large objects within re_match_2_internal,
+ we make the fail stack and register vectors global.
+ The fail stack, we grow to the maximum size when a regexp
+ is compiled.
+ The register vectors, we adjust in size each time we
+ compile a regexp, according to the number of registers it needs. */
+
+static fail_stack_type fail_stack;
+
+/* Size with which the following vectors are currently allocated.
+ That is so we can make them bigger as needed,
+ but never make them smaller. */
+static int regs_allocated_size;
+
+static const char ** regstart, ** regend;
+static const char ** old_regstart, ** old_regend;
+static const char **best_regstart, **best_regend;
+static register_info_type *reg_info;
+static const char **reg_dummy;
+static register_info_type *reg_info_dummy;
+
+/* Make the register vectors big enough for NUM_REGS registers,
+ but don't make them smaller. */
+
+static
+regex_grow_registers (num_regs)
+ int num_regs;
+{
+ if (num_regs > regs_allocated_size)
+ {
+ RETALLOC_IF (regstart, num_regs, const char *);
+ RETALLOC_IF (regend, num_regs, const char *);
+ RETALLOC_IF (old_regstart, num_regs, const char *);
+ RETALLOC_IF (old_regend, num_regs, const char *);
+ RETALLOC_IF (best_regstart, num_regs, const char *);
+ RETALLOC_IF (best_regend, num_regs, const char *);
+ RETALLOC_IF (reg_info, num_regs, register_info_type);
+ RETALLOC_IF (reg_dummy, num_regs, const char *);
+ RETALLOC_IF (reg_info_dummy, num_regs, register_info_type);
+
+ regs_allocated_size = num_regs;
+ }
+}
+
+#endif /* not MATCH_MAY_ALLOCATE */
+
/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
Returns one of error codes defined in `regex.h', or zero for success.
@@ -1065,6 +1848,14 @@ typedef struct
The `fastmap' and `newline_anchor' fields are neither
examined nor set. */
+/* Return, freeing storage we allocated. */
+#define FREE_STACK_RETURN(value) \
+ do { \
+ FREE_RANGE_TABLE_WORK_AREA (range_table_work); \
+ free (compile_stack.stack); \
+ return value; \
+ } while (0)
+
static reg_errcode_t
regex_compile (pattern, size, syntax, bufp)
const char *pattern;
@@ -1075,7 +1866,7 @@ regex_compile (pattern, size, syntax, bufp)
/* 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;
+ register unsigned int c, c1;
/* A random temporary spot in PATTERN. */
const char *p1;
@@ -1087,11 +1878,16 @@ regex_compile (pattern, size, syntax, bufp)
compile_stack_type compile_stack;
/* Points to the current (ending) position in the pattern. */
+#ifdef AIX
+ /* `const' makes AIX compiler fail. */
+ char *p = pattern;
+#else
const char *p = pattern;
+#endif
const char *pend = pattern + size;
/* How to translate the characters in the pattern. */
- char *translate = bufp->translate;
+ RE_TRANSLATE_TYPE translate = bufp->translate;
/* Address of the count-byte of the most recently inserted `exactn'
command. This makes it possible to tell if a new exact-match
@@ -1112,7 +1908,7 @@ regex_compile (pattern, size, syntax, bufp)
const char *beg_interval;
/* Address of the place where a forward jump should go to the end of
- the containing expression. Each alternative of an `or' -- except the
+ the containing expression. Each alternative of an `or' -- except the
last -- ends with a forward jump of this sort. */
unsigned char *fixup_alt_jump = 0;
@@ -1121,6 +1917,9 @@ regex_compile (pattern, size, syntax, bufp)
number is put in the stop_memory as the start_memory. */
regnum_t regnum = 0;
+ /* Work area for range table of charset. */
+ struct range_table_work_area range_table_work;
+
#ifdef DEBUG
DEBUG_PRINT1 ("\nCompiling pattern: ");
if (debug)
@@ -1128,7 +1927,7 @@ regex_compile (pattern, size, syntax, bufp)
unsigned debug_count;
for (debug_count = 0; debug_count < size; debug_count++)
- printchar (pattern[debug_count]);
+ putchar (pattern[debug_count]);
putchar ('\n');
}
#endif /* DEBUG */
@@ -1141,6 +1940,9 @@ regex_compile (pattern, size, syntax, bufp)
compile_stack.size = INIT_COMPILE_STACK_SIZE;
compile_stack.avail = 0;
+ range_table_work.table = 0;
+ range_table_work.allocated = 0;
+
/* Initialize the pattern buffer. */
bufp->syntax = syntax;
bufp->fastmap_accurate = 0;
@@ -1154,6 +1956,14 @@ regex_compile (pattern, size, syntax, bufp)
/* Always count groups, whether or not bufp->no_sub is set. */
bufp->re_nsub = 0;
+#ifdef emacs
+ /* bufp->multibyte is set before regex_compile is called, so don't alter
+ it. */
+#else /* not emacs */
+ /* Nothing is recognized as a multibyte character. */
+ bufp->multibyte = 0;
+#endif
+
#if !defined (emacs) && !defined (SYNTAX_TABLE)
/* Initialize the syntax table. */
init_syntax_once ();
@@ -1163,15 +1973,15 @@ regex_compile (pattern, size, syntax, bufp)
{
if (bufp->buffer)
{ /* If zero allocated, but buffer is non-null, try to realloc
- enough space. This loses if buffer's address is bogus, but
- that is the user's responsibility. */
- RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
- }
+ enough space. This loses if buffer's address is bogus, but
+ that is the user's responsibility. */
+ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
+ }
else
- { /* Caller did not allocate a buffer. Do it for them. */
- bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
- }
- if (!bufp->buffer) return REG_ESPACE;
+ { /* Caller did not allocate a buffer. Do it for them. */
+ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
+ }
+ if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE);
bufp->allocated = INIT_BUF_SIZE;
}
@@ -1184,857 +1994,969 @@ regex_compile (pattern, size, syntax, bufp)
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))
- BUF_PUSH (begline);
- else
- goto normal_char;
- }
- break;
+ {
+ 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))
+ BUF_PUSH (begline);
+ 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))
- BUF_PUSH (endline);
- 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))
+ BUF_PUSH (endline);
+ 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 (!laststart)
- {
- if (syntax & RE_CONTEXT_INVALID_OPS)
- return REG_BADRPT;
- else if (!(syntax & RE_CONTEXT_INDEP_OPS))
- goto normal_char;
- }
+ case '?':
+ if ((syntax & RE_BK_PLUS_QM)
+ || (syntax & RE_LIMITED_OPS))
+ goto normal_char;
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern... */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+
+ {
+ /* Are we optimizing this jump? */
+ boolean keep_string_p = false;
+
+ /* 1 means zero (many) matches is allowed. */
+ char zero_times_ok = 0, many_times_ok = 0;
- {
- /* Are we optimizing this jump? */
- boolean keep_string_p = false;
+ /* 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. */
- /* 1 means zero (many) matches is allowed. */
- char zero_times_ok = 0, many_times_ok = 0;
+ for (;;)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
- /* 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. */
+ if (p == pend)
+ break;
- for (;;)
- {
- zero_times_ok |= c != '+';
- many_times_ok |= c != '?';
+ PATFETCH (c);
- if (p == pend)
- break;
+ if (c == '*'
+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
+ ;
- 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 (!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)
- { /* More than one repetition is allowed, so 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).
-
- But if we are at the `*' in the exact sequence `.*\n',
- insert an unconditional jump backwards to the .,
- instead of the beginning of the loop. This way we only
- push a failure point once, instead of every time
- through the loop. */
- assert (p - 1 > pattern);
-
- /* Allocate the space for the jump. */
- GET_BUFFER_SPACE (3);
-
- /* We know we are not at the first character of the pattern,
- because laststart was nonzero. And we've already
- incremented `p', by the way, to be the character after
- the `*'. Do we have to do something analogous here
- for null bytes, because of RE_DOT_NOT_NULL? */
- if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
+ {
+ if (p == pend) FREE_STACK_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 (!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)
+ { /* More than one repetition is allowed, so 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).
+
+ But if we are at the `*' in the exact sequence `.*\n',
+ insert an unconditional jump backwards to the .,
+ instead of the beginning of the loop. This way we only
+ push a failure point once, instead of every time
+ through the loop. */
+ assert (p - 1 > pattern);
+
+ /* Allocate the space for the jump. */
+ GET_BUFFER_SPACE (3);
+
+ /* We know we are not at the first character of the pattern,
+ because laststart was nonzero. And we've already
+ incremented `p', by the way, to be the character after
+ the `*'. Do we have to do something analogous here
+ for null bytes, because of RE_DOT_NOT_NULL? */
+ if (TRANSLATE ((unsigned char)*(p - 2)) == TRANSLATE ('.')
&& zero_times_ok
- && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
- && !(syntax & RE_DOT_NEWLINE))
- { /* We have .*\n. */
- STORE_JUMP (jump, b, laststart);
- keep_string_p = true;
- }
- else
- /* Anything else. */
- STORE_JUMP (maybe_pop_jump, b, laststart - 3);
-
- /* We've added more stuff to the buffer. */
- b += 3;
- }
-
- /* 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 (keep_string_p ? on_failure_keep_string_jump
- : on_failure_jump,
- laststart, b + 3);
- pending_exact = 0;
- b += 3;
-
- if (!zero_times_ok)
- {
- /* At least one repetition is required, so insert a
- `dummy_failure_jump' 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 (3);
- INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
- b += 3;
- }
- }
+ && p < pend
+ && TRANSLATE ((unsigned char)*p) == TRANSLATE ('\n')
+ && !(syntax & RE_DOT_NEWLINE))
+ { /* We have .*\n. */
+ STORE_JUMP (jump, b, laststart);
+ keep_string_p = true;
+ }
+ else
+ /* Anything else. */
+ STORE_JUMP (maybe_pop_jump, b, laststart - 3);
+
+ /* We've added more stuff to the buffer. */
+ b += 3;
+ }
+
+ /* 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 (keep_string_p ? on_failure_keep_string_jump
+ : on_failure_jump,
+ laststart, b + 3);
+ pending_exact = 0;
+ b += 3;
+
+ if (!zero_times_ok)
+ {
+ /* At least one repetition is required, so insert a
+ `dummy_failure_jump' 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 (3);
+ INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
+ b += 3;
+ }
+ }
break;
case '.':
- laststart = b;
- BUF_PUSH (anychar);
- break;
+ laststart = b;
+ BUF_PUSH (anychar);
+ break;
- case '[':
- {
- boolean had_char_class = false;
+ case '[':
+ {
+ CLEAR_RANGE_TABLE_WORK_USED (range_table_work);
- if (p == pend) return REG_EBRACK;
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
- /* Ensure that we have enough space to push a charset: the
- opcode, the length count, and the bitset; 34 bytes in all. */
+ /* Ensure that we have enough space to push a charset: the
+ opcode, the length count, and the bitset; 34 bytes in all. */
GET_BUFFER_SPACE (34);
- laststart = b;
+ laststart = b;
- /* We test `*p == '^' twice, instead of using an if
- statement, so we only need one BUF_PUSH. */
- BUF_PUSH (*p == '^' ? charset_not : charset);
- if (*p == '^')
- p++;
+ /* We test `*p == '^' twice, instead of using an if
+ statement, so we only need one BUF_PUSH. */
+ BUF_PUSH (*p == '^' ? charset_not : charset);
+ if (*p == '^')
+ p++;
- /* Remember the first position in the bracket expression. */
- p1 = p;
+ /* Remember the first position in the bracket expression. */
+ p1 = p;
- /* Push the number of bytes in the bitmap. */
- BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+ /* Push the number of bytes in the bitmap. */
+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
- /* Clear the whole map. */
- bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+ /* Clear the whole map. */
+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
- /* charset_not matches newline according to a syntax bit. */
- if ((re_opcode_t) b[-2] == charset_not
- && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
- SET_LIST_BIT ('\n');
+ /* charset_not matches newline according to a syntax bit. */
+ if ((re_opcode_t) b[-2] == charset_not
+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
+ SET_LIST_BIT ('\n');
- /* Read in characters and ranges, setting map bits. */
- for (;;)
- {
- if (p == pend) return REG_EBRACK;
+ /* Read in characters and ranges, setting map bits. */
+ for (;;)
+ {
+ int len;
+ boolean escaped_char = false;
- PATFETCH (c);
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
- /* \ might escape characters inside [...] and [^...]. */
- if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
- {
- if (p == pend) return REG_EESCAPE;
+ PATFETCH (c);
- PATFETCH (c1);
- SET_LIST_BIT (c1);
- continue;
- }
+ /* \ might escape characters inside [...] and [^...]. */
+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
- /* Could be the end of the bracket expression. If it's
- not (i.e., when the bracket expression is `[]' so
- far), the ']' character bit gets set way below. */
- if (c == ']' && p != p1 + 1)
- break;
+ PATFETCH (c);
+ escaped_char = true;
+ }
+ else
+ {
+ /* Could be the end of the bracket expression. If it's
+ not (i.e., when the bracket expression is `[]' so
+ far), the ']' character bit gets set way below. */
+ if (c == ']' && p != p1 + 1)
+ break;
+ }
- /* Look ahead to see if it's a range when the last thing
- was a character class. */
- if (had_char_class && c == '-' && *p != ']')
- return REG_ERANGE;
-
- /* Look ahead to see if it's a range when the last thing
- was a character: if this is a hyphen not at the
- beginning or the end of a list, then it's the range
- operator. */
- if (c == '-'
- && !(p - 2 >= pattern && p[-2] == '[')
- && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
- && *p != ']')
- {
- reg_errcode_t ret
- = compile_range (&p, pend, translate, syntax, b);
- if (ret != REG_NOERROR) return ret;
- }
-
- else if (p[0] == '-' && p[1] != ']')
- { /* This handles ranges made up of characters only. */
- reg_errcode_t ret;
-
- /* Move past the `-'. */
- PATFETCH (c1);
-
- ret = compile_range (&p, pend, translate, syntax, b);
- if (ret != REG_NOERROR) return ret;
- }
-
- /* See if we're at the beginning of a possible character
- class. */
-
- else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
- { /* Leave room for the null. */
- char str[CHAR_CLASS_MAX_LENGTH + 1];
-
- PATFETCH (c);
- c1 = 0;
-
- /* If pattern is `[[:'. */
- if (p == pend) return REG_EBRACK;
-
- for (;;)
- {
- PATFETCH (c);
- if (c == ':' || c == ']' || p == pend
- || c1 == CHAR_CLASS_MAX_LENGTH)
- break;
- str[c1++] = c;
- }
- str[c1] = '\0';
-
- /* If isn't a word bracketed by `[:' and:`]':
- undo the ending character, the letters, and leave
- the leading `:' and `[' (but set bits for them). */
- if (c == ':' && *p == ']')
- {
- int ch;
- boolean is_alnum = STREQ (str, "alnum");
- boolean is_alpha = STREQ (str, "alpha");
- boolean is_blank = STREQ (str, "blank");
- boolean is_cntrl = STREQ (str, "cntrl");
- boolean is_digit = STREQ (str, "digit");
- boolean is_graph = STREQ (str, "graph");
- boolean is_lower = STREQ (str, "lower");
- boolean is_print = STREQ (str, "print");
- boolean is_punct = STREQ (str, "punct");
- boolean is_space = STREQ (str, "space");
- boolean is_upper = STREQ (str, "upper");
- boolean is_xdigit = STREQ (str, "xdigit");
-
- if (!IS_CHAR_CLASS (str)) return REG_ECTYPE;
-
- /* Throw away the ] at the end of the character
- class. */
- PATFETCH (c);
-
- if (p == pend) return REG_EBRACK;
-
- for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
- {
- if ( (is_alnum && ISALNUM (ch))
- || (is_alpha && ISALPHA (ch))
- || (is_blank && ISBLANK (ch))
- || (is_cntrl && ISCNTRL (ch))
- || (is_digit && ISDIGIT (ch))
- || (is_graph && ISGRAPH (ch))
- || (is_lower && ISLOWER (ch))
- || (is_print && ISPRINT (ch))
- || (is_punct && ISPUNCT (ch))
- || (is_space && ISSPACE (ch))
- || (is_upper && ISUPPER (ch))
- || (is_xdigit && ISXDIGIT (ch)))
- SET_LIST_BIT (ch);
- }
- had_char_class = true;
- }
- else
- {
- c1++;
- while (c1--)
- PATUNFETCH;
- SET_LIST_BIT ('[');
- SET_LIST_BIT (':');
- had_char_class = false;
- }
- }
- else
- {
- had_char_class = false;
- SET_LIST_BIT (c);
- }
- }
-
- /* Discard any (non)matching list bytes that are all 0 at the
- end of the map. Decrease the map-length byte too. */
- while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
- b[-1]--;
- b += b[-1];
- }
- break;
+ /* If C indicates start of multibyte char, get the
+ actual character code in C, and set the pattern
+ pointer P to the next character boundary. */
+ if (bufp->multibyte && BASE_LEADING_CODE_P (c))
+ {
+ PATUNFETCH;
+ c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
+ p += len;
+ }
+ /* What should we do for the character which is
+ greater than 0x7F, but not BASE_LEADING_CODE_P?
+ XXX */
+
+ /* See if we're at the beginning of a possible character
+ class. */
+
+ else if (!escaped_char &&
+ syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
+ {
+ /* Leave room for the null. */
+ char str[CHAR_CLASS_MAX_LENGTH + 1];
+
+ PATFETCH (c);
+ c1 = 0;
+
+ /* If pattern is `[[:'. */
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (;;)
+ {
+ PATFETCH (c);
+ if (c == ':' || c == ']' || p == pend
+ || c1 == CHAR_CLASS_MAX_LENGTH)
+ break;
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+
+ /* If isn't a word bracketed by `[:' and `:]':
+ undo the ending character, the letters, and
+ leave the leading `:' and `[' (but set bits for
+ them). */
+ if (c == ':' && *p == ']')
+ {
+ int ch;
+ boolean is_alnum = STREQ (str, "alnum");
+ boolean is_alpha = STREQ (str, "alpha");
+ boolean is_blank = STREQ (str, "blank");
+ boolean is_cntrl = STREQ (str, "cntrl");
+ boolean is_digit = STREQ (str, "digit");
+ boolean is_graph = STREQ (str, "graph");
+ boolean is_lower = STREQ (str, "lower");
+ boolean is_print = STREQ (str, "print");
+ boolean is_punct = STREQ (str, "punct");
+ boolean is_space = STREQ (str, "space");
+ boolean is_upper = STREQ (str, "upper");
+ boolean is_xdigit = STREQ (str, "xdigit");
+
+ if (!IS_CHAR_CLASS (str))
+ FREE_STACK_RETURN (REG_ECTYPE);
+
+ /* Throw away the ] at the end of the character
+ class. */
+ PATFETCH (c);
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
+ {
+ int translated = TRANSLATE (ch);
+ /* This was split into 3 if's to
+ avoid an arbitrary limit in some compiler. */
+ if ( (is_alnum && ISALNUM (ch))
+ || (is_alpha && ISALPHA (ch))
+ || (is_blank && ISBLANK (ch))
+ || (is_cntrl && ISCNTRL (ch)))
+ SET_LIST_BIT (translated);
+ if ( (is_digit && ISDIGIT (ch))
+ || (is_graph && ISGRAPH (ch))
+ || (is_lower && ISLOWER (ch))
+ || (is_print && ISPRINT (ch)))
+ SET_LIST_BIT (translated);
+ if ( (is_punct && ISPUNCT (ch))
+ || (is_space && ISSPACE (ch))
+ || (is_upper && ISUPPER (ch))
+ || (is_xdigit && ISXDIGIT (ch)))
+ SET_LIST_BIT (translated);
+ }
+
+ /* Repeat the loop. */
+ continue;
+ }
+ else
+ {
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT ('[');
+
+ /* Because the `:' may starts the range, we
+ can't simply set bit and repeat the loop.
+ Instead, just set it to C and handle below. */
+ c = ':';
+ }
+ }
+
+ if (p < pend && p[0] == '-' && p[1] != ']')
+ {
+
+ /* Discard the `-'. */
+ PATFETCH (c1);
+
+ /* Fetch the character which ends the range. */
+ PATFETCH (c1);
+ if (bufp->multibyte && BASE_LEADING_CODE_P (c1))
+ {
+ PATUNFETCH;
+ c1 = STRING_CHAR_AND_LENGTH (p, pend - p, len);
+ p += len;
+ }
+
+ if (SINGLE_BYTE_CHAR_P (c)
+ && ! SINGLE_BYTE_CHAR_P (c1))
+ {
+ /* Handle a range such as \177-\377 in multibyte mode.
+ Split that into two ranges,,
+ the low one ending at 0237, and the high one
+ starting at ...040. */
+ int c1_base = (c1 & ~0177) | 040;
+ SET_RANGE_TABLE_WORK_AREA (range_table_work, c, c1);
+ c1 = 0237;
+ }
+ else if (!SAME_CHARSET_P (c, c1))
+ FREE_STACK_RETURN (REG_ERANGE);
+ }
+ else
+ /* Range from C to C. */
+ c1 = c;
+
+ /* Set the range ... */
+ if (SINGLE_BYTE_CHAR_P (c))
+ /* ... into bitmap. */
+ {
+ unsigned this_char;
+ int range_start = c, range_end = c1;
+
+ /* If the start is after the end, the range is empty. */
+ if (range_start > range_end)
+ {
+ if (syntax & RE_NO_EMPTY_RANGES)
+ FREE_STACK_RETURN (REG_ERANGE);
+ /* Else, repeat the loop. */
+ }
+ else
+ {
+ for (this_char = range_start; this_char <= range_end;
+ this_char++)
+ SET_LIST_BIT (TRANSLATE (this_char));
+ }
+ }
+ else
+ /* ... into range table. */
+ SET_RANGE_TABLE_WORK_AREA (range_table_work, c, c1);
+ }
+
+ /* Discard any (non)matching list bytes that are all 0 at the
+ end of the map. Decrease the map-length byte too. */
+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ b += b[-1];
+
+ /* Build real range table from work area. */
+ if (RANGE_TABLE_WORK_USED (range_table_work))
+ {
+ int i;
+ int used = RANGE_TABLE_WORK_USED (range_table_work);
+
+ /* Allocate space for COUNT + RANGE_TABLE. Needs two
+ bytes for COUNT and three bytes for each character. */
+ GET_BUFFER_SPACE (2 + used * 3);
+
+ /* Indicate the existence of range table. */
+ laststart[1] |= 0x80;
+
+ STORE_NUMBER_AND_INCR (b, used / 2);
+ for (i = 0; i < used; i++)
+ STORE_CHARACTER_AND_INCR
+ (b, RANGE_TABLE_WORK_ELT (range_table_work, i));
+ }
+ }
+ break;
case '(':
- if (syntax & RE_NO_BK_PARENS)
- goto handle_open;
- else
- goto normal_char;
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_open;
+ else
+ goto normal_char;
- case ')':
- if (syntax & RE_NO_BK_PARENS)
- goto handle_close;
- else
- goto normal_char;
+ case ')':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_close;
+ else
+ goto normal_char;
- case '\n':
- if (syntax & RE_NEWLINE_ALT)
- goto handle_alt;
- else
- goto normal_char;
+ case '\n':
+ if (syntax & RE_NEWLINE_ALT)
+ goto handle_alt;
+ else
+ goto normal_char;
case '|':
- if (syntax & RE_NO_BK_VBAR)
- goto handle_alt;
- else
- goto normal_char;
+ if (syntax & RE_NO_BK_VBAR)
+ goto handle_alt;
+ else
+ goto normal_char;
- case '{':
- if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
- goto handle_interval;
- else
- goto normal_char;
+ case '{':
+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
+ goto handle_interval;
+ else
+ goto normal_char;
- case '\\':
- if (p == pend) return REG_EESCAPE;
+ case '\\':
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
- /* Do not translate the character after the \, so that we can
- distinguish, e.g., \B from \b, even if we normally would
- translate, e.g., B to b. */
- PATFETCH_RAW (c);
+ /* Do not translate the character after the \, so that we can
+ distinguish, e.g., \B from \b, even if we normally would
+ translate, e.g., B to b. */
+ PATFETCH_RAW (c);
- switch (c)
- {
- case '(':
- if (syntax & RE_NO_BK_PARENS)
- goto normal_backslash;
+ switch (c)
+ {
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto normal_backslash;
- handle_open:
- bufp->re_nsub++;
- regnum++;
+ handle_open:
+ bufp->re_nsub++;
+ regnum++;
- if (COMPILE_STACK_FULL)
- {
- RETALLOC (compile_stack.stack, compile_stack.size << 1,
- compile_stack_elt_t);
- if (compile_stack.stack == NULL) return REG_ESPACE;
+ if (COMPILE_STACK_FULL)
+ {
+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
+ compile_stack_elt_t);
+ if (compile_stack.stack == NULL) return REG_ESPACE;
- compile_stack.size <<= 1;
- }
+ compile_stack.size <<= 1;
+ }
- /* These are the values to restore when we hit end of this
- group. They are all relative offsets, so that if the
- whole pattern moves because of realloc, they will still
- be valid. */
- COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
- COMPILE_STACK_TOP.fixup_alt_jump
- = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
- COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
- COMPILE_STACK_TOP.regnum = regnum;
-
- /* We will eventually replace the 0 with the number of
- groups inner to this one. But do not push a
- start_memory for groups beyond the last one we can
- represent in the compiled pattern. */
- if (regnum <= MAX_REGNUM)
- {
- COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
- BUF_PUSH_3 (start_memory, regnum, 0);
- }
+ /* These are the values to restore when we hit end of this
+ group. They are all relative offsets, so that if the
+ whole pattern moves because of realloc, they will still
+ be valid. */
+ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
+ COMPILE_STACK_TOP.fixup_alt_jump
+ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
+ COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
+ COMPILE_STACK_TOP.regnum = regnum;
+
+ /* We will eventually replace the 0 with the number of
+ groups inner to this one. But do not push a
+ start_memory for groups beyond the last one we can
+ represent in the compiled pattern. */
+ if (regnum <= MAX_REGNUM)
+ {
+ COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
+ BUF_PUSH_3 (start_memory, regnum, 0);
+ }
- compile_stack.avail++;
+ compile_stack.avail++;
- fixup_alt_jump = 0;
- laststart = 0;
- begalt = b;
+ fixup_alt_jump = 0;
+ laststart = 0;
+ begalt = b;
/* If we've reached MAX_REGNUM groups, then this open
won't actually generate any code, so we'll have to
clear pending_exact explicitly. */
pending_exact = 0;
- break;
+ break;
- case ')':
- if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
+ case ')':
+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
- if (COMPILE_STACK_EMPTY)
- if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
- goto normal_backslash;
- else
- return REG_ERPAREN;
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_backslash;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
- handle_close:
- if (fixup_alt_jump)
- { /* Push a dummy failure point at the end of the
- alternative for a possible future
- `pop_failure_jump' to pop. See comments at
- `push_dummy_failure' in `re_match_2'. */
- BUF_PUSH (push_dummy_failure);
+ handle_close:
+ if (fixup_alt_jump)
+ { /* Push a dummy failure point at the end of the
+ alternative for a possible future
+ `pop_failure_jump' to pop. See comments at
+ `push_dummy_failure' in `re_match_2'. */
+ BUF_PUSH (push_dummy_failure);
- /* We allocated space for this jump when we assigned
- to `fixup_alt_jump', in the `handle_alt' case below. */
- STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
- }
+ /* We allocated space for this jump when we assigned
+ to `fixup_alt_jump', in the `handle_alt' case below. */
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
+ }
+
+ /* See similar code for backslashed left paren above. */
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_char;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
- /* See similar code for backslashed left paren above. */
- if (COMPILE_STACK_EMPTY)
- if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
- goto normal_char;
- else
- return REG_ERPAREN;
-
- /* Since we just checked for an empty stack above, this
- ``can't happen''. */
- assert (compile_stack.avail != 0);
- {
- /* We don't just want to restore into `regnum', because
- later groups should continue to be numbered higher,
- as in `(ab)c(de)' -- the second group is #2. */
- regnum_t this_group_regnum;
-
- compile_stack.avail--;
- begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
- fixup_alt_jump
- = COMPILE_STACK_TOP.fixup_alt_jump
- ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
- : 0;
- laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
- this_group_regnum = COMPILE_STACK_TOP.regnum;
+ /* Since we just checked for an empty stack above, this
+ ``can't happen''. */
+ assert (compile_stack.avail != 0);
+ {
+ /* We don't just want to restore into `regnum', because
+ later groups should continue to be numbered higher,
+ as in `(ab)c(de)' -- the second group is #2. */
+ regnum_t this_group_regnum;
+
+ compile_stack.avail--;
+ begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
+ fixup_alt_jump
+ = COMPILE_STACK_TOP.fixup_alt_jump
+ ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
+ : 0;
+ laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
+ this_group_regnum = COMPILE_STACK_TOP.regnum;
/* If we've reached MAX_REGNUM groups, then this open
won't actually generate any code, so we'll have to
clear pending_exact explicitly. */
pending_exact = 0;
- /* We're at the end of the group, so now we know how many
- groups were inside this one. */
- if (this_group_regnum <= MAX_REGNUM)
- {
- unsigned char *inner_group_loc
- = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
-
- *inner_group_loc = regnum - this_group_regnum;
- BUF_PUSH_3 (stop_memory, this_group_regnum,
- regnum - this_group_regnum);
- }
- }
- break;
-
-
- case '|': /* `\|'. */
- if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
- goto normal_backslash;
- handle_alt:
- if (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 (3);
- INSERT_JUMP (on_failure_jump, begalt, b + 6);
- pending_exact = 0;
- b += 3;
-
- /* The alternative before this one has a jump after it
- which gets executed if it gets matched. Adjust that
- jump so it will jump to this 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. A picture:
- _____ _____
- | | | |
- | v | v
- a | b | c
-
- If we are at `b', then fixup_alt_jump right now points to a
- three-byte space after `a'. We'll put in the jump, set
- fixup_alt_jump to right after `b', and leave behind three
- bytes which we'll fill in when we get to after `c'. */
-
- if (fixup_alt_jump)
- STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
-
- /* Mark and leave space for a jump after this alternative,
- to be filled in later either by next alternative or
- when know we're at the end of a series of alternatives. */
- fixup_alt_jump = b;
- GET_BUFFER_SPACE (3);
- b += 3;
-
- laststart = 0;
- begalt = b;
- break;
-
-
- case '{':
- /* If \{ is a literal. */
- if (!(syntax & RE_INTERVALS)
- /* If we're at `\{' and it's not the open-interval
- operator. */
- || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
- || (p - 2 == pattern && p == pend))
- goto normal_backslash;
-
- handle_interval:
- {
- /* If got here, then the syntax allows intervals. */
-
- /* At least (most) this many matches must be made. */
- int lower_bound = -1, upper_bound = -1;
-
- beg_interval = p - 1;
-
- if (p == pend)
- {
- if (syntax & RE_NO_BK_BRACES)
- goto unfetch_interval;
- else
- return REG_EBRACE;
- }
-
- GET_UNSIGNED_NUMBER (lower_bound);
-
- if (c == ',')
- {
- GET_UNSIGNED_NUMBER (upper_bound);
- if (upper_bound < 0) upper_bound = RE_DUP_MAX;
- }
- else
- /* Interval such as `{1}' => match exactly once. */
- upper_bound = lower_bound;
-
- if (lower_bound < 0 || upper_bound > RE_DUP_MAX
- || lower_bound > upper_bound)
- {
- if (syntax & RE_NO_BK_BRACES)
- goto unfetch_interval;
- else
- return REG_BADBR;
- }
-
- if (!(syntax & RE_NO_BK_BRACES))
- {
- if (c != '\\') return REG_EBRACE;
-
- PATFETCH (c);
- }
-
- if (c != '}')
- {
- if (syntax & RE_NO_BK_BRACES)
- goto unfetch_interval;
- else
- return REG_BADBR;
- }
-
- /* We just parsed a valid interval. */
-
- /* If it's invalid to have no preceding re. */
- if (!laststart)
- {
- if (syntax & RE_CONTEXT_INVALID_OPS)
- return REG_BADRPT;
- else if (syntax & RE_CONTEXT_INDEP_OPS)
- laststart = b;
- else
- goto unfetch_interval;
- }
-
- /* If the 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 we insert the jump. */
- if (upper_bound == 0)
- {
- GET_BUFFER_SPACE (3);
- INSERT_JUMP (jump, laststart, b + 3);
- b += 3;
- }
-
- /* Otherwise, we have a nontrivial interval. When
- we're all done, the pattern will look like:
- set_number_at <jump count> <upper bound>
- set_number_at <succeed_n count> <lower bound>
- succeed_n <after jump addr> <succeed_n count>
- <body of loop>
- jump_n <succeed_n addr> <jump count>
- (The upper bound and `jump_n' are omitted if
- `upper_bound' is 1, though.) */
- else
- { /* If the upper bound is > 1, we need to insert
- more at the end of the loop. */
- unsigned nbytes = 10 + (upper_bound > 1) * 10;
-
- GET_BUFFER_SPACE (nbytes);
-
- /* Initialize lower bound of the `succeed_n', even
- though it will be set during matching by its
- attendant `set_number_at' (inserted next),
- because `re_compile_fastmap' needs to know.
- Jump to the `jump_n' we might insert below. */
- INSERT_JUMP2 (succeed_n, laststart,
- b + 5 + (upper_bound > 1) * 5,
- lower_bound);
- b += 5;
-
- /* Code to initialize the lower bound. Insert
- before the `succeed_n'. The `5' is the last two
- bytes of this `set_number_at', plus 3 bytes of
- the following `succeed_n'. */
- insert_op2 (set_number_at, laststart, 5, lower_bound, b);
- b += 5;
-
- if (upper_bound > 1)
- { /* More than one repetition is allowed, so
- append a backward jump to the `succeed_n'
- that starts this interval.
-
- When we've reached this during matching,
- we'll have matched the interval once, so
- jump back only `upper_bound - 1' times. */
- STORE_JUMP2 (jump_n, b, laststart + 5,
- upper_bound - 1);
- b += 5;
-
- /* The location we want to set is the second
- parameter of the `jump_n'; that is `b-2' as
- an absolute address. `laststart' will be
- the `set_number_at' we're about to insert;
- `laststart+3' the number to set, the source
- for the relative address. But we are
- inserting into the middle of the pattern --
- so everything is getting moved up by 5.
- Conclusion: (b - 2) - (laststart + 3) + 5,
- i.e., b - laststart.
-
- We insert this at the beginning of the loop
- so that if we fail during matching, we'll
- reinitialize the bounds. */
- insert_op2 (set_number_at, laststart, b - laststart,
- upper_bound - 1, b);
- b += 5;
- }
- }
- pending_exact = 0;
- beg_interval = NULL;
- }
- break;
-
- unfetch_interval:
- /* If an invalid interval, match the characters as literals. */
- assert (beg_interval);
- p = beg_interval;
- beg_interval = NULL;
-
- /* normal_char and normal_backslash need `c'. */
- PATFETCH (c);
-
- if (!(syntax & RE_NO_BK_BRACES))
- {
- if (p > pattern && p[-1] == '\\')
- goto normal_backslash;
- }
- goto normal_char;
+ /* We're at the end of the group, so now we know how many
+ groups were inside this one. */
+ if (this_group_regnum <= MAX_REGNUM)
+ {
+ unsigned char *inner_group_loc
+ = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
+
+ *inner_group_loc = regnum - this_group_regnum;
+ BUF_PUSH_3 (stop_memory, this_group_regnum,
+ regnum - this_group_regnum);
+ }
+ }
+ break;
+
+
+ case '|': /* `\|'. */
+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
+ goto normal_backslash;
+ handle_alt:
+ if (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 (3);
+ INSERT_JUMP (on_failure_jump, begalt, b + 6);
+ pending_exact = 0;
+ b += 3;
+
+ /* The alternative before this one has a jump after it
+ which gets executed if it gets matched. Adjust that
+ jump so it will jump to this 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. A picture:
+ _____ _____
+ | | | |
+ | v | v
+ a | b | c
+
+ If we are at `b', then fixup_alt_jump right now points to a
+ three-byte space after `a'. We'll put in the jump, set
+ fixup_alt_jump to right after `b', and leave behind three
+ bytes which we'll fill in when we get to after `c'. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ /* Mark and leave space for a jump after this alternative,
+ to be filled in later either by next alternative or
+ when know we're at the end of a series of alternatives. */
+ fixup_alt_jump = b;
+ GET_BUFFER_SPACE (3);
+ b += 3;
+
+ laststart = 0;
+ begalt = b;
+ break;
+
+
+ case '{':
+ /* If \{ is a literal. */
+ if (!(syntax & RE_INTERVALS)
+ /* If we're at `\{' and it's not the open-interval
+ operator. */
+ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+ || (p - 2 == pattern && p == pend))
+ goto normal_backslash;
+
+ handle_interval:
+ {
+ /* If got here, then the syntax allows intervals. */
+
+ /* At least (most) this many matches must be made. */
+ int lower_bound = -1, upper_bound = -1;
+
+ beg_interval = p - 1;
+
+ if (p == pend)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_EBRACE);
+ }
+
+ GET_UNSIGNED_NUMBER (lower_bound);
+
+ if (c == ',')
+ {
+ GET_UNSIGNED_NUMBER (upper_bound);
+ if (upper_bound < 0) upper_bound = RE_DUP_MAX;
+ }
+ else
+ /* Interval such as `{1}' => match exactly once. */
+ upper_bound = lower_bound;
+
+ if (lower_bound < 0 || upper_bound > RE_DUP_MAX
+ || lower_bound > upper_bound)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (c != '\\') FREE_STACK_RETURN (REG_EBRACE);
+
+ PATFETCH (c);
+ }
+
+ if (c != '}')
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ /* We just parsed a valid interval. */
+
+ /* If it's invalid to have no preceding re. */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (syntax & RE_CONTEXT_INDEP_OPS)
+ laststart = b;
+ else
+ goto unfetch_interval;
+ }
+
+ /* If the 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 we insert the jump. */
+ if (upper_bound == 0)
+ {
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (jump, laststart, b + 3);
+ b += 3;
+ }
+
+ /* Otherwise, we have a nontrivial interval. When
+ we're all done, the pattern will look like:
+ set_number_at <jump count> <upper bound>
+ set_number_at <succeed_n count> <lower bound>
+ succeed_n <after jump addr> <succeed_n count>
+ <body of loop>
+ jump_n <succeed_n addr> <jump count>
+ (The upper bound and `jump_n' are omitted if
+ `upper_bound' is 1, though.) */
+ else
+ { /* If the upper bound is > 1, we need to insert
+ more at the end of the loop. */
+ unsigned nbytes = 10 + (upper_bound > 1) * 10;
+
+ GET_BUFFER_SPACE (nbytes);
+
+ /* Initialize lower bound of the `succeed_n', even
+ though it will be set during matching by its
+ attendant `set_number_at' (inserted next),
+ because `re_compile_fastmap' needs to know.
+ Jump to the `jump_n' we might insert below. */
+ INSERT_JUMP2 (succeed_n, laststart,
+ b + 5 + (upper_bound > 1) * 5,
+ lower_bound);
+ b += 5;
+
+ /* Code to initialize the lower bound. Insert
+ before the `succeed_n'. The `5' is the last two
+ bytes of this `set_number_at', plus 3 bytes of
+ the following `succeed_n'. */
+ insert_op2 (set_number_at, laststart, 5, lower_bound, b);
+ b += 5;
+
+ if (upper_bound > 1)
+ { /* More than one repetition is allowed, so
+ append a backward jump to the `succeed_n'
+ that starts this interval.
+
+ When we've reached this during matching,
+ we'll have matched the interval once, so
+ jump back only `upper_bound - 1' times. */
+ STORE_JUMP2 (jump_n, b, laststart + 5,
+ upper_bound - 1);
+ b += 5;
+
+ /* The location we want to set is the second
+ parameter of the `jump_n'; that is `b-2' as
+ an absolute address. `laststart' will be
+ the `set_number_at' we're about to insert;
+ `laststart+3' the number to set, the source
+ for the relative address. But we are
+ inserting into the middle of the pattern --
+ so everything is getting moved up by 5.
+ Conclusion: (b - 2) - (laststart + 3) + 5,
+ i.e., b - laststart.
+
+ We insert this at the beginning of the loop
+ so that if we fail during matching, we'll
+ reinitialize the bounds. */
+ insert_op2 (set_number_at, laststart, b - laststart,
+ upper_bound - 1, b);
+ b += 5;
+ }
+ }
+ pending_exact = 0;
+ beg_interval = NULL;
+ }
+ break;
+
+ unfetch_interval:
+ /* If an invalid interval, match the characters as literals. */
+ assert (beg_interval);
+ p = beg_interval;
+ beg_interval = NULL;
+
+ /* normal_char and normal_backslash need `c'. */
+ PATFETCH (c);
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (p > pattern && p[-1] == '\\')
+ goto normal_backslash;
+ }
+ goto normal_char;
#ifdef emacs
- /* There is no way to specify the before_dot and after_dot
- operators. rms says this is ok. --karl */
- case '=':
- BUF_PUSH (at_dot);
- break;
-
- case 's':
- laststart = b;
- PATFETCH (c);
- BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
- break;
-
- case 'S':
- laststart = b;
- PATFETCH (c);
- BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
- break;
+ /* There is no way to specify the before_dot and after_dot
+ operators. rms says this is ok. --karl */
+ case '=':
+ BUF_PUSH (at_dot);
+ break;
+
+ case 's':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
+ break;
+
+ case 'S':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
+ break;
+
+ case 'c':
+ laststart = b;
+ PATFETCH_RAW (c);
+ BUF_PUSH_2 (categoryspec, c);
+ break;
+
+ case 'C':
+ laststart = b;
+ PATFETCH_RAW (c);
+ BUF_PUSH_2 (notcategoryspec, c);
+ break;
#endif /* emacs */
- case 'w':
- laststart = b;
- BUF_PUSH (wordchar);
- break;
-
+ case 'w':
+ laststart = b;
+ BUF_PUSH (wordchar);
+ break;
- case 'W':
- laststart = b;
- BUF_PUSH (notwordchar);
- break;
+ case 'W':
+ laststart = b;
+ BUF_PUSH (notwordchar);
+ break;
- case '<':
- BUF_PUSH (wordbeg);
- break;
- case '>':
- BUF_PUSH (wordend);
- break;
+ case '<':
+ BUF_PUSH (wordbeg);
+ break;
- case 'b':
- BUF_PUSH (wordbound);
- break;
+ case '>':
+ BUF_PUSH (wordend);
+ break;
- case 'B':
- BUF_PUSH (notwordbound);
- break;
+ case 'b':
+ BUF_PUSH (wordbound);
+ break;
- case '`':
- BUF_PUSH (begbuf);
- break;
+ case 'B':
+ BUF_PUSH (notwordbound);
+ break;
- case '\'':
- BUF_PUSH (endbuf);
- break;
+ case '`':
+ BUF_PUSH (begbuf);
+ break;
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- if (syntax & RE_NO_BK_REFS)
- goto normal_char;
+ case '\'':
+ BUF_PUSH (endbuf);
+ break;
- c1 = c - '0';
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ if (syntax & RE_NO_BK_REFS)
+ goto normal_char;
- if (c1 > regnum)
- return REG_ESUBREG;
+ c1 = c - '0';
- /* Can't back reference to a subexpression if inside of it. */
- if (group_in_compile_stack (compile_stack, c1))
- goto normal_char;
+ if (c1 > regnum)
+ FREE_STACK_RETURN (REG_ESUBREG);
- laststart = b;
- BUF_PUSH_2 (duplicate, c1);
- break;
+ /* Can't back reference to a subexpression if inside of it. */
+ if (group_in_compile_stack (compile_stack, c1))
+ goto normal_char;
+ laststart = b;
+ BUF_PUSH_2 (duplicate, c1);
+ break;
- case '+':
- case '?':
- if (syntax & RE_BK_PLUS_QM)
- goto handle_plus;
- else
- goto normal_backslash;
- default:
- normal_backslash:
- /* 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. */
- c = TRANSLATE (c);
- goto normal_char;
- }
- break;
+ case '+':
+ case '?':
+ if (syntax & RE_BK_PLUS_QM)
+ goto handle_plus;
+ else
+ goto normal_backslash;
+
+ default:
+ normal_backslash:
+ /* 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. */
+ c = TRANSLATE (c);
+ goto normal_char;
+ }
+ break;
default:
- /* Expects the character in `c'. */
+ /* Expects the character in `c'. */
normal_char:
+ p1 = p - 1; /* P1 points the head of C. */
+#ifdef emacs
+ if (bufp->multibyte)
+ {
+ c = STRING_CHAR (p1, pend - p1);
+ c = TRANSLATE (c);
+ /* Set P to the next character boundary. */
+ p += MULTIBYTE_FORM_LENGTH (p1, pend - p1) - 1;
+ }
+#endif
/* If no exactn currently being built. */
- if (!pending_exact
+ if (!pending_exact
- /* If last exactn not at current position. */
- || pending_exact + *pending_exact + 1 != b
+ /* If last exactn not at current position. */
+ || pending_exact + *pending_exact + 1 != b
- /* We have only one byte following the exactn for the count. */
- || *pending_exact == (1 << BYTEWIDTH) - 1
+ /* We have only one byte following the exactn for the count. */
+ || *pending_exact >= (1 << BYTEWIDTH) - (p - p1)
- /* If followed by a repetition operator. */
- || *p == '*' || *p == '^'
+ /* If followed by a repetition operator. */
+ || (p != pend && (*p == '*' || *p == '^'))
|| ((syntax & RE_BK_PLUS_QM)
- ? *p == '\\' && (p[1] == '+' || p[1] == '?')
- : (*p == '+' || *p == '?'))
+ ? p + 1 < pend && *p == '\\' && (p[1] == '+' || p[1] == '?')
+ : p != pend && (*p == '+' || *p == '?'))
|| ((syntax & RE_INTERVALS)
- && ((syntax & RE_NO_BK_BRACES)
- ? *p == '{'
- : (p[0] == '\\' && p[1] == '{'))))
+ && ((syntax & RE_NO_BK_BRACES)
+ ? p != pend && *p == '{'
+ : p + 1 < pend && p[0] == '\\' && p[1] == '{')))
{
/* Start building a new exactn. */
- laststart = b;
+ laststart = b;
BUF_PUSH_2 (exactn, 0);
pending_exact = b - 1;
- }
+ }
- BUF_PUSH (c);
- (*pending_exact)++;
+#ifdef emacs
+ if (! SINGLE_BYTE_CHAR_P (c))
+ {
+ unsigned char work[4], *str;
+ int i = CHAR_STRING (c, work, str);
+ int j;
+ for (j = 0; j < i; j++)
+ {
+ BUF_PUSH (str[j]);
+ (*pending_exact)++;
+ }
+ }
+ else
+#endif
+ {
+ BUF_PUSH (c);
+ (*pending_exact)++;
+ }
break;
- } /* switch (c) */
+ } /* switch (c) */
} /* while p != pend */
@@ -2044,7 +2966,12 @@ regex_compile (pattern, size, syntax, bufp)
STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
if (!COMPILE_STACK_EMPTY)
- return REG_EPAREN;
+ FREE_STACK_RETURN (REG_EPAREN);
+
+ /* If we don't want backtracking, force success
+ the first time we reach the end of the compiled pattern. */
+ if (syntax & RE_NO_POSIX_BACKTRACKING)
+ BUF_PUSH (succeed);
free (compile_stack.stack);
@@ -2054,17 +2981,55 @@ regex_compile (pattern, size, syntax, bufp)
#ifdef DEBUG
if (debug)
{
- DEBUG_PRINT1 ("\nCompiled pattern: ");
+ DEBUG_PRINT1 ("\nCompiled pattern: \n");
print_compiled_pattern (bufp);
}
#endif /* DEBUG */
+#ifndef MATCH_MAY_ALLOCATE
+ /* Initialize the failure stack to the largest possible stack. This
+ isn't necessary unless we're trying to avoid calling alloca in
+ the search and match routines. */
+ {
+ int num_regs = bufp->re_nsub + 1;
+
+ if (fail_stack.size < re_max_failures * TYPICAL_FAILURE_SIZE)
+ {
+ fail_stack.size = re_max_failures * TYPICAL_FAILURE_SIZE;
+
+#ifdef emacs
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) xmalloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) xrealloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+#else /* not emacs */
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) malloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) realloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+#endif /* not emacs */
+ }
+
+ regex_grow_registers (num_regs);
+ }
+#endif /* not MATCH_MAY_ALLOCATE */
+
return REG_NOERROR;
} /* regex_compile */
/* Subroutines for `regex_compile'. */
-/* Store OP at LOC followed by two-byte integer parameter ARG. */
+/* Store OP at LOC followed by two-byte integer parameter ARG. */
static void
store_op1 (op, loc, arg)
@@ -2145,7 +3110,7 @@ at_begline_loc_p (pattern, p, syntax)
return
/* After a subexpression? */
(*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
- /* After an alternative? */
+ /* After an alternative? */
|| (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
}
@@ -2160,19 +3125,19 @@ at_endline_loc_p (p, pend, syntax)
{
const char *next = p;
boolean next_backslash = *next == '\\';
- const char *next_next = p + 1 < pend ? p + 1 : NULL;
-
+ 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 == ')')
+ : next_backslash && next_next && *next_next == ')')
/* Before an alternative? */
|| (syntax & RE_NO_BK_VBAR ? *next == '|'
- : next_backslash && next_next && *next_next == '|');
+ : next_backslash && next_next && *next_next == '|');
}
-/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
false if it's not. */
static boolean
@@ -2182,378 +3147,14 @@ group_in_compile_stack (compile_stack, regnum)
{
int this_element;
- for (this_element = compile_stack.avail - 1;
- this_element >= 0;
+ 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. */
-
-static reg_errcode_t
-compile_range (p_ptr, pend, translate, syntax, b)
- const char **p_ptr, *pend;
- char *translate;
- reg_syntax_t syntax;
- unsigned char *b;
-{
- unsigned this_char;
-
- const char *p = *p_ptr;
- int range_start, range_end;
-
- if (p == pend)
- return REG_ERANGE;
-
- /* Even though the pattern is a signed `char *', we need to fetch
- with unsigned char *'s; if the high bit of the pattern character
- is set, the range endpoints will be negative if we fetch using a
- signed char *.
-
- We also want to fetch the endpoints without translating them; the
- appropriate translation is done in the bit-setting loop below. */
- range_start = ((unsigned char *) p)[-2];
- range_end = ((unsigned char *) p)[0];
-
- /* Have to increment the pointer into the pattern string, so the
- caller isn't still at the ending character. */
- (*p_ptr)++;
-
- /* If the start is after the end, the range is empty. */
- if (range_start > range_end)
- return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
-
- /* Here we see why `this_char' has to be larger than an `unsigned
- char' -- the range is inclusive, so if `range_end' == 0xff
- (assuming 8-bit characters), we would otherwise go into an infinite
- loop, since all characters <= 0xff. */
- for (this_char = range_start; this_char <= range_end; this_char++)
- {
- SET_LIST_BIT (TRANSLATE (this_char));
- }
-
- return REG_NOERROR;
-}
-
-/* Failure stack declarations and macros; both re_compile_fastmap and
- re_match_2 use a failure stack. These have to be macros because of
- REGEX_ALLOCATE. */
-
-
-/* Number of failure points for which to initially allocate space
- when matching. If this number is exceeded, we allocate more
- space, so it is not a hard limit. */
-#ifndef INIT_FAILURE_ALLOC
-#define INIT_FAILURE_ALLOC 5
-#endif
-
-/* Roughly the maximum number of failure points on the stack. Would be
- exactly that if always used MAX_FAILURE_SPACE each time we failed.
- This is a variable only so users of regex can assign to it; we never
- change it ourselves. */
-int re_max_failures = 2000;
-
-union fail_stack_elt
-{
- unsigned char *pointer;
- int integer;
-};
-
-typedef union fail_stack_elt fail_stack_elt_t;
-
-typedef struct
-{
- fail_stack_elt_t *stack;
- unsigned size;
- unsigned avail; /* Offset of next open position. */
-} fail_stack_type;
-
-#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
-#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
-#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
-#define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail])
-
-
-/* Initialize `fail_stack'. Do `return -2' if the alloc fails. */
-
-#define INIT_FAIL_STACK() \
- do { \
- fail_stack.stack = (fail_stack_elt_t *) \
- REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
- \
- if (fail_stack.stack == NULL) \
- return -2; \
- \
- fail_stack.size = INIT_FAILURE_ALLOC; \
- fail_stack.avail = 0; \
- } while (0)
-
-
-/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
-
- Return 1 if succeeds, and 0 if either ran out of memory
- allocating space for it or it was already too large.
-
- REGEX_REALLOCATE requires `destination' be declared. */
-
-#define DOUBLE_FAIL_STACK(fail_stack) \
- ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \
- ? 0 \
- : ((fail_stack).stack = (fail_stack_elt_t *) \
- REGEX_REALLOCATE ((fail_stack).stack, \
- (fail_stack).size * sizeof (fail_stack_elt_t), \
- ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
- \
- (fail_stack).stack == NULL \
- ? 0 \
- : ((fail_stack).size <<= 1, \
- 1)))
-
-
-/* Push PATTERN_OP on FAIL_STACK.
-
- Return 1 if was able to do so and 0 if ran out of memory allocating
- space to do so. */
-#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \
- ((FAIL_STACK_FULL () \
- && !DOUBLE_FAIL_STACK (FAIL_STACK)) \
- ? 0 \
- : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \
- 1))
-
-/* Push a pointer value onto the failure stack.
- Assumes the variable `fail_stack'. Probably should only
- be called from within `PUSH_FAILURE_POINT'. */
-#define PUSH_FAILURE_POINTER(item) \
- fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item)
-
-/* This pushes an integer-valued item onto the failure stack.
- Assumes the variable `fail_stack'. Probably should only
- be called from within `PUSH_FAILURE_POINT'. */
-#define PUSH_FAILURE_INT(item) \
- fail_stack.stack[fail_stack.avail++].integer = (item)
-
-/* Push a fail_stack_elt_t value onto the failure stack.
- Assumes the variable `fail_stack'. Probably should only
- be called from within `PUSH_FAILURE_POINT'. */
-#define PUSH_FAILURE_ELT(item) \
- fail_stack.stack[fail_stack.avail++] = (item)
-
-/* These three POP... operations complement the three PUSH... operations.
- All assume that `fail_stack' is nonempty. */
-#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
-#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
-#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
-
-/* Used to omit pushing failure point id's when we're not debugging. */
-#ifdef DEBUG
-#define DEBUG_PUSH PUSH_FAILURE_INT
-#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
-#else
-#define DEBUG_PUSH(item)
-#define DEBUG_POP(item_addr)
-#endif
-
-
-/* Push the information about the state we will need
- if we ever fail back to it.
-
- Requires variables fail_stack, regstart, regend, reg_info, and
- num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be
- declared.
-
- Does `return FAILURE_CODE' if runs out of memory. */
-
-#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
- do { \
- char *destination; \
- /* Must be int, so when we don't save any registers, the arithmetic \
- of 0 + -1 isn't done as unsigned. */ \
- int this_reg; \
- \
- DEBUG_STATEMENT (failure_id++); \
- DEBUG_STATEMENT (nfailure_points_pushed++); \
- DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
- DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
- DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
- \
- DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \
- DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
- \
- /* Ensure we have enough space allocated for what we will push. */ \
- while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
- { \
- if (!DOUBLE_FAIL_STACK (fail_stack)) \
- return failure_code; \
- \
- DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
- (fail_stack).size); \
- DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
- } \
- \
- /* Push the info, starting with the registers. */ \
- DEBUG_PRINT1 ("\n"); \
- \
- if (1) \
- for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
- this_reg++) \
- { \
- DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \
- DEBUG_STATEMENT (num_regs_pushed++); \
- \
- DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
- PUSH_FAILURE_POINTER (regstart[this_reg]); \
- \
- DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
- PUSH_FAILURE_POINTER (regend[this_reg]); \
- \
- DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \
- DEBUG_PRINT2 (" match_null=%d", \
- REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
- DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
- DEBUG_PRINT2 (" matched_something=%d", \
- MATCHED_SOMETHING (reg_info[this_reg])); \
- DEBUG_PRINT2 (" ever_matched=%d", \
- EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
- DEBUG_PRINT1 ("\n"); \
- PUSH_FAILURE_ELT (reg_info[this_reg].word); \
- } \
- \
- DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\
- PUSH_FAILURE_INT (lowest_active_reg); \
- \
- DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\
- PUSH_FAILURE_INT (highest_active_reg); \
- \
- DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \
- DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
- PUSH_FAILURE_POINTER (pattern_place); \
- \
- DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \
- DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
- size2); \
- DEBUG_PRINT1 ("'\n"); \
- PUSH_FAILURE_POINTER (string_place); \
- \
- DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
- DEBUG_PUSH (failure_id); \
- } while (0)
-
-/* This is the number of items that are pushed and popped on the stack
- for each register. */
-#define NUM_REG_ITEMS 3
-
-/* Individual items aside from the registers. */
-#ifdef DEBUG
-#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
-#else
-#define NUM_NONREG_ITEMS 4
-#endif
-
-/* We push at most this many items on the stack. */
-#define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
-
-/* We actually push this many items. */
-#define NUM_FAILURE_ITEMS \
- ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \
- + NUM_NONREG_ITEMS)
-
-/* How many items can still be added to the stack without overflowing it. */
-#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
-
-
-/* Pops what PUSH_FAIL_STACK pushes.
-
- We restore into the parameters, all of which should be lvalues:
- STR -- the saved data position.
- PAT -- the saved pattern position.
- LOW_REG, HIGH_REG -- the highest and lowest active registers.
- REGSTART, REGEND -- arrays of string positions.
- REG_INFO -- array of information about each subexpression.
-
- Also assumes the variables `fail_stack' and (if debugging), `bufp',
- `pend', `string1', `size1', `string2', and `size2'. */
-
-#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
-{ \
- DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \
- int this_reg; \
- const unsigned char *string_temp; \
- \
- assert (!FAIL_STACK_EMPTY ()); \
- \
- /* Remove failure points and point to how many regs pushed. */ \
- DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
- DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
- DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
- \
- assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
- \
- DEBUG_POP (&failure_id); \
- DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
- \
- /* If the saved string location is NULL, it came from an \
- on_failure_keep_string_jump opcode, and we want to throw away the \
- saved NULL, thus retaining our current position in the string. */ \
- string_temp = POP_FAILURE_POINTER (); \
- if (string_temp != NULL) \
- str = (const char *) string_temp; \
- \
- DEBUG_PRINT2 (" Popping string 0x%x: `", str); \
- DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
- DEBUG_PRINT1 ("'\n"); \
- \
- pat = (unsigned char *) POP_FAILURE_POINTER (); \
- DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \
- DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
- \
- /* Restore register info. */ \
- high_reg = (unsigned) POP_FAILURE_INT (); \
- DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \
- \
- low_reg = (unsigned) POP_FAILURE_INT (); \
- DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \
- \
- if (1) \
- for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
- { \
- DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \
- \
- reg_info[this_reg].word = POP_FAILURE_ELT (); \
- DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \
- \
- regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \
- DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
- \
- regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \
- DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
- } \
- else \
- { \
- for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
- { \
- reg_info[this_reg].word.integer = 0; \
- regend[this_reg] = 0; \
- regstart[this_reg] = 0; \
- } \
- highest_active_reg = high_reg; \
- } \
- \
- DEBUG_STATEMENT (nfailure_points_popped++); \
-} /* POP_FAILURE_POINT */
/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
@@ -2572,8 +3173,10 @@ int
re_compile_fastmap (bufp)
struct re_pattern_buffer *bufp;
{
- int j, k;
+ int i, j, k;
+#ifdef MATCH_MAY_ALLOCATE
fail_stack_type fail_stack;
+#endif
#ifndef REGEX_MALLOC
char *destination;
#endif
@@ -2586,8 +3189,12 @@ re_compile_fastmap (bufp)
unsigned char *p = pattern;
register unsigned char *pend = pattern + size;
+ /* This holds the pointer to the failure stack, when
+ it is allocated relocatably. */
+ fail_stack_elt_t *failure_stack_ptr;
+
/* Assume that each path through the pattern can be null until
- proven otherwise. We set this false at the bottom of switch
+ proven otherwise. We set this false at the bottom of switch
statement, to which we get only if a particular path doesn't
match the empty string. */
boolean path_can_be_null = true;
@@ -2595,69 +3202,81 @@ re_compile_fastmap (bufp)
/* We aren't doing a `succeed_n' to begin with. */
boolean succeed_n_p = false;
+ /* If all elements for base leading-codes in fastmap is set, this
+ flag is set true. */
+ boolean match_any_multibyte_characters = false;
+
+ /* Maximum code of simple (single byte) character. */
+ int simple_char_max;
+
assert (fastmap != NULL && p != NULL);
INIT_FAIL_STACK ();
- bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
bufp->fastmap_accurate = 1; /* It will be when we're done. */
bufp->can_be_null = 0;
- while (p != pend || !FAIL_STACK_EMPTY ())
+ while (1)
{
- if (p == pend)
- {
- bufp->can_be_null |= path_can_be_null;
-
- /* Reset for next path. */
- path_can_be_null = true;
-
- p = fail_stack.stack[--fail_stack.avail].pointer;
+ if (p == pend || *p == succeed)
+ {
+ /* We have reached the (effective) end of pattern. */
+ if (!FAIL_STACK_EMPTY ())
+ {
+ bufp->can_be_null |= path_can_be_null;
+
+ /* Reset for next path. */
+ path_can_be_null = true;
+
+ p = fail_stack.stack[--fail_stack.avail].pointer;
+
+ continue;
+ }
+ else
+ break;
}
- /* We should never be about to go beyond the end of the pattern. */
+ /* We should never be about to go beyond the end of the pattern. */
assert (p < pend);
-
-#ifdef SWITCH_ENUM_BUG
- switch ((int) ((re_opcode_t) *p++))
-#else
- switch ((re_opcode_t) *p++)
-#endif
+
+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
{
- /* I guess the idea here is to simply not bother with a fastmap
- if a backreference is used, since it's too hard to figure out
- the fastmap for the corresponding group. Setting
- `can_be_null' stops `re_search_2' from using the fastmap, so
- that is all we do. */
+ /* I guess the idea here is to simply not bother with a fastmap
+ if a backreference is used, since it's too hard to figure out
+ the fastmap for the corresponding group. Setting
+ `can_be_null' stops `re_search_2' from using the fastmap, so
+ that is all we do. */
case duplicate:
bufp->can_be_null = 1;
- return 0;
+ goto done;
/* Following are the cases which match a character. These end
- with `break'. */
+ with `break'. */
case exactn:
- fastmap[p[1]] = 1;
+ fastmap[p[1]] = 1;
break;
- case charset:
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+#ifndef emacs
+ case charset:
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
- fastmap[j] = 1;
+ fastmap[j] = 1;
break;
case charset_not:
/* Chars beyond end of map must be allowed. */
for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
- fastmap[j] = 1;
+ fastmap[j] = 1;
for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
- fastmap[j] = 1;
- break;
+ fastmap[j] = 1;
+ break;
case wordchar:
@@ -2672,171 +3291,327 @@ re_compile_fastmap (bufp)
if (SYNTAX (j) != Sword)
fastmap[j] = 1;
break;
+#else /* emacs */
+ case charset:
+ for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH - 1, p++;
+ j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+ fastmap[j] = 1;
+ if (CHARSET_RANGE_TABLE_EXISTS_P (&p[-2])
+ && match_any_multibyte_characters == false)
+ {
+ /* Set fastmap[I] 1 where I is a base leading code of each
+ multibyte character in the range table. */
+ int c, count;
- case anychar:
- /* `.' matches anything ... */
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- fastmap[j] = 1;
+ /* Make P points the range table. */
+ p += CHARSET_BITMAP_SIZE (&p[-2]);
+
+ /* Extract the number of ranges in range table into
+ COUNT. */
+ EXTRACT_NUMBER_AND_INCR (count, p);
+ for (; count > 0; count--, p += 2 * 3) /* XXX */
+ {
+ /* Extract the start of each range. */
+ EXTRACT_CHARACTER (c, p);
+ j = CHAR_CHARSET (c);
+ fastmap[CHARSET_LEADING_CODE_BASE (j)] = 1;
+ }
+ }
+ break;
- /* ... except perhaps newline. */
- if (!(bufp->syntax & RE_DOT_NEWLINE))
- fastmap['\n'] = 0;
- /* Return if we have already set `can_be_null'; if we have,
- then the fastmap is irrelevant. Something's wrong here. */
- else if (bufp->can_be_null)
- return 0;
+ case charset_not:
+ /* Chars beyond end of bitmap are possible matches.
+ All the single-byte codes can occur in multibyte buffers.
+ So any that are not listed in the charset
+ are possible matches, even in multibyte buffers. */
+ simple_char_max = (1 << BYTEWIDTH);
+ for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH;
+ j < simple_char_max; j++)
+ fastmap[j] = 1;
+
+ for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH - 1, p++;
+ j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+ fastmap[j] = 1;
- /* Otherwise, have to check alternative paths. */
+ if (bufp->multibyte)
+ /* Any character set can possibly contain a character
+ which doesn't match the specified set of characters. */
+ {
+ set_fastmap_for_multibyte_characters:
+ if (match_any_multibyte_characters == false)
+ {
+ for (j = 0x80; j < 0xA0; j++) /* XXX */
+ if (BASE_LEADING_CODE_P (j))
+ fastmap[j] = 1;
+ match_any_multibyte_characters = true;
+ }
+ }
break;
+ case wordchar:
+ /* All the single-byte codes can occur in multibyte buffers,
+ and they may have word syntax. So do consider them. */
+ simple_char_max = (1 << BYTEWIDTH);
+ for (j = 0; j < simple_char_max; j++)
+ if (SYNTAX (j) == Sword)
+ fastmap[j] = 1;
+
+ if (bufp->multibyte)
+ /* Any character set can possibly contain a character
+ whose syntax is `Sword'. */
+ goto set_fastmap_for_multibyte_characters;
+ break;
+
+
+ case notwordchar:
+ /* All the single-byte codes can occur in multibyte buffers,
+ and they may not have word syntax. So do consider them. */
+ simple_char_max = (1 << BYTEWIDTH);
+ for (j = 0; j < simple_char_max; j++)
+ if (SYNTAX (j) != Sword)
+ fastmap[j] = 1;
+
+ if (bufp->multibyte)
+ /* Any character set can possibly contain a character
+ whose syntax is not `Sword'. */
+ goto set_fastmap_for_multibyte_characters;
+ break;
+#endif
+
+ case anychar:
+ {
+ int fastmap_newline = fastmap['\n'];
+
+ /* `.' matches anything, except perhaps newline.
+ Even in a multibyte buffer, it should match any
+ conceivable byte value for the fastmap. */
+ if (bufp->multibyte)
+ match_any_multibyte_characters = true;
+
+ simple_char_max = (1 << BYTEWIDTH);
+ for (j = 0; j < simple_char_max; j++)
+ fastmap[j] = 1;
+
+ /* ... except perhaps newline. */
+ if (!(bufp->syntax & RE_DOT_NEWLINE))
+ fastmap['\n'] = fastmap_newline;
+
+ /* Return if we have already set `can_be_null'; if we have,
+ then the fastmap is irrelevant. Something's wrong here. */
+ else if (bufp->can_be_null)
+ goto done;
+
+ /* Otherwise, have to check alternative paths. */
+ break;
+ }
+
#ifdef emacs
- case syntaxspec:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ case notsyntaxspec:
+ case syntaxspec:
+ /* This match depends on text properties. These end with
+ aborting optimizations. */
+ bufp->can_be_null = 1;
+ goto done;
+#if 0
k = *p++;
- for (j = 0; j < (1 << BYTEWIDTH); j++)
+ simple_char_max = bufp->multibyte ? 0x80 : (1 << BYTEWIDTH);
+ for (j = 0; j < simple_char_max; j++)
if (SYNTAX (j) == (enum syntaxcode) k)
fastmap[j] = 1;
- break;
+ if (bufp->multibyte)
+ /* Any character set can possibly contain a character
+ whose syntax is K. */
+ goto set_fastmap_for_multibyte_characters;
+ break;
case notsyntaxspec:
k = *p++;
- for (j = 0; j < (1 << BYTEWIDTH); j++)
+ simple_char_max = bufp->multibyte ? 0x80 : (1 << BYTEWIDTH);
+ for (j = 0; j < simple_char_max; j++)
if (SYNTAX (j) != (enum syntaxcode) k)
fastmap[j] = 1;
+
+ if (bufp->multibyte)
+ /* Any character set can possibly contain a character
+ whose syntax is not K. */
+ goto set_fastmap_for_multibyte_characters;
break;
+#endif
+
+ case categoryspec:
+ k = *p++;
+ simple_char_max = (1 << BYTEWIDTH);
+ for (j = 0; j < simple_char_max; j++)
+ if (CHAR_HAS_CATEGORY (j, k))
+ fastmap[j] = 1;
+
+ if (bufp->multibyte)
+ /* Any character set can possibly contain a character
+ whose category is K. */
+ goto set_fastmap_for_multibyte_characters;
+ break;
+
+
+ case notcategoryspec:
+ k = *p++;
+ simple_char_max = (1 << BYTEWIDTH);
+ for (j = 0; j < simple_char_max; j++)
+ if (!CHAR_HAS_CATEGORY (j, k))
+ fastmap[j] = 1;
+
+ if (bufp->multibyte)
+ /* Any character set can possibly contain a character
+ whose category is not K. */
+ goto set_fastmap_for_multibyte_characters;
+ break;
/* All cases after this match the empty string. These end with
- `continue'. */
+ `continue'. */
case before_dot:
case at_dot:
case after_dot:
- continue;
-#endif /* not emacs */
+ continue;
+#endif /* emacs */
- case no_op:
- case begline:
- case endline:
+ case no_op:
+ case begline:
+ case endline:
case begbuf:
case endbuf:
+#ifndef emacs
case wordbound:
case notwordbound:
case wordbeg:
case wordend:
- case push_dummy_failure:
- continue;
+#endif
+ case push_dummy_failure:
+ continue;
case jump_n:
- case pop_failure_jump:
+ case pop_failure_jump:
case maybe_pop_jump:
case jump:
- case jump_past_alt:
+ case jump_past_alt:
case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR (j, p);
+ EXTRACT_NUMBER_AND_INCR (j, p);
p += j;
if (j > 0)
continue;
- /* Jump backward implies we just went through the body of a
- loop and matched nothing. Opcode jumped to should be
- `on_failure_jump' or `succeed_n'. Just treat it like an
- ordinary jump. For a * loop, it has pushed its failure
- point already; if so, discard that as redundant. */
- if ((re_opcode_t) *p != on_failure_jump
+ /* Jump backward implies we just went through the body of a
+ loop and matched nothing. Opcode jumped to should be
+ `on_failure_jump' or `succeed_n'. Just treat it like an
+ ordinary jump. For a * loop, it has pushed its failure
+ point already; if so, discard that as redundant. */
+ if ((re_opcode_t) *p != on_failure_jump
&& (re_opcode_t) *p != succeed_n)
continue;
- p++;
- EXTRACT_NUMBER_AND_INCR (j, p);
- p += j;
+ p++;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
- /* If what's on the stack is where we are now, pop it. */
- if (!FAIL_STACK_EMPTY ()
+ /* If what's on the stack is where we are now, pop it. */
+ if (!FAIL_STACK_EMPTY ()
&& fail_stack.stack[fail_stack.avail - 1].pointer == p)
- fail_stack.avail--;
+ fail_stack.avail--;
- continue;
+ continue;
- case on_failure_jump:
- case on_failure_keep_string_jump:
+ case on_failure_jump:
+ case on_failure_keep_string_jump:
handle_on_failure_jump:
- EXTRACT_NUMBER_AND_INCR (j, p);
-
- /* For some patterns, e.g., `(a?)?', `p+j' here points to the
- end of the pattern. We don't want to push such a point,
- since when we restore it above, entering the switch will
- increment `p' past the end of the pattern. We don't need
- to push such a point since we obviously won't find any more
- fastmap entries beyond `pend'. Such a pattern can match
- the null string, though. */
- if (p + j < pend)
- {
- if (!PUSH_PATTERN_OP (p + j, fail_stack))
- return -2;
- }
- else
- bufp->can_be_null = 1;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+
+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
+ end of the pattern. We don't want to push such a point,
+ since when we restore it above, entering the switch will
+ increment `p' past the end of the pattern. We don't need
+ to push such a point since we obviously won't find any more
+ fastmap entries beyond `pend'. Such a pattern can match
+ the null string, though. */
+ if (p + j < pend)
+ {
+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
+ {
+ RESET_FAIL_STACK ();
+ return -2;
+ }
+ }
+ else
+ bufp->can_be_null = 1;
- if (succeed_n_p)
- {
- EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
- succeed_n_p = false;
+ if (succeed_n_p)
+ {
+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
+ succeed_n_p = false;
}
- continue;
+ continue;
case succeed_n:
- /* Get to the number of times to succeed. */
- p += 2;
+ /* 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)
+ /* Increment p past the n for when k != 0. */
+ EXTRACT_NUMBER_AND_INCR (k, p);
+ if (k == 0)
{
- p -= 4;
- succeed_n_p = true; /* Spaghetti code alert. */
- goto handle_on_failure_jump;
- }
- continue;
+ p -= 4;
+ succeed_n_p = true; /* Spaghetti code alert. */
+ goto handle_on_failure_jump;
+ }
+ continue;
case set_number_at:
- p += 4;
- continue;
+ p += 4;
+ continue;
case start_memory:
- case stop_memory:
+ case stop_memory:
p += 2;
continue;
default:
- abort (); /* We have listed all the cases. */
- } /* switch *p++ */
+ abort (); /* We have listed all the cases. */
+ } /* switch *p++ */
/* Getting here means we have found the possible starting
- characters for one path of the pattern -- and that the empty
- string does not match. We need not follow this path further.
- Instead, look at the next alternative (remembered on the
- stack), or quit if no more. The test at the top of the loop
- does these things. */
+ characters for one path of the pattern -- and that the empty
+ string does not match. We need not follow this path further.
+ Instead, look at the next alternative (remembered on the
+ stack), or quit if no more. The test at the top of the loop
+ does these things. */
path_can_be_null = false;
p = pend;
} /* while p */
/* Set `can_be_null' for the last path (also the first path, if the
- pattern is empty). */
+ pattern is empty). */
bufp->can_be_null |= path_can_be_null;
+
+ done:
+ RESET_FAIL_STACK ();
return 0;
} /* re_compile_fastmap */
@@ -2875,7 +3650,7 @@ re_set_registers (bufp, regs, num_regs, starts, ends)
}
}
-/* Searching routines. */
+/* Searching routines. */
/* Like re_search_2, below, but only one string is specified, and
doesn't let you say where to stop matching. */
@@ -2891,6 +3666,13 @@ re_search (bufp, string, size, startpos, range, regs)
regs, size);
}
+/* End address of virtual concatenation of string. */
+#define STOP_ADDR_VSTRING(P) \
+ (((P) >= size1 ? string2 + size2 : string1 + size1))
+
+/* Address of POS in the concatenation of virtual string. */
+#define POS_ADDR_VSTRING(POS) \
+ (((POS) >= size1 ? string2 - size1 : string1) + (POS))
/* Using the compiled pattern in BUFP->buffer, first tries to match the
virtual concatenation of STRING1 and STRING2, starting first at index
@@ -2925,29 +3707,34 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
{
int val;
register char *fastmap = bufp->fastmap;
- register char *translate = bufp->translate;
+ register RE_TRANSLATE_TYPE translate = bufp->translate;
int total_size = size1 + size2;
int endpos = startpos + range;
+ int anchored_start = 0;
+
+ /* Nonzero if we have to concern multibyte character. */
+ int multibyte = bufp->multibyte;
/* Check for out-of-range STARTPOS. */
if (startpos < 0 || startpos > total_size)
return -1;
/* Fix up RANGE if it might eventually take us outside
- the virtual concatenation of STRING1 and STRING2. */
- if (endpos < -1)
- range = -1 - startpos;
+ the virtual concatenation of STRING1 and STRING2.
+ Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */
+ if (endpos < 0)
+ range = 0 - 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
- search for a pattern that must be anchored. */
+ search for a pattern anchored at beginning of buffer. */
if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0)
{
if (startpos > 0)
return -1;
else
- range = 1;
+ range = 0;
}
#ifdef emacs
@@ -2955,8 +3742,8 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
don't keep searching past point. */
if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
{
- range = PT - startpos;
- if (range <= 0)
+ range = PT_BYTE - BEGV_BYTE - startpos;
+ if (range < 0)
return -1;
}
#endif /* emacs */
@@ -2966,57 +3753,122 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
if (re_compile_fastmap (bufp) == -2)
return -2;
+ /* See whether the pattern is anchored. */
+ if (bufp->buffer[0] == begline)
+ anchored_start = 1;
+
+#ifdef emacs
+ gl_state.object = re_match_object;
+ {
+ int adjpos = NILP (re_match_object) || BUFFERP (re_match_object);
+ int charpos = SYNTAX_TABLE_BYTE_TO_CHAR (startpos + adjpos);
+
+ SETUP_SYNTAX_TABLE_FOR_OBJECT (re_match_object, charpos, 1);
+ }
+#endif
+
/* Loop through the string, looking for a place to start matching. */
for (;;)
{
+ /* If the pattern is anchored,
+ skip quickly past places we cannot match.
+ We don't bother to treat startpos == 0 specially
+ because that case doesn't repeat. */
+ if (anchored_start && startpos > 0)
+ {
+ if (! (bufp->newline_anchor
+ && ((startpos <= size1 ? string1[startpos - 1]
+ : string2[startpos - size1 - 1])
+ == '\n')))
+ goto advance;
+ }
+
/* If a fastmap is supplied, skip quickly over characters that
- cannot be the start of a match. If the pattern can match the
- null string, however, we don't need to skip characters; we want
- the first null string. */
+ cannot be the start of a match. If the pattern can match the
+ null string, however, we don't need to skip characters; we want
+ the first null string. */
if (fastmap && startpos < total_size && !bufp->can_be_null)
{
- if (range > 0) /* Searching forwards. */
+ register const char *d;
+ register unsigned int buf_ch;
+
+ d = POS_ADDR_VSTRING (startpos);
+
+ if (range > 0) /* Searching forwards. */
{
- register const char *d;
register int lim = 0;
int irange = range;
- if (startpos < size1 && startpos + range >= size1)
- lim = range - (size1 - startpos);
-
- d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
+ if (startpos < size1 && startpos + range >= size1)
+ lim = range - (size1 - startpos);
- /* Written out as an if-else to avoid testing `translate'
- inside the loop. */
- if (translate)
- while (range > lim
- && !fastmap[(unsigned char)
- translate[(unsigned char) *d++]])
- range--;
+ /* Written out as an if-else to avoid testing `translate'
+ inside the loop. */
+ if (RE_TRANSLATE_P (translate))
+ {
+ if (multibyte)
+ while (range > lim)
+ {
+ int buf_charlen;
+
+ buf_ch = STRING_CHAR_AND_LENGTH (d, range - lim,
+ buf_charlen);
+
+ buf_ch = RE_TRANSLATE (translate, buf_ch);
+ if (buf_ch >= 0400
+ || fastmap[buf_ch])
+ break;
+
+ range -= buf_charlen;
+ d += buf_charlen;
+ }
+ else
+ while (range > lim
+ && !fastmap[(unsigned char)
+ RE_TRANSLATE (translate, (unsigned char) *d)])
+ {
+ d++;
+ range--;
+ }
+ }
else
- while (range > lim && !fastmap[(unsigned char) *d++])
- range--;
+ while (range > lim && !fastmap[(unsigned char) *d])
+ {
+ d++;
+ range--;
+ }
startpos += irange - range;
}
- else /* Searching backwards. */
+ else /* Searching backwards. */
{
- register char c = (size1 == 0 || startpos >= size1
- ? string2[startpos - size1]
- : string1[startpos]);
+ int room = (size1 == 0 || startpos >= size1
+ ? size2 + size1 - startpos
+ : size1 - startpos);
- if (!fastmap[(unsigned char) TRANSLATE (c)])
+ buf_ch = STRING_CHAR (d, room);
+ if (RE_TRANSLATE_P (translate))
+ buf_ch = RE_TRANSLATE (translate, buf_ch);
+
+ if (! (buf_ch >= 0400
+ || fastmap[buf_ch]))
goto advance;
}
}
/* If can't match the null string, and that's all we have left, fail. */
if (range >= 0 && startpos == total_size && fastmap
- && !bufp->can_be_null)
+ && !bufp->can_be_null)
return -1;
- val = re_match_2 (bufp, string1, size1, string2, size2,
- startpos, regs, stop);
+ val = re_match_2_internal (bufp, string1, size1, string2, size2,
+ startpos, regs, stop);
+#ifndef REGEX_MALLOC
+#ifdef C_ALLOCA
+ alloca (0);
+#endif
+#endif
+
if (val >= 0)
return startpos;
@@ -3025,17 +3877,60 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
advance:
if (!range)
- break;
+ break;
else if (range > 0)
- {
- range--;
- startpos++;
- }
+ {
+ /* Update STARTPOS to the next character boundary. */
+ if (multibyte)
+ {
+ const unsigned char *p
+ = (const unsigned char *) POS_ADDR_VSTRING (startpos);
+ const unsigned char *pend
+ = (const unsigned char *) STOP_ADDR_VSTRING (startpos);
+ int len = MULTIBYTE_FORM_LENGTH (p, pend - p);
+
+ range -= len;
+ if (range < 0)
+ break;
+ startpos += len;
+ }
+ else
+ {
+ range--;
+ startpos++;
+ }
+ }
else
- {
- range++;
- startpos--;
- }
+ {
+ range++;
+ startpos--;
+
+ /* Update STARTPOS to the previous character boundary. */
+ if (multibyte)
+ {
+ const unsigned char *p
+ = (const unsigned char *) POS_ADDR_VSTRING (startpos);
+ int len = 0;
+
+ /* Find the head of multibyte form. */
+ while (!CHAR_HEAD_P (*p))
+ p--, len++;
+
+ /* Adjust it. */
+#if 0 /* XXX */
+ if (MULTIBYTE_FORM_LENGTH (p, len + 1) != (len + 1))
+ ;
+ else
+#endif
+ {
+ range += len;
+ if (range > 0)
+ break;
+
+ startpos -= len;
+ }
+ }
+ }
}
return -1;
} /* re_search_2 */
@@ -3044,67 +3939,15 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
static int bcmp_translate ();
static boolean alt_match_null_string_p (),
- common_op_match_null_string_p (),
- group_match_null_string_p ();
-
-/* Structure for per-register (a.k.a. per-group) information.
- Other register information, such as the
- starting and ending positions (which are addresses), and the list of
- inner groups (which is a bits list) are maintained in separate
- variables.
-
- We are making a (strictly speaking) nonportable assumption here: that
- the compiler will pack our bit fields into something that fits into
- the type of `word', i.e., is something that fits into one item on the
- failure stack. */
-
-typedef union
-{
- fail_stack_elt_t word;
- struct
- {
- /* This field is one if this group can match the empty string,
- zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
-#define MATCH_NULL_UNSET_VALUE 3
- unsigned match_null_string_p : 2;
- unsigned is_active : 1;
- unsigned matched_something : 1;
- unsigned ever_matched_something : 1;
- } bits;
-} register_info_type;
-
-#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
-#define IS_ACTIVE(R) ((R).bits.is_active)
-#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
-#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
-
-
-/* Call this when have matched a real character; it sets `matched' flags
- for the subexpressions which we are currently inside. Also records
- that those subexprs have matched. */
-#define SET_REGS_MATCHED() \
- do \
- { \
- unsigned r; \
- for (r = lowest_active_reg; r <= highest_active_reg; r++) \
- { \
- MATCHED_SOMETHING (reg_info[r]) \
- = EVER_MATCHED_SOMETHING (reg_info[r]) \
- = 1; \
- } \
- } \
- while (0)
-
+ common_op_match_null_string_p (),
+ group_match_null_string_p ();
/* This converts PTR, a pointer into one of the search strings `string1'
and `string2' into an offset from the beginning of that string. */
-#define POINTER_TO_OFFSET(ptr) \
- (FIRST_STRING_P (ptr) ? (ptr) - string1 : (ptr) - string2 + size1)
-
-/* Registers are set to a sentinel when they haven't yet matched. */
-#define REG_UNSET_VALUE ((char *) -1)
-#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
-
+#define POINTER_TO_OFFSET(ptr) \
+ (FIRST_STRING_P (ptr) \
+ ? ((regoff_t) ((ptr) - string1)) \
+ : ((regoff_t) ((ptr) - string2 + size1)))
/* Macros for dealing with the split strings in re_match_2. */
@@ -3113,19 +3956,19 @@ typedef union
/* Call before fetching a character with *d. This switches over to
string2 if necessary. */
#define PREFETCH() \
- while (d == dend) \
+ while (d == dend) \
{ \
/* End of string2 => fail. */ \
- if (dend == end_match_2) \
- goto fail; \
- /* End of string1 => advance to string2. */ \
- d = string2; \
+ if (dend == end_match_2) \
+ goto fail; \
+ /* End of string1 => advance to string2. */ \
+ d = string2; \
dend = end_match_2; \
}
/* Test if at very beginning or at very end of the virtual concatenation
- of `string1' and `string2'. If only one string, it's `string2'. */
+ of `string1' and `string2'. If only one string, it's `string2'. */
#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
#define AT_STRINGS_END(d) ((d) == end2)
@@ -3136,22 +3979,33 @@ typedef union
string2, look at the last character in string1. */
#define WORDCHAR_P(d) \
(SYNTAX ((d) == end1 ? *string2 \
- : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
== Sword)
+/* Disabled due to a compiler bug -- see comment at case wordbound */
+
+/* The comment at case wordbound is following one, but we don't use
+ AT_WORD_BOUNDARY anymore to support multibyte form.
+
+ The DEC Alpha C compiler 3.x generates incorrect code for the
+ test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of
+ AT_WORD_BOUNDARY, so this code is disabled. Expanding the
+ macro and introducing temporary variables works around the bug. */
+
+#if 0
/* Test if the character before D and the one at D differ with respect
to being word-constituent. */
#define AT_WORD_BOUNDARY(d) \
(AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
|| WORDCHAR_P (d - 1) != WORDCHAR_P (d))
-
+#endif
/* Free everything we malloc. */
-#ifdef REGEX_MALLOC
-#define FREE_VAR(var) if (var) free (var); var = NULL
+#ifdef MATCH_MAY_ALLOCATE
+#define FREE_VAR(var) if (var) { REGEX_FREE (var); var = NULL; } else
#define FREE_VARIABLES() \
do { \
- FREE_VAR (fail_stack.stack); \
+ REGEX_FREE_STACK (fail_stack.stack); \
FREE_VAR (regstart); \
FREE_VAR (regend); \
FREE_VAR (old_regstart); \
@@ -3162,25 +4016,23 @@ typedef union
FREE_VAR (reg_dummy); \
FREE_VAR (reg_info_dummy); \
} while (0)
-#else /* not REGEX_MALLOC */
-/* Some MIPS systems (at least) want this to free alloca'd storage. */
-#define FREE_VARIABLES() alloca (0)
-#endif /* not REGEX_MALLOC */
-
+#else
+#define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */
+#endif /* not MATCH_MAY_ALLOCATE */
-/* These values must meet several constraints. They must not be valid
+/* These values must meet several constraints. They must not be valid
register values; since we have a limit of 255 registers (because
we use only one byte in the pattern for the register number), we can
- use numbers larger than 255. They must differ by 1, because of
+ use numbers larger than 255. They must differ by 1, because of
NUM_FAILURE_ITEMS above. And the value for the lowest register must
be larger than the value for the highest register, so we do not try
- to actually save any registers when none are active. */
+ to actually save any registers when none are active. */
#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
/* Matching routines. */
-#ifndef emacs /* Emacs never uses this. */
+#ifndef emacs /* Emacs never uses this. */
/* re_match is like re_match_2 except it takes only a single string. */
int
@@ -3189,11 +4041,23 @@ re_match (bufp, string, size, pos, regs)
const char *string;
int size, pos;
struct re_registers *regs;
- {
- return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size);
+{
+ int result = re_match_2_internal (bufp, NULL, 0, string, size,
+ pos, regs, size);
+#ifndef REGEX_MALLOC /* CVS */
+#ifdef C_ALLOCA /* CVS */
+ alloca (0);
+#endif /* CVS */
+#endif /* CVS */
+ return result;
}
#endif /* not emacs */
+#ifdef emacs
+/* In Emacs, this is the string or buffer in which we
+ are matching. It is used for looking up syntax properties. */
+Lisp_Object re_match_object;
+#endif
/* re_match_2 matches the compiled pattern in BUFP against the
the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
@@ -3201,11 +4065,11 @@ re_match (bufp, string, size, pos, regs)
matching at STOP.
If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
- store offsets for the substring each group matched in REGS. See the
+ store offsets for the substring each group matched in REGS. See the
documentation for exactly how many groups we fill.
We return -1 if no match, -2 if an internal error (such as the
- failure stack overflowing). Otherwise, we return the length of the
+ failure stack overflowing). Otherwise, we return the length of the
matched substring. */
int
@@ -3217,6 +4081,37 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
struct re_registers *regs;
int stop;
{
+ int result;
+
+#ifdef emacs
+ int charpos;
+ int adjpos = NILP (re_match_object) || BUFFERP (re_match_object);
+ gl_state.object = re_match_object;
+ charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos + adjpos);
+ SETUP_SYNTAX_TABLE_FOR_OBJECT (re_match_object, charpos, 1);
+#endif
+
+ result = re_match_2_internal (bufp, string1, size1, string2, size2,
+ pos, regs, stop);
+#ifndef REGEX_MALLOC /* CVS */
+#ifdef C_ALLOCA /* CVS */
+ alloca (0);
+#endif /* CVS */
+#endif /* CVS */
+ return result;
+}
+
+/* This is a separate function so that we can force an alloca cleanup
+ afterwards. */
+static int
+re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
/* General temporaries. */
int mcnt;
unsigned char *p1;
@@ -3225,7 +4120,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
const char *end1, *end2;
/* Pointers into string1 and string2, just past the last characters in
- each to consider matching. */
+ each to consider matching. */
const char *end_match_1, *end_match_2;
/* Where we are in the data, and the end of the current string. */
@@ -3235,8 +4130,15 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
unsigned char *p = bufp->buffer;
register unsigned char *pend = p + bufp->used;
- /* We use this to map every character in the string. */
- char *translate = bufp->translate;
+ /* Mark the opcode just after a start_memory, so we can test for an
+ empty subpattern when we get to the stop_memory. */
+ unsigned char *just_past_start_mem = 0;
+
+ /* We use this to map every character in the string. */
+ RE_TRANSLATE_TYPE translate = bufp->translate;
+
+ /* Nonzero if we have to concern multibyte character. */
+ int multibyte = bufp->multibyte;
/* Failure point stack. Each place that can handle a failure further
down the line pushes a failure point on this stack. It consists of
@@ -3246,15 +4148,21 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
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. */
+ it gets discarded and the next next one is tried. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
fail_stack_type fail_stack;
+#endif
#ifdef DEBUG
static unsigned failure_id = 0;
unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
#endif
+ /* This holds the pointer to the failure stack, when
+ it is allocated relocatably. */
+ fail_stack_elt_t *failure_stack_ptr;
+
/* We fill all the registers internally, independent of what we
- return, for use in backreferences. The number here includes
+ return, for use in backreferences. The number here includes
an element for register zero. */
unsigned num_regs = bufp->re_nsub + 1;
@@ -3269,33 +4177,41 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
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.) */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
const char **regstart, **regend;
+#endif
/* If a group that's operated upon by a repetition operator fails to
match anything, then the register for its start will need to be
restored because it will have been set to wherever in the string we
are when we last see its open-group operator. Similarly for a
register's end. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
const char **old_regstart, **old_regend;
+#endif
/* 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. */
+ loop their register is in. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
register_info_type *reg_info;
+#endif
/* 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 = false;
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
const char **best_regstart, **best_regend;
-
+#endif
+
/* Logically, this is `best_regend[0]'. But we don't want to have to
allocate space for that if we're not allocating space for anything
- else (see below). Also, we never need info about register 0 for
+ else (see below). Also, we never need info about register 0 for
any of the other register vectors, and it seems rather a kludge to
treat `best_regend' differently than the rest. So we keep track of
the end of the best match so far in a separate variable. We
@@ -3303,9 +4219,14 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
and need to test it, it's not garbage. */
const char *match_end = NULL;
+ /* This helps SET_REGS_MATCHED avoid doing redundant work. */
+ int set_regs_matched_done = 0;
+
/* Used when we pop values we don't care about. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
const char **reg_dummy;
register_info_type *reg_info_dummy;
+#endif
#ifdef DEBUG
/* Counts the total number of registers pushed. */
@@ -3316,6 +4237,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
INIT_FAIL_STACK ();
+#ifdef MATCH_MAY_ALLOCATE
/* Do not bother to initialize all the register variables if there are
no groups in the pattern, as it takes a fair amount of time. If
there are groups, we include space for register 0 (the whole
@@ -3334,22 +4256,21 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
if (!(regstart && regend && old_regstart && old_regend && reg_info
- && best_regstart && best_regend && reg_dummy && reg_info_dummy))
- {
- FREE_VARIABLES ();
- return -2;
- }
+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
}
-#ifdef REGEX_MALLOC
else
{
/* We must initialize all our variables to NULL, so that
- `FREE_VARIABLES' doesn't try to free them. */
+ `FREE_VARIABLES' doesn't try to free them. */
regstart = regend = old_regstart = old_regend = best_regstart
- = best_regend = reg_dummy = NULL;
+ = best_regend = reg_dummy = NULL;
reg_info = reg_info_dummy = (register_info_type *) NULL;
}
-#endif /* REGEX_MALLOC */
+#endif /* MATCH_MAY_ALLOCATE */
/* The starting position is bogus. */
if (pos < 0 || pos > size1 + size2)
@@ -3364,7 +4285,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
for (mcnt = 1; mcnt < num_regs; mcnt++)
{
regstart[mcnt] = regend[mcnt]
- = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
IS_ACTIVE (reg_info[mcnt]) = 0;
@@ -3373,7 +4294,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
}
/* We move `string1' into `string2' if the latter's empty -- but not if
- `string1' is null. */
+ `string1' is null. */
if (size2 == 0 && string1 != NULL)
{
string2 = string1;
@@ -3419,7 +4340,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
DEBUG_PRINT1 ("'\n");
- /* This loops over pattern commands. It exits by returning from the
+ /* This loops over pattern commands. It exits by returning from the
function if the match is complete, or it drops through if the match
fails at this starting point in the input data. */
for (;;)
@@ -3428,177 +4349,222 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
if (p == pend)
{ /* End of pattern means we might have succeeded. */
- DEBUG_PRINT1 ("end of pattern ... ");
+ DEBUG_PRINT1 ("end of pattern ... ");
/* If we haven't matched the entire string, and we want the
- longest match, try backtracking. */
- if (d != end_match_2)
+ longest match, try backtracking. */
+ if (d != end_match_2)
{
- DEBUG_PRINT1 ("backtracking.\n");
+ /* 1 if this match ends in the same string (string1 or string2)
+ as the best previous match. */
+ boolean same_str_p = (FIRST_STRING_P (match_end)
+ == MATCHING_IN_FIRST_STRING);
+ /* 1 if this match is the best seen so far. */
+ boolean best_match_p;
+
+ /* AIX compiler got confused when this was combined
+ with the previous declaration. */
+ if (same_str_p)
+ best_match_p = d > match_end;
+ else
+ best_match_p = !MATCHING_IN_FIRST_STRING;
- if (!FAIL_STACK_EMPTY ())
- { /* More failure points to try. */
- boolean same_str_p = (FIRST_STRING_P (match_end)
- == MATCHING_IN_FIRST_STRING);
+ DEBUG_PRINT1 ("backtracking.\n");
- /* If exceeds best match so far, save it. */
- if (!best_regs_set
- || (same_str_p && d > match_end)
- || (!same_str_p && !MATCHING_IN_FIRST_STRING))
- {
- best_regs_set = true;
- match_end = d;
+ if (!FAIL_STACK_EMPTY ())
+ { /* More failure points to try. */
- DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
+ /* If exceeds best match so far, save it. */
+ if (!best_regs_set || best_match_p)
+ {
+ best_regs_set = true;
+ match_end = d;
- for (mcnt = 1; mcnt < num_regs; mcnt++)
- {
- best_regstart[mcnt] = regstart[mcnt];
- best_regend[mcnt] = regend[mcnt];
- }
- }
- goto fail;
- }
+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
- /* If no failure points, don't restore garbage. */
- else if (best_regs_set)
- {
- restore_best_regs:
- /* Restore best match. It may happen that `dend ==
- end_match_1' while the restored d is in string2.
- For example, the pattern `x.*y.*z' against the
- strings `x-' and `y-z-', if the two strings are
- not consecutive in memory. */
- DEBUG_PRINT1 ("Restoring best registers.\n");
-
- d = match_end;
- dend = ((d >= string1 && d <= end1)
- ? end_match_1 : end_match_2);
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
+ }
+ }
+ goto fail;
+ }
+
+ /* If no failure points, don't restore garbage. And if
+ last match is real best match, don't restore second
+ best one. */
+ else if (best_regs_set && !best_match_p)
+ {
+ restore_best_regs:
+ /* Restore best match. It may happen that `dend ==
+ end_match_1' while the restored d is in string2.
+ For example, the pattern `x.*y.*z' against the
+ strings `x-' and `y-z-', if the two strings are
+ not consecutive in memory. */
+ DEBUG_PRINT1 ("Restoring best registers.\n");
+
+ d = match_end;
+ dend = ((d >= string1 && d <= end1)
+ ? end_match_1 : end_match_2);
for (mcnt = 1; mcnt < num_regs; mcnt++)
{
regstart[mcnt] = best_regstart[mcnt];
regend[mcnt] = best_regend[mcnt];
}
- }
- } /* d != end_match_2 */
+ }
+ } /* d != end_match_2 */
- DEBUG_PRINT1 ("Accepting match.\n");
+ succeed_label:
+ DEBUG_PRINT1 ("Accepting match.\n");
- /* If caller wants register contents data back, do it. */
- if (regs && !bufp->no_sub)
+ /* If caller wants register contents data back, do it. */
+ if (regs && !bufp->no_sub)
{
- /* Have the register data arrays been allocated? */
- if (bufp->regs_allocated == REGS_UNALLOCATED)
- { /* No. So allocate them with malloc. We need one
- extra element beyond `num_regs' for the `-1' marker
- GNU code uses. */
- regs->num_regs = MAX (RE_NREGS, num_regs + 1);
- regs->start = TALLOC (regs->num_regs, regoff_t);
- regs->end = TALLOC (regs->num_regs, regoff_t);
- if (regs->start == NULL || regs->end == NULL)
- return -2;
- bufp->regs_allocated = REGS_REALLOCATE;
- }
- else if (bufp->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 < num_regs + 1)
- {
- regs->num_regs = num_regs + 1;
- RETALLOC (regs->start, regs->num_regs, regoff_t);
- RETALLOC (regs->end, regs->num_regs, regoff_t);
- if (regs->start == NULL || regs->end == NULL)
- return -2;
- }
- }
- else
+ /* Have the register data arrays been allocated? */
+ if (bufp->regs_allocated == REGS_UNALLOCATED)
+ { /* No. So allocate them with malloc. We need one
+ extra element beyond `num_regs' for the `-1' marker
+ GNU code uses. */
+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
+ regs->start = TALLOC (regs->num_regs, regoff_t);
+ regs->end = TALLOC (regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ bufp->regs_allocated = REGS_REALLOCATE;
+ }
+ else if (bufp->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 < num_regs + 1)
+ {
+ regs->num_regs = num_regs + 1;
+ RETALLOC (regs->start, regs->num_regs, regoff_t);
+ RETALLOC (regs->end, regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ }
+ }
+ else
{
/* These braces fend off a "empty body in an else-statement"
- warning under GCC when assert expands to nothing. */
+ warning under GCC when assert expands to nothing. */
assert (bufp->regs_allocated == REGS_FIXED);
}
- /* Convert the pointer data in `regstart' and `regend' to
- indices. Register zero has to be set differently,
- since we haven't kept track of any info for it. */
- if (regs->num_regs > 0)
- {
- regs->start[0] = pos;
- regs->end[0] = (MATCHING_IN_FIRST_STRING ? d - string1
- : d - string2 + size1);
- }
+ /* Convert the pointer data in `regstart' and `regend' to
+ indices. Register zero has to be set differently,
+ since we haven't kept track of any info for it. */
+ if (regs->num_regs > 0)
+ {
+ regs->start[0] = pos;
+ regs->end[0] = (MATCHING_IN_FIRST_STRING
+ ? ((regoff_t) (d - string1))
+ : ((regoff_t) (d - string2 + size1)));
+ }
- /* Go through the first `min (num_regs, regs->num_regs)'
- registers, since that is all we initialized. */
+ /* Go through the first `min (num_regs, regs->num_regs)'
+ registers, since that is all we initialized. */
for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++)
{
- if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
- regs->start[mcnt] = regs->end[mcnt] = -1;
- else
- {
- regs->start[mcnt] = POINTER_TO_OFFSET (regstart[mcnt]);
- regs->end[mcnt] = POINTER_TO_OFFSET (regend[mcnt]);
- }
+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ else
+ {
+ regs->start[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
+ regs->end[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
+ }
}
- /* If the regs structure we return has more elements than
- were in the pattern, set the extra elements to -1. If
- we (re)allocated the registers, this is the case,
- because we always allocate enough to have at least one
- -1 at the end. */
- for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++)
- regs->start[mcnt] = regs->end[mcnt] = -1;
+ /* If the regs structure we return has more elements than
+ were in the pattern, set the extra elements to -1. If
+ we (re)allocated the registers, this is the case,
+ because we always allocate enough to have at least one
+ -1 at the end. */
+ for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++)
+ regs->start[mcnt] = regs->end[mcnt] = -1;
} /* regs && !bufp->no_sub */
- FREE_VARIABLES ();
- DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
- nfailure_points_pushed, nfailure_points_popped,
- nfailure_points_pushed - nfailure_points_popped);
- DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
+ nfailure_points_pushed, nfailure_points_popped,
+ nfailure_points_pushed - nfailure_points_popped);
+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
- mcnt = d - pos - (MATCHING_IN_FIRST_STRING
+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
? string1
: string2 - size1);
- DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
- return mcnt;
- }
+ FREE_VARIABLES ();
+ return mcnt;
+ }
- /* Otherwise match next pattern command. */
-#ifdef SWITCH_ENUM_BUG
- switch ((int) ((re_opcode_t) *p++))
-#else
- switch ((re_opcode_t) *p++)
-#endif
+ /* Otherwise match next pattern command. */
+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
{
- /* Ignore these. Used to ignore the n of succeed_n's which
- currently have n == 0. */
- case no_op:
- DEBUG_PRINT1 ("EXECUTING no_op.\n");
- break;
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case no_op:
+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
+ break;
+ case succeed:
+ DEBUG_PRINT1 ("EXECUTING succeed.\n");
+ goto succeed_label;
- /* Match the next n pattern characters exactly. The following
- byte in the pattern defines n, and the n bytes after that
- are the characters to match. */
+ /* Match the next n pattern characters exactly. The following
+ byte in the pattern defines n, and the n bytes after that
+ are the characters to match. */
case exactn:
mcnt = *p++;
- DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
- /* This is written out as an if-else so we don't waste time
- testing `translate' inside the loop. */
- if (translate)
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (RE_TRANSLATE_P (translate))
{
- do
- {
- PREFETCH ();
- if (translate[(unsigned char) *d++] != (char) *p++)
- goto fail;
- }
- while (--mcnt);
+#ifdef emacs
+ if (multibyte)
+ do
+ {
+ int pat_charlen, buf_charlen;
+ unsigned int pat_ch, buf_ch;
+
+ PREFETCH ();
+ pat_ch = STRING_CHAR_AND_LENGTH (p, pend - p, pat_charlen);
+ buf_ch = STRING_CHAR_AND_LENGTH (d, dend - d, buf_charlen);
+
+ if (RE_TRANSLATE (translate, buf_ch)
+ != pat_ch)
+ goto fail;
+
+ p += pat_charlen;
+ d += buf_charlen;
+ mcnt -= pat_charlen;
+ }
+ while (mcnt > 0);
+ else
+#endif /* not emacs */
+ do
+ {
+ PREFETCH ();
+ if ((unsigned char) RE_TRANSLATE (translate, (unsigned char) *d)
+ != (unsigned char) *p++)
+ goto fail;
+ d++;
+ }
+ while (--mcnt);
}
else
{
@@ -3610,206 +4576,262 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
while (--mcnt);
}
SET_REGS_MATCHED ();
- break;
+ break;
- /* Match any character except possibly a newline or a null. */
+ /* Match any character except possibly a newline or a null. */
case anychar:
- DEBUG_PRINT1 ("EXECUTING anychar.\n");
+ {
+ int buf_charlen;
+ unsigned int buf_ch;
- PREFETCH ();
+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
- if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
- || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
- goto fail;
+ PREFETCH ();
- SET_REGS_MATCHED ();
- DEBUG_PRINT2 (" Matched `%d'.\n", *d);
- d++;
+#ifdef emacs
+ if (multibyte)
+ buf_ch = STRING_CHAR_AND_LENGTH (d, dend - d, buf_charlen);
+ else
+#endif /* not emacs */
+ {
+ buf_ch = (unsigned char) *d;
+ buf_charlen = 1;
+ }
+
+ buf_ch = TRANSLATE (buf_ch);
+
+ if ((!(bufp->syntax & RE_DOT_NEWLINE)
+ && buf_ch == '\n')
+ || ((bufp->syntax & RE_DOT_NOT_NULL)
+ && buf_ch == '\000'))
+ goto fail;
+
+ SET_REGS_MATCHED ();
+ DEBUG_PRINT2 (" Matched `%d'.\n", *d);
+ d += buf_charlen;
+ }
break;
case charset:
case charset_not:
{
- register unsigned char c;
+ register unsigned int c;
boolean not = (re_opcode_t) *(p - 1) == charset_not;
+ int len;
- DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+ /* Start of actual range_table, or end of bitmap if there is no
+ range table. */
+ unsigned char *range_table;
- PREFETCH ();
- c = TRANSLATE (*d); /* The character to match. */
+ /* Nonzero if there is range table. */
+ int range_table_exists;
- /* Cast to `unsigned' instead of `unsigned char' in case the
- bit list is a full 32 bytes long. */
- if (c < (unsigned) (*p * BYTEWIDTH)
+ /* Number of ranges of range table. Not in bytes. */
+ int count;
+
+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+
+ PREFETCH ();
+ c = (unsigned char) *d;
+
+ range_table = CHARSET_RANGE_TABLE (&p[-1]); /* Past the bitmap. */
+ range_table_exists = CHARSET_RANGE_TABLE_EXISTS_P (&p[-1]);
+ if (range_table_exists)
+ EXTRACT_NUMBER_AND_INCR (count, range_table);
+ else
+ count = 0;
+
+ if (multibyte && BASE_LEADING_CODE_P (c))
+ c = STRING_CHAR_AND_LENGTH (d, dend - d, len);
+
+ if (SINGLE_BYTE_CHAR_P (c))
+ { /* Lookup bitmap. */
+ c = TRANSLATE (c); /* The character to match. */
+ len = 1;
+
+ /* Cast to `unsigned' instead of `unsigned char' in
+ case the bit list is a full 32 bytes long. */
+ if (c < (unsigned) (CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH)
&& p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
not = !not;
+ }
+ else if (range_table_exists)
+ CHARSET_LOOKUP_RANGE_TABLE_RAW (not, c, range_table, count);
- p += 1 + *p;
+ p = CHARSET_RANGE_TABLE_END (range_table, count);
if (!not) goto fail;
SET_REGS_MATCHED ();
- d++;
+ d += len;
break;
}
- /* The beginning of a group is represented by start_memory.
- The arguments are the register number in the next byte, and the
- number of groups inner to this one in the next. The text
- matched within the group is recorded (in the internal
- registers data structure) under the register number. */
- case start_memory:
+ /* The beginning of a group is represented by start_memory.
+ The arguments are the register number in the next byte, and the
+ number of groups inner to this one in the next. The text
+ matched within the group is recorded (in the internal
+ registers data structure) under the register number. */
+ case start_memory:
DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
- /* Find out if this group can match the empty string. */
+ /* Find out if this group can match the empty string. */
p1 = p; /* To send to group_match_null_string_p. */
- if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
- REG_MATCH_NULL_STRING_P (reg_info[*p])
- = group_match_null_string_p (&p1, pend, reg_info);
-
- /* Save the position in the string where we were the last time
- we were at this open-group operator in case the group is
- operated upon by a repetition operator, e.g., with `(a*)*b'
- against `ab'; then we want to ignore where we are now in
- the string in case this attempt to match fails. */
- old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
- ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
- : regstart[*p];
+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[*p])
+ = group_match_null_string_p (&p1, pend, reg_info);
+
+ /* Save the position in the string where we were the last time
+ we were at this open-group operator in case the group is
+ operated upon by a repetition operator, e.g., with `(a*)*b'
+ against `ab'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
+ : regstart[*p];
DEBUG_PRINT2 (" old_regstart: %d\n",
POINTER_TO_OFFSET (old_regstart[*p]));
- regstart[*p] = d;
+ regstart[*p] = d;
DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
- IS_ACTIVE (reg_info[*p]) = 1;
- MATCHED_SOMETHING (reg_info[*p]) = 0;
+ IS_ACTIVE (reg_info[*p]) = 1;
+ MATCHED_SOMETHING (reg_info[*p]) = 0;
- /* This is the new highest active register. */
- highest_active_reg = *p;
+ /* Clear this whenever we change the register activity status. */
+ set_regs_matched_done = 0;
- /* If nothing was active before, this is the new lowest active
- register. */
- if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
- lowest_active_reg = *p;
+ /* This is the new highest active register. */
+ highest_active_reg = *p;
- /* Move past the register number and inner group count. */
- p += 2;
- break;
+ /* If nothing was active before, this is the new lowest active
+ register. */
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *p;
+
+ /* Move past the register number and inner group count. */
+ p += 2;
+ just_past_start_mem = p;
+
+ break;
- /* The stop_memory opcode represents the end of a group. Its
- arguments are the same as start_memory's: the register
- number, and the number of inner groups. */
+ /* The stop_memory opcode represents the end of a group. Its
+ arguments are the same as start_memory's: the register
+ number, and the number of inner groups. */
case stop_memory:
DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
- /* We need to save the string position the last time we were at
- this close-group operator in case the group is operated
- upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
- against `aba'; then we want to ignore where we are now in
- the string in case this attempt to match fails. */
- old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
- ? REG_UNSET (regend[*p]) ? d : regend[*p]
+ /* We need to save the string position the last time we were at
+ this close-group operator in case the group is operated
+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
+ against `aba'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
: regend[*p];
DEBUG_PRINT2 (" old_regend: %d\n",
POINTER_TO_OFFSET (old_regend[*p]));
- regend[*p] = d;
+ regend[*p] = d;
DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
- /* This register isn't active anymore. */
- IS_ACTIVE (reg_info[*p]) = 0;
+ /* This register isn't active anymore. */
+ IS_ACTIVE (reg_info[*p]) = 0;
- /* If this was the only register active, nothing is active
- anymore. */
- if (lowest_active_reg == highest_active_reg)
- {
- lowest_active_reg = NO_LOWEST_ACTIVE_REG;
- highest_active_reg = NO_HIGHEST_ACTIVE_REG;
- }
- else
- { /* We must scan for the new highest active register, since
- it isn't necessarily one less than now: consider
- (a(b)c(d(e)f)g). When group 3 ends, after the f), the
- new highest active register is 1. */
- unsigned char r = *p - 1;
- while (r > 0 && !IS_ACTIVE (reg_info[r]))
- r--;
-
- /* If we end up at register zero, that means that we saved
- the registers as the result of an `on_failure_jump', not
- a `start_memory', and we jumped to past the innermost
- `stop_memory'. For example, in ((.)*) we save
- registers 1 and 2 as a result of the *, but when we pop
- back to the second ), we are at the stop_memory 1.
- Thus, nothing is active. */
+ /* Clear this whenever we change the register activity status. */
+ set_regs_matched_done = 0;
+
+ /* If this was the only register active, nothing is active
+ anymore. */
+ if (lowest_active_reg == highest_active_reg)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ { /* We must scan for the new highest active register, since
+ it isn't necessarily one less than now: consider
+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
+ new highest active register is 1. */
+ unsigned char r = *p - 1;
+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
+ r--;
+
+ /* If we end up at register zero, that means that we saved
+ the registers as the result of an `on_failure_jump', not
+ a `start_memory', and we jumped to past the innermost
+ `stop_memory'. For example, in ((.)*) we save
+ registers 1 and 2 as a result of the *, but when we pop
+ back to the second ), we are at the stop_memory 1.
+ Thus, nothing is active. */
if (r == 0)
- {
- lowest_active_reg = NO_LOWEST_ACTIVE_REG;
- highest_active_reg = NO_HIGHEST_ACTIVE_REG;
- }
- else
- highest_active_reg = r;
- }
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ highest_active_reg = r;
+ }
- /* If just failed to match something this time around with a
- group that's operated on by a repetition operator, try to
- force exit from the ``loop'', and restore the register
- information for this group that we had before trying this
- last match. */
- if ((!MATCHED_SOMETHING (reg_info[*p])
- || (re_opcode_t) p[-3] == start_memory)
- && (p + 2) < pend)
- {
- boolean is_a_jump_n = false;
+ /* If just failed to match something this time around with a
+ group that's operated on by a repetition operator, try to
+ force exit from the ``loop'', and restore the register
+ information for this group that we had before trying this
+ last match. */
+ if ((!MATCHED_SOMETHING (reg_info[*p])
+ || just_past_start_mem == p - 1)
+ && (p + 2) < pend)
+ {
+ boolean is_a_jump_n = false;
- p1 = p + 2;
- mcnt = 0;
- switch ((re_opcode_t) *p1++)
- {
- case jump_n:
+ p1 = p + 2;
+ mcnt = 0;
+ switch ((re_opcode_t) *p1++)
+ {
+ case jump_n:
is_a_jump_n = true;
- case pop_failure_jump:
+ case pop_failure_jump:
case maybe_pop_jump:
case jump:
case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
if (is_a_jump_n)
p1 += 2;
- break;
+ break;
- default:
- /* do nothing */ ;
- }
+ default:
+ /* do nothing */ ;
+ }
p1 += mcnt;
- /* If the next operation is a jump backwards in the pattern
- to an on_failure_jump right before the start_memory
- corresponding to this stop_memory, 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 && (re_opcode_t) *p1 == on_failure_jump
- && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump right before the start_memory
+ corresponding to this stop_memory, 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 && (re_opcode_t) *p1 == on_failure_jump
+ && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
{
- /* If this group ever matched anything, then restore
- what its registers were before trying this last
- failed match, e.g., with `(a*)*b' against `ab' for
- regstart[1], and, e.g., with `((a*)*(b*)*)*'
- against `aba' for regend[3].
+ /* If this group ever matched anything, then restore
+ what its registers were before trying this last
+ failed match, e.g., with `(a*)*b' against `ab' for
+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
+ against `aba' for regend[3].
- Also restore the registers for inner groups for,
- e.g., `((a*)(b*))*' against `aba' (register 3 would
- otherwise get trashed). */
+ Also restore the registers for inner groups for,
+ e.g., `((a*)(b*))*' against `aba' (register 3 would
+ otherwise get trashed). */
- if (EVER_MATCHED_SOMETHING (reg_info[*p]))
+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
{
unsigned r;
- EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
/* Restore this and inner groups' (if any) registers. */
for (r = *p; r < *p + *(p + 1); r++)
@@ -3822,53 +4844,53 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
}
}
p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
- goto fail;
- }
- }
+ goto fail;
+ }
+ }
- /* Move past the register number and the inner group count. */
- p += 2;
- break;
+ /* Move past the register number and the inner group count. */
+ p += 2;
+ break;
/* \<digit> has been turned into a `duplicate' command which is
- followed by the numeric value of <digit> as the register number. */
- case duplicate:
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
{
register const char *d2, *dend2;
- int regno = *p++; /* Get which register to match against. */
+ int regno = *p++; /* Get which register to match against. */
DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
- /* Can't back reference a group which we've never matched. */
- if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
- goto fail;
+ /* Can't back reference a group which we've never matched. */
+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
+ goto fail;
- /* Where in input to try to start matching. */
- d2 = regstart[regno];
+ /* 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. */
+ /* 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 = ((FIRST_STRING_P (regstart[regno])
+ dend2 = ((FIRST_STRING_P (regstart[regno])
== FIRST_STRING_P (regend[regno]))
? regend[regno] : end_match_1);
for (;;)
{
/* If necessary, advance to next segment in register
- contents. */
+ contents. */
while (d2 == dend2)
{
if (dend2 == end_match_2) break;
if (dend2 == regend[regno]) break;
- /* End of string1 => advance to string2. */
- d2 = string2;
- dend2 = regend[regno];
+ /* End of string1 => advance to string2. */
+ d2 = string2;
+ dend2 = regend[regno];
}
/* At end of register contents => success */
if (d2 == dend2) break;
@@ -3880,433 +4902,761 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
mcnt = dend - d;
/* Want how many consecutive characters we can match in
- one shot, so, if necessary, adjust the count. */
- if (mcnt > dend2 - d2)
+ 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 (d, d2, mcnt, translate)
- : bcmp (d, d2, mcnt))
+ past them. */
+ if (RE_TRANSLATE_P (translate)
+ ? bcmp_translate (d, d2, mcnt, translate)
+ : bcmp (d, d2, mcnt))
goto fail;
d += mcnt, d2 += mcnt;
+
+ /* Do this because we've match some characters. */
+ SET_REGS_MATCHED ();
}
}
break;
- /* begline matches the empty string at the beginning of the string
- (unless `not_bol' is set in `bufp'), and, if
- `newline_anchor' is set, after newlines. */
+ /* begline matches the empty string at the beginning of the string
+ (unless `not_bol' is set in `bufp'), and, if
+ `newline_anchor' is set, after newlines. */
case begline:
- DEBUG_PRINT1 ("EXECUTING begline.\n");
+ DEBUG_PRINT1 ("EXECUTING begline.\n");
- if (AT_STRINGS_BEG (d))
- {
- if (!bufp->not_bol) break;
- }
- else if (d[-1] == '\n' && bufp->newline_anchor)
- {
- break;
- }
- /* In all other cases, we fail. */
- goto fail;
+ if (AT_STRINGS_BEG (d))
+ {
+ if (!bufp->not_bol) break;
+ }
+ else if (d[-1] == '\n' && bufp->newline_anchor)
+ {
+ break;
+ }
+ /* In all other cases, we fail. */
+ goto fail;
- /* endline is the dual of begline. */
+ /* endline is the dual of begline. */
case endline:
- DEBUG_PRINT1 ("EXECUTING endline.\n");
+ DEBUG_PRINT1 ("EXECUTING endline.\n");
- if (AT_STRINGS_END (d))
- {
- if (!bufp->not_eol) break;
- }
+ if (AT_STRINGS_END (d))
+ {
+ if (!bufp->not_eol) break;
+ }
- /* We have to ``prefetch'' the next character. */
- else if ((d == end1 ? *string2 : *d) == '\n'
- && bufp->newline_anchor)
- {
- break;
- }
- goto fail;
+ /* We have to ``prefetch'' the next character. */
+ else if ((d == end1 ? *string2 : *d) == '\n'
+ && bufp->newline_anchor)
+ {
+ break;
+ }
+ goto fail;
/* Match at the very beginning of the data. */
- case begbuf:
- DEBUG_PRINT1 ("EXECUTING begbuf.\n");
- if (AT_STRINGS_BEG (d))
- break;
- goto fail;
+ case begbuf:
+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
+ if (AT_STRINGS_BEG (d))
+ break;
+ goto fail;
/* Match at the very end of the data. */
- case endbuf:
- DEBUG_PRINT1 ("EXECUTING endbuf.\n");
+ case endbuf:
+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
if (AT_STRINGS_END (d))
break;
- goto fail;
-
-
- /* on_failure_keep_string_jump is used to optimize `.*\n'. It
- pushes NULL as the value for the string on the stack. Then
- `pop_failure_point' will keep the current value for the
- string, instead of restoring it. To see why, consider
- matching `foo\nbar' against `.*\n'. The .* matches the foo;
- then the . fails against the \n. But the next thing we want
- to do is match the \n against the \n; if we restored the
- string value, we would be back at the foo.
-
- Because this is used only in specific cases, we don't need to
- check all the things that `on_failure_jump' does, to make
- sure the right things get saved on the stack. Hence we don't
- share its code. The only reason to push anything on the
- stack at all is that otherwise we would have to change
- `anychar's code to do something besides goto fail in this
- case; that seems worse than this. */
- case on_failure_keep_string_jump:
- DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
-
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
-
- PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
- break;
+ goto fail;
+
+
+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
+ pushes NULL as the value for the string on the stack. Then
+ `pop_failure_point' will keep the current value for the
+ string, instead of restoring it. To see why, consider
+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
+ then the . fails against the \n. But the next thing we want
+ to do is match the \n against the \n; if we restored the
+ string value, we would be back at the foo.
+
+ Because this is used only in specific cases, we don't need to
+ check all the things that `on_failure_jump' does, to make
+ sure the right things get saved on the stack. Hence we don't
+ share its code. The only reason to push anything on the
+ stack at all is that otherwise we would have to change
+ `anychar's code to do something besides goto fail in this
+ case; that seems worse than this. */
+ case on_failure_keep_string_jump:
+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
+
+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
+ break;
/* Uses of on_failure_jump:
- Each alternative starts with an on_failure_jump that points
- to the beginning of the next alternative. Each alternative
- except the last ends with a jump that in effect jumps past
- the rest of the alternatives. (They really jump to the
- ending jump of the following alternative, because tensioning
- these jumps is a hassle.)
+ Each alternative starts with an on_failure_jump that points
+ to the beginning of the next alternative. Each alternative
+ except the last ends with a jump that in effect jumps past
+ the rest of the alternatives. (They really jump to the
+ ending jump of the following alternative, because tensioning
+ these jumps is a hassle.)
- Repeats start with an on_failure_jump that points past both
- the repetition text and either the following jump or
- pop_failure_jump back to this on_failure_jump. */
+ Repeats start with an on_failure_jump that points past both
+ the repetition text and either the following jump or
+ pop_failure_jump back to this on_failure_jump. */
case on_failure_jump:
- on_failure:
- DEBUG_PRINT1 ("EXECUTING on_failure_jump");
-
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
-
- /* If this on_failure_jump comes right before a group (i.e.,
- the original * applied to a group), save the information
- for that group and all inner ones, so that if we fail back
- to this point, the group's information will be correct.
- For example, in \(a*\)*\1, we need the preceding group,
- and in \(\(a*\)b*\)\2, we need the inner group. */
-
- /* We can't use `p' to check ahead because we push
- a failure point to `p + mcnt' after we do this. */
- p1 = p;
-
- /* We need to skip no_op's before we look for the
- start_memory in case this on_failure_jump is happening as
- the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
- against aba. */
- while (p1 < pend && (re_opcode_t) *p1 == no_op)
- p1++;
-
- if (p1 < pend && (re_opcode_t) *p1 == start_memory)
- {
- /* We have a new highest active register now. This will
- get reset at the start_memory we are about to get to,
- but we will have saved all the registers relevant to
- this repetition op, as described above. */
- highest_active_reg = *(p1 + 1) + *(p1 + 2);
- if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
- lowest_active_reg = *(p1 + 1);
- }
+ on_failure:
+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
- DEBUG_PRINT1 (":\n");
- PUSH_FAILURE_POINT (p + mcnt, d, -2);
- break;
+#if defined (WINDOWSNT) && defined (emacs)
+ QUIT;
+#endif
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
+
+ /* If this on_failure_jump comes right before a group (i.e.,
+ the original * applied to a group), save the information
+ for that group and all inner ones, so that if we fail back
+ to this point, the group's information will be correct.
+ For example, in \(a*\)*\1, we need the preceding group,
+ and in \(zz\(a*\)b*\)\2, we need the inner group. */
+ /* We can't use `p' to check ahead because we push
+ a failure point to `p + mcnt' after we do this. */
+ p1 = p;
- /* A smart repeat ends with `maybe_pop_jump'.
- We change it to either `pop_failure_jump' or `jump'. */
- case maybe_pop_jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
- {
+ /* We need to skip no_op's before we look for the
+ start_memory in case this on_failure_jump is happening as
+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
+ against aba. */
+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
+ p1++;
+
+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
+ {
+ /* We have a new highest active register now. This will
+ get reset at the start_memory we are about to get to,
+ but we will have saved all the registers relevant to
+ this repetition op, as described above. */
+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *(p1 + 1);
+ }
+
+ DEBUG_PRINT1 (":\n");
+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
+ break;
+
+
+ /* A smart repeat ends with `maybe_pop_jump'.
+ We change it to either `pop_failure_jump' or `jump'. */
+ case maybe_pop_jump:
+#if defined (WINDOWSNT) && defined (emacs)
+ QUIT;
+#endif
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
+ {
register unsigned char *p2 = p;
- /* Compare the beginning of the repeat with what in the
- pattern follows its end. If we can establish that there
- is nothing that they would both match, i.e., that we
- would have to backtrack because of (as in, e.g., `a*a')
- then we can change to pop_failure_jump, because we'll
- never have to backtrack.
-
- This is not true in the case of alternatives: in
- `(a|ab)*' we do need to backtrack to the `ab' alternative
- (e.g., if the string was `ab'). But instead of trying to
- detect that here, the alternative has put on a dummy
- failure point which is what we will end up popping. */
-
- /* Skip over open/close-group commands. */
- while (p2 + 2 < pend
- && ((re_opcode_t) *p2 == stop_memory
- || (re_opcode_t) *p2 == start_memory))
- p2 += 3; /* Skip over args, too. */
-
- /* If we're at the end of the pattern, we can change. */
- if (p2 == pend)
+ /* Compare the beginning of the repeat with what in the
+ pattern follows its end. If we can establish that there
+ is nothing that they would both match, i.e., that we
+ would have to backtrack because of (as in, e.g., `a*a')
+ then we can change to pop_failure_jump, because we'll
+ never have to backtrack.
+
+ This is not true in the case of alternatives: in
+ `(a|ab)*' we do need to backtrack to the `ab' alternative
+ (e.g., if the string was `ab'). But instead of trying to
+ detect that here, the alternative has put on a dummy
+ failure point which is what we will end up popping. */
+
+ /* Skip over open/close-group commands.
+ If what follows this loop is a ...+ construct,
+ look at what begins its body, since we will have to
+ match at least one of that. */
+ while (1)
+ {
+ if (p2 + 2 < pend
+ && ((re_opcode_t) *p2 == stop_memory
+ || (re_opcode_t) *p2 == start_memory))
+ p2 += 3;
+ else if (p2 + 6 < pend
+ && (re_opcode_t) *p2 == dummy_failure_jump)
+ p2 += 6;
+ else
+ break;
+ }
+
+ p1 = p + mcnt;
+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
+ to the `maybe_finalize_jump' of this case. Examine what
+ follows. */
+
+ /* If we're at the end of the pattern, we can change. */
+ if (p2 == pend)
{
/* Consider what happens when matching ":\(.*\)"
against ":/". I don't really understand this code
- yet. */
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT1
- (" End of pattern: change to `pop_failure_jump'.\n");
- }
+ yet. */
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1
+ (" End of pattern: change to `pop_failure_jump'.\n");
+ }
- else if ((re_opcode_t) *p2 == exactn
+ else if ((re_opcode_t) *p2 == exactn
|| (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
{
- register unsigned char c
- = *p2 == (unsigned char) endline ? '\n' : p2[2];
- p1 = p + mcnt;
-
- /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
- to the `maybe_finalize_jump' of this case. Examine what
- follows. */
- if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
- {
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
- c, p1[5]);
- }
+ register unsigned int c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+
+ if ((re_opcode_t) p1[3] == exactn)
+ {
+ if (!(multibyte /* && (c != '\n') */
+ && BASE_LEADING_CODE_P (c))
+ ? c != p1[5]
+ : (STRING_CHAR (&p2[2], pend - &p2[2])
+ != STRING_CHAR (&p1[5], pend - &p1[5])))
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+ }
else if ((re_opcode_t) p1[3] == charset
|| (re_opcode_t) p1[3] == charset_not)
{
int not = (re_opcode_t) p1[3] == charset_not;
- if (c < (unsigned char) (p1[4] * BYTEWIDTH)
+ if (multibyte /* && (c != '\n') */
+ && BASE_LEADING_CODE_P (c))
+ c = STRING_CHAR (&p2[2], pend - &p2[2]);
+
+ /* Test if C is listed in charset (or charset_not)
+ at `&p1[3]'. */
+ if (SINGLE_BYTE_CHAR_P (c))
+ {
+ if (c < CHARSET_BITMAP_SIZE (&p1[3]) * BYTEWIDTH
&& p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
not = !not;
+ }
+ else if (CHARSET_RANGE_TABLE_EXISTS_P (&p1[3]))
+ CHARSET_LOOKUP_RANGE_TABLE (not, c, &p1[3]);
- /* `not' is equal to 1 if c would match, which means
- that we can't change to pop_failure_jump. */
+ /* `not' is equal to 1 if c would match, which means
+ that we can't change to pop_failure_jump. */
if (!not)
- {
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
- }
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
}
}
+ else if ((re_opcode_t) *p2 == charset)
+ {
+ if ((re_opcode_t) p1[3] == exactn)
+ {
+ register unsigned int c = p1[5];
+ int not = 0;
+
+ if (multibyte && BASE_LEADING_CODE_P (c))
+ c = STRING_CHAR (&p1[5], pend - &p1[5]);
+
+ /* Test if C is listed in charset at `p2'. */
+ if (SINGLE_BYTE_CHAR_P (c))
+ {
+ if (c < CHARSET_BITMAP_SIZE (p2) * BYTEWIDTH
+ && (p2[2 + c / BYTEWIDTH]
+ & (1 << (c % BYTEWIDTH))))
+ not = !not;
+ }
+ else if (CHARSET_RANGE_TABLE_EXISTS_P (p2))
+ CHARSET_LOOKUP_RANGE_TABLE (not, c, p2);
+
+ if (!not)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+
+ /* It is hard to list up all the character in charset
+ P2 if it includes multibyte character. Give up in
+ such case. */
+ else if (!multibyte || !CHARSET_RANGE_TABLE_EXISTS_P (p2))
+ {
+ /* Now, we are sure that P2 has no range table.
+ So, for the size of bitmap in P2, `p2[1]' is
+ enough. But P1 may have range table, so the
+ size of bitmap table of P1 is extracted by
+ using macro `CHARSET_BITMAP_SIZE'.
+
+ Since we know that all the character listed in
+ P2 is ASCII, it is enough to test only bitmap
+ table of P1. */
+
+ if ((re_opcode_t) p1[3] == charset_not)
+ {
+ int idx;
+ /* We win if the charset_not inside the loop lists
+ every character listed in the charset after. */
+ for (idx = 0; idx < (int) p2[1]; idx++)
+ if (! (p2[2 + idx] == 0
+ || (idx < CHARSET_BITMAP_SIZE (&p1[3])
+ && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
+ break;
+
+ if (idx == p2[1])
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ else if ((re_opcode_t) p1[3] == charset)
+ {
+ int idx;
+ /* We win if the charset inside the loop
+ has no overlap with the one after the loop. */
+ for (idx = 0;
+ (idx < (int) p2[1]
+ && idx < CHARSET_BITMAP_SIZE (&p1[3]));
+ idx++)
+ if ((p2[2 + idx] & p1[5 + idx]) != 0)
+ break;
+
+ if (idx == p2[1]
+ || idx == CHARSET_BITMAP_SIZE (&p1[3]))
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ }
}
p -= 2; /* Point at relative address again. */
if ((re_opcode_t) p[-1] != pop_failure_jump)
{
p[-1] = (unsigned char) jump;
- DEBUG_PRINT1 (" Match => jump.\n");
+ DEBUG_PRINT1 (" Match => jump.\n");
goto unconditional_jump;
}
- /* Note fall through. */
+ /* Note fall through. */
/* The end of a simple repeat has a pop_failure_jump back to
- its matching on_failure_jump, where the latter will push a
- failure point. The pop_failure_jump takes off failure
- points put on by this pop_failure_jump's matching
- on_failure_jump; we got through the pattern to here from the
- matching on_failure_jump, so didn't fail. */
- case pop_failure_jump:
- {
- /* We need to pass separate storage for the lowest and
- highest registers, even though we don't care about the
- actual values. Otherwise, we will restore only one
- register from the stack, since lowest will == highest in
- `pop_failure_point'. */
- unsigned dummy_low_reg, dummy_high_reg;
- unsigned char *pdummy;
- const char *sdummy;
-
- DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
- POP_FAILURE_POINT (sdummy, pdummy,
- dummy_low_reg, dummy_high_reg,
- reg_dummy, reg_dummy, reg_info_dummy);
- }
- /* Note fall through. */
-
-
- /* Unconditionally jump (without popping any failure points). */
- case jump:
+ its matching on_failure_jump, where the latter will push a
+ failure point. The pop_failure_jump takes off failure
+ points put on by this pop_failure_jump's matching
+ on_failure_jump; we got through the pattern to here from the
+ matching on_failure_jump, so didn't fail. */
+ case pop_failure_jump:
+ {
+ /* We need to pass separate storage for the lowest and
+ highest registers, even though we don't care about the
+ actual values. Otherwise, we will restore only one
+ register from the stack, since lowest will == highest in
+ `pop_failure_point'. */
+ unsigned dummy_low_reg, dummy_high_reg;
+ unsigned char *pdummy;
+ const char *sdummy;
+
+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
+ POP_FAILURE_POINT (sdummy, pdummy,
+ dummy_low_reg, dummy_high_reg,
+ reg_dummy, reg_dummy, reg_info_dummy);
+ }
+ /* Note fall through. */
+
+
+ /* Unconditionally jump (without popping any failure points). */
+ case jump:
unconditional_jump:
+#if defined (WINDOWSNT) && defined (emacs)
+ QUIT;
+#endif
EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
- DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
- p += mcnt; /* Do the jump. */
- DEBUG_PRINT2 ("(to 0x%x).\n", p);
+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
+ p += mcnt; /* Do the jump. */
+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
break;
- /* We need this opcode so we can detect where alternatives end
- in `group_match_null_string_p' et al. */
- case jump_past_alt:
- DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
- goto unconditional_jump;
-
-
- /* Normally, the on_failure_jump pushes a failure point, which
- then gets popped at pop_failure_jump. We will end up at
- pop_failure_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 pop_failure_jump to pop. */
- case dummy_failure_jump:
- DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
- /* It doesn't matter what we push for the string here. What
- the code at `fail' tests is the value for the pattern. */
- PUSH_FAILURE_POINT (0, 0, -2);
- goto unconditional_jump;
-
-
- /* At the end of an alternative, we need to push a dummy failure
- point in case we are followed by a `pop_failure_jump', because
- we don't want the failure point for the alternative to be
- popped. For example, matching `(a|ab)*' against `aab'
- requires that we match the `ab' alternative. */
- case push_dummy_failure:
- DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
- /* See comments just above at `dummy_failure_jump' about the
- two zeroes. */
- PUSH_FAILURE_POINT (0, 0, -2);
- break;
+ /* We need this opcode so we can detect where alternatives end
+ in `group_match_null_string_p' et al. */
+ case jump_past_alt:
+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
+ goto unconditional_jump;
- /* Have to succeed matching what follows at least n times.
- After that, handle like `on_failure_jump'. */
- case succeed_n:
- EXTRACT_NUMBER (mcnt, p + 2);
- DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
- assert (mcnt >= 0);
- /* Originally, this is how many times we HAVE to succeed. */
- if (mcnt > 0)
- {
- mcnt--;
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at pop_failure_jump. We will end up at
+ pop_failure_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 pop_failure_jump to pop. */
+ case dummy_failure_jump:
+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
+ /* It doesn't matter what we push for the string here. What
+ the code at `fail' tests is the value for the pattern. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ goto unconditional_jump;
+
+
+ /* At the end of an alternative, we need to push a dummy failure
+ point in case we are followed by a `pop_failure_jump', because
+ we don't want the failure point for the alternative to be
+ popped. For example, matching `(a|ab)*' against `aab'
+ requires that we match the `ab' alternative. */
+ case push_dummy_failure:
+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
+ /* See comments just above at `dummy_failure_jump' about the
+ two zeroes. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ break;
+
+ /* Have to succeed matching what follows at least n times.
+ After that, handle like `on_failure_jump'. */
+ case succeed_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
+
+ assert (mcnt >= 0);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt > 0)
+ {
+ mcnt--;
p += 2;
- STORE_NUMBER_AND_INCR (p, mcnt);
- DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt);
- }
+ STORE_NUMBER_AND_INCR (p, mcnt);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt);
+ }
else if (mcnt == 0)
- {
- DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
+ {
+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
p[2] = (unsigned char) no_op;
- p[3] = (unsigned char) no_op;
- goto on_failure;
- }
- break;
+ p[3] = (unsigned char) no_op;
+ goto on_failure;
+ }
+ break;
- case jump_n:
- EXTRACT_NUMBER (mcnt, p + 2);
- DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
+ case jump_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
- /* Originally, this is how many times we CAN jump. */
- if (mcnt)
- {
- mcnt--;
- STORE_NUMBER (p + 2, mcnt);
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt)
+ {
+ mcnt--;
+ STORE_NUMBER (p + 2, mcnt);
goto unconditional_jump;
- }
- /* If don't have to jump any more, skip over the rest of command. */
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
else
p += 4;
- break;
+ break;
case set_number_at:
{
- DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- p1 = p + mcnt;
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
STORE_NUMBER (p1, mcnt);
- break;
- }
+ break;
+ }
+
+ case wordbound:
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
- case wordbound:
- DEBUG_PRINT1 ("EXECUTING wordbound.\n");
- if (AT_WORD_BOUNDARY (d))
+ /* We SUCCEED in one of the following cases: */
+
+ /* Case 1: D is at the beginning or the end of string. */
+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
+ break;
+ else
+ {
+ /* C1 is the character before D, S1 is the syntax of C1, C2
+ is the character at D, and S2 is the syntax of C2. */
+ int c1, c2, s1, s2;
+ int pos1 = PTR_TO_OFFSET (d - 1);
+ int charpos;
+
+ GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
+ GET_CHAR_AFTER_2 (c2, d, string1, end1, string2, end2);
+#ifdef emacs
+ charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1);
+ UPDATE_SYNTAX_TABLE (charpos);
+#endif
+ s1 = SYNTAX (c1);
+#ifdef emacs
+ UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
+#endif
+ s2 = SYNTAX (c2);
+
+ if (/* Case 2: Only one of S1 and S2 is Sword. */
+ ((s1 == Sword) != (s2 == Sword))
+ /* Case 3: Both of S1 and S2 are Sword, and macro
+ WORD_BOUNDARY_P (C1, C2) returns nonzero. */
+ || ((s1 == Sword) && WORD_BOUNDARY_P (c1, c2)))
break;
- goto fail;
+ }
+ goto fail;
- case notwordbound:
- DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
- if (AT_WORD_BOUNDARY (d))
+ case notwordbound:
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+
+ /* We FAIL in one of the following cases: */
+
+ /* Case 1: D is at the beginning or the end of string. */
+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
goto fail;
- break;
+ else
+ {
+ /* C1 is the character before D, S1 is the syntax of C1, C2
+ is the character at D, and S2 is the syntax of C2. */
+ int c1, c2, s1, s2;
+ int pos1 = PTR_TO_OFFSET (d - 1);
+ int charpos;
+
+ GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
+ GET_CHAR_AFTER_2 (c2, d, string1, end1, string2, end2);
+#ifdef emacs
+ charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1);
+ UPDATE_SYNTAX_TABLE (charpos);
+#endif
+ s1 = SYNTAX (c1);
+#ifdef emacs
+ UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
+#endif
+ s2 = SYNTAX (c2);
+
+ if (/* Case 2: Only one of S1 and S2 is Sword. */
+ ((s1 == Sword) != (s2 == Sword))
+ /* Case 3: Both of S1 and S2 are Sword, and macro
+ WORD_BOUNDARY_P (C1, C2) returns nonzero. */
+ || ((s1 == Sword) && WORD_BOUNDARY_P (c1, c2)))
+ goto fail;
+ }
+ break;
case wordbeg:
- DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
- if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
- break;
- goto fail;
+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
+
+ /* We FAIL in one of the following cases: */
+
+ /* Case 1: D is at the end of string. */
+ if (AT_STRINGS_END (d))
+ goto fail;
+ else
+ {
+ /* C1 is the character before D, S1 is the syntax of C1, C2
+ is the character at D, and S2 is the syntax of C2. */
+ int c1, c2, s1, s2;
+ int pos1 = PTR_TO_OFFSET (d);
+ int charpos;
+
+ GET_CHAR_AFTER_2 (c2, d, string1, end1, string2, end2);
+#ifdef emacs
+ charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1);
+ UPDATE_SYNTAX_TABLE (charpos);
+#endif
+ s2 = SYNTAX (c2);
+
+ /* Case 2: S2 is not Sword. */
+ if (s2 != Sword)
+ goto fail;
+
+ /* Case 3: D is not at the beginning of string ... */
+ if (!AT_STRINGS_BEG (d))
+ {
+ GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
+#ifdef emacs
+ UPDATE_SYNTAX_TABLE_BACKWARD (charpos - 1);
+#endif
+ s1 = SYNTAX (c1);
+
+ /* ... and S1 is Sword, and WORD_BOUNDARY_P (C1, C2)
+ returns 0. */
+ if ((s1 == Sword) && !WORD_BOUNDARY_P (c1, c2))
+ goto fail;
+ }
+ }
+ break;
case wordend:
- DEBUG_PRINT1 ("EXECUTING wordend.\n");
- if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
- && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
- break;
- goto fail;
+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
+
+ /* We FAIL in one of the following cases: */
+
+ /* Case 1: D is at the beginning of string. */
+ if (AT_STRINGS_BEG (d))
+ goto fail;
+ else
+ {
+ /* C1 is the character before D, S1 is the syntax of C1, C2
+ is the character at D, and S2 is the syntax of C2. */
+ int c1, c2, s1, s2;
+ int pos1 = PTR_TO_OFFSET (d);
+ int charpos;
+ GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
#ifdef emacs
- case before_dot:
- DEBUG_PRINT1 ("EXECUTING before_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) >= point)
- goto fail;
- break;
-
- case at_dot:
- DEBUG_PRINT1 ("EXECUTING at_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) != point)
- goto fail;
- break;
-
- case after_dot:
- DEBUG_PRINT1 ("EXECUTING after_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) <= point)
- goto fail;
- break;
+ charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1 - 1);
+ UPDATE_SYNTAX_TABLE (charpos);
+#endif
+ s1 = SYNTAX (c1);
+
+ /* Case 2: S1 is not Sword. */
+ if (s1 != Sword)
+ goto fail;
+
+ /* Case 3: D is not at the end of string ... */
+ if (!AT_STRINGS_END (d))
+ {
+ GET_CHAR_AFTER_2 (c2, d, string1, end1, string2, end2);
+#ifdef emacs
+ UPDATE_SYNTAX_TABLE_FORWARD (charpos);
+#endif
+ s2 = SYNTAX (c2);
+
+ /* ... and S2 is Sword, and WORD_BOUNDARY_P (C1, C2)
+ returns 0. */
+ if ((s2 == Sword) && !WORD_BOUNDARY_P (c1, c2))
+ goto fail;
+ }
+ }
+ break;
+
+#ifdef emacs
+ case before_dot:
+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
+ if (PTR_BYTE_POS ((unsigned char *) d) >= PT_BYTE)
+ goto fail;
+ break;
+
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_BYTE_POS ((unsigned char *) d) != PT_BYTE)
+ goto fail;
+ break;
+
+ case after_dot:
+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
+ if (PTR_BYTE_POS ((unsigned char *) d) <= PT_BYTE)
+ goto fail;
+ break;
case syntaxspec:
- DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
mcnt = *p++;
goto matchsyntax;
- case wordchar:
- DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
mcnt = (int) Sword;
- matchsyntax:
+ matchsyntax:
PREFETCH ();
- if (SYNTAX (*d++) != (enum syntaxcode) mcnt)
- goto fail;
- /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
- d++;
- if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
+#ifdef emacs
+ {
+ int pos1 = SYNTAX_TABLE_BYTE_TO_CHAR (PTR_TO_OFFSET (d));
+ UPDATE_SYNTAX_TABLE (pos1);
+ }
+#endif
+ {
+ int c, len;
+
+ if (multibyte)
+ /* we must concern about multibyte form, ... */
+ c = STRING_CHAR_AND_LENGTH (d, dend - d, len);
+ else
+ /* everything should be handled as ASCII, even though it
+ looks like multibyte form. */
+ c = *d, len = 1;
+
+ if (SYNTAX (c) != (enum syntaxcode) mcnt)
goto fail;
- SET_REGS_MATCHED ();
+ d += len;
+ }
+ SET_REGS_MATCHED ();
break;
case notsyntaxspec:
- DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
mcnt = *p++;
goto matchnotsyntax;
- case notwordchar:
- DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
mcnt = (int) Sword;
- matchnotsyntax:
+ matchnotsyntax:
PREFETCH ();
- /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
- d++;
- if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
+#ifdef emacs
+ {
+ int pos1 = SYNTAX_TABLE_BYTE_TO_CHAR (PTR_TO_OFFSET (d));
+ UPDATE_SYNTAX_TABLE (pos1);
+ }
+#endif
+ {
+ int c, len;
+
+ if (multibyte)
+ c = STRING_CHAR_AND_LENGTH (d, dend - d, len);
+ else
+ c = *d, len = 1;
+
+ if (SYNTAX (c) == (enum syntaxcode) mcnt)
goto fail;
+ d += len;
+ }
+ SET_REGS_MATCHED ();
+ break;
+
+ case categoryspec:
+ DEBUG_PRINT2 ("EXECUTING categoryspec %d.\n", *p);
+ mcnt = *p++;
+ PREFETCH ();
+ {
+ int c, len;
+
+ if (multibyte)
+ c = STRING_CHAR_AND_LENGTH (d, dend - d, len);
+ else
+ c = *d, len = 1;
+
+ if (!CHAR_HAS_CATEGORY (c, mcnt))
+ goto fail;
+ d += len;
+ }
+ SET_REGS_MATCHED ();
+ break;
+
+ case notcategoryspec:
+ DEBUG_PRINT2 ("EXECUTING notcategoryspec %d.\n", *p);
+ mcnt = *p++;
+ PREFETCH ();
+ {
+ int c, len;
+
+ if (multibyte)
+ c = STRING_CHAR_AND_LENGTH (d, dend - d, len);
+ else
+ c = *d, len = 1;
+
+ if (CHAR_HAS_CATEGORY (c, mcnt))
+ goto fail;
+ d += len;
+ }
SET_REGS_MATCHED ();
break;
@@ -4338,6 +5688,9 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
/* We goto here if a matching operation fails. */
fail:
+#if defined (WINDOWSNT) && defined (emacs)
+ QUIT;
+#endif
if (!FAIL_STACK_EMPTY ())
{ /* A restart point is known. Restore to that state. */
DEBUG_PRINT1 ("\nFAIL:\n");
@@ -4644,14 +5997,30 @@ static int
bcmp_translate (s1, s2, len, translate)
unsigned char *s1, *s2;
register int len;
- char *translate;
+ RE_TRANSLATE_TYPE translate;
{
register unsigned char *p1 = s1, *p2 = s2;
- while (len)
+ unsigned char *p1_end = s1 + len;
+ unsigned char *p2_end = s2 + len;
+
+ while (p1 != p1_end && p2 != p2_end)
{
- if (translate[*p1++] != translate[*p2++]) return 1;
- len--;
+ int p1_charlen, p2_charlen;
+ int p1_ch, p2_ch;
+
+ p1_ch = STRING_CHAR_AND_LENGTH (p1, p1_end - p1, p1_charlen);
+ p2_ch = STRING_CHAR_AND_LENGTH (p2, p2_end - p2, p2_charlen);
+
+ if (RE_TRANSLATE (translate, p1_ch)
+ != RE_TRANSLATE (translate, p2_ch))
+ return 1;
+
+ p1 += p1_charlen, p2 += p2_charlen;
}
+
+ if (p1 != p1_end || p2 != p2_end)
+ return 1;
+
return 0;
}
@@ -4688,18 +6057,26 @@ re_compile_pattern (pattern, length, bufp)
ret = regex_compile (pattern, length, re_syntax_options, bufp);
- return re_error_msg[(int) ret];
-}
+ if (!ret)
+ return NULL;
+ return gettext (re_error_msgid[(int) ret]);
+}
/* Entry points compatible with 4.2 BSD regex library. We don't define
- them if this is an Emacs or POSIX compilation. */
+ them unless specifically requested. */
-#if !defined (emacs)
+#if defined (_REGEX_RE_COMP) || defined (_LIBC)
/* BSD has one and only one pattern buffer. */
static struct re_pattern_buffer re_comp_buf;
char *
+#ifdef _LIBC
+/* Make these definitions weak in libc, so POSIX programs can redefine
+ these names if they don't use our functions, and still use
+ regcomp/regexec below without link errors. */
+weak_function
+#endif
re_comp (s)
const char *s;
{
@@ -4708,7 +6085,7 @@ re_comp (s)
if (!s)
{
if (!re_comp_buf.buffer)
- return "No previous regular expression";
+ return gettext ("No previous regular expression");
return 0;
}
@@ -4716,12 +6093,14 @@ re_comp (s)
{
re_comp_buf.buffer = (unsigned char *) malloc (200);
if (re_comp_buf.buffer == NULL)
- return "Memory exhausted";
+ /* CVS: Yes, we're discarding `const' here if !HAVE_LIBINTL. */
+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
re_comp_buf.allocated = 200;
re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
if (re_comp_buf.fastmap == NULL)
- return "Memory exhausted";
+ /* CVS: Yes, we're discarding `const' here if !HAVE_LIBINTL. */
+ return (char *) gettext (re_error_msgid[(int) REG_ESPACE]);
}
/* Since `re_exec' always passes NULL for the `regs' argument, we
@@ -4731,13 +6110,19 @@ re_comp (s)
re_comp_buf.newline_anchor = 1;
ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
-
- /* Yes, we're discarding `const' here. */
- return (char *) re_error_msg[(int) ret];
+
+ if (!ret)
+ return NULL;
+
+ /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */
+ return (char *) gettext (re_error_msgid[(int) ret]);
}
int
+#ifdef _LIBC
+weak_function
+#endif
re_exec (s)
const char *s;
{
@@ -4745,7 +6130,7 @@ re_exec (s)
return
0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
}
-#endif /* not emacs and not _POSIX_SOURCE */
+#endif /* _REGEX_RE_COMP */
/* POSIX.2 functions. Don't define these for Emacs. */
@@ -4799,6 +6184,7 @@ regcomp (preg, pattern, cflags)
/* regex_compile will allocate the space for the compiled pattern. */
preg->buffer = 0;
preg->allocated = 0;
+ preg->used = 0;
/* Don't bother to use a fastmap when searching. This simplifies the
REG_NEWLINE case: if we used a fastmap, we'd have to put all the
@@ -4810,7 +6196,9 @@ regcomp (preg, pattern, cflags)
{
unsigned i;
- preg->translate = (char *) malloc (CHAR_SET_SIZE);
+ preg->translate
+ = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
+ * sizeof (*(RE_TRANSLATE_TYPE)0));
if (preg->translate == NULL)
return (int) REG_ESPACE;
@@ -4936,19 +6324,14 @@ regerror (errcode, preg, errbuf, errbuf_size)
size_t msg_size;
if (errcode < 0
- || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0])))
+ || errcode >= (sizeof (re_error_msgid) / sizeof (re_error_msgid[0])))
/* Only error codes returned by the rest of the code should be passed
to this routine. If we are given anything else, or if other regex
code generates an invalid error code, then the program has a bug.
Dump core so we can fix it. */
abort ();
- msg = re_error_msg[errcode];
-
- /* POSIX doesn't require that we do anything in this case, but why
- not be nice. */
- if (! msg)
- msg = "Success";
+ msg = gettext (re_error_msgid[errcode]);
msg_size = strlen (msg) + 1; /* Includes the null. */
diff --git a/contrib/cvs/lib/regex.h b/contrib/cvs/lib/regex.h
index 6ab52c3..411e7d2 100644
--- a/contrib/cvs/lib/regex.h
+++ b/contrib/cvs/lib/regex.h
@@ -1,7 +1,7 @@
/* Definitions for data structures and routines for the regular
expression library, version 0.12.
- Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1985, 89, 90, 91, 92, 93, 95 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
@@ -11,7 +11,12 @@
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. */
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
#ifndef __REGEXP_LIBRARY_H__
#define __REGEXP_LIBRARY_H__
@@ -19,7 +24,7 @@
/* POSIX says that <sys/types.h> must be included (by the caller) before
<regex.h>. */
-#ifdef VMS
+#if !defined (_POSIX_C_SOURCE) && !defined (_POSIX_SOURCE) && defined (VMS)
/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
should be there. */
#include <stddef.h>
@@ -126,11 +131,22 @@ typedef unsigned reg_syntax_t;
If not set, then an unmatched ) is invalid. */
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+/* If this bit is set, succeed as soon as we match the whole pattern,
+ without further backtracking. */
+#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 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;
+
+#ifdef emacs
+/* In Emacs, this is the string or buffer in which we
+ are matching. It is used for looking up syntax properties. */
+extern Lisp_Object re_match_object;
+#endif
+
/* Define combinations of the above bits for the standard possibilities.
(The [[[ comments delimit what gets put into the Texinfo file, so
@@ -271,6 +287,12 @@ typedef enum
compiled, the `re_nsub' field is available. All other fields are
private to the regex routines. */
+#ifndef RE_TRANSLATE_TYPE
+#define RE_TRANSLATE_TYPE char *
+#define RE_TRANSLATE(TBL, C) ((TBL)[C])
+#define RE_TRANSLATE_P(TBL) (TBL)
+#endif
+
struct re_pattern_buffer
{
/* [[[begin pattern_buffer]]] */
@@ -297,7 +319,7 @@ struct re_pattern_buffer
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. */
- char *translate;
+ RE_TRANSLATE_TYPE translate;
/* Number of subexpressions found by the compiler. */
size_t re_nsub;
@@ -336,15 +358,14 @@ struct re_pattern_buffer
/* If true, an anchor at a newline matches. */
unsigned newline_anchor : 1;
+ /* If true, multi-byte form in the `buffer' should be recognized as a
+ multibyte character. */
+ unsigned multibyte : 1;
+
/* [[[end pattern_buffer]]] */
};
typedef struct re_pattern_buffer regex_t;
-
-
-/* search.c (search_buffer) in Emacs needs this one opcode value. It is
- defined both in `regex.c' and here. */
-#define RE_EXACTN_VALUE 1
/* Type for byte offsets within the string. POSIX mandates this. */
typedef int regoff_t;
@@ -461,11 +482,12 @@ extern void re_set_registers
_RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
unsigned num_regs, regoff_t *starts, regoff_t *ends));
-/* 4.2 bsd compatibility. System headers may declare the argument as
- either "char *" (e.g. Cray unistd.h) or "const char *" (e.g. linux
- regex.h), so don't prototype them here. */
-extern char *re_comp ();
-extern int re_exec ();
+#ifdef _REGEX_RE_COMP
+/* 4.2 bsd compatibility. */
+/* CVS: don't use prototypes: they may conflict with system headers. */
+extern char *re_comp _RE_ARGS (());
+extern int re_exec _RE_ARGS (());
+#endif
/* POSIX compatibility. */
extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
diff --git a/contrib/cvs/lib/savecwd.c b/contrib/cvs/lib/savecwd.c
index b5b7cb8..2d687c3 100644
--- a/contrib/cvs/lib/savecwd.c
+++ b/contrib/cvs/lib/savecwd.c
@@ -13,6 +13,7 @@
#endif
#ifdef HAVE_FCNTL_H
+# include <sys/types.h>
# include <fcntl.h>
#else
# include <sys/file.h>
diff --git a/contrib/cvs/lib/sighandle.c b/contrib/cvs/lib/sighandle.c
index b229ea6..2d21df8 100644
--- a/contrib/cvs/lib/sighandle.c
+++ b/contrib/cvs/lib/sighandle.c
@@ -384,6 +384,16 @@ void SIG_beginCrSect()
}
/*
+ * Return nonzero if currently in a critical section.
+ * Otherwise return zero.
+ */
+
+int SIG_inCrSect()
+{
+ return SIG_crSectNest > 0;
+}
+
+/*
* The following ends a critical section.
*/
diff --git a/contrib/cvs/man/ChangeLog b/contrib/cvs/man/ChangeLog
index 38cc91b..adb8e2d 100644
--- a/contrib/cvs/man/ChangeLog
+++ b/contrib/cvs/man/ChangeLog
@@ -1,3 +1,37 @@
+2000-09-07 Larry Jones <larry.jones@sdrc.com>
+
+ * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@
+ from autoconf.
+
+2000-05-03 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.1: Correct CVSEDITOR/VISUAL/EDITOR documentation.
+ Correct KJ's botched patch application.
+
+2000-01-02 John P Cavanaugh <cavanaug@sr.hp.com>
+
+ * cvs.texinfo: document new -C option to update, now that it works
+ both remotely and locally.
+ (Re-applied by Karl Fogel <kfogel@red-bean.com>.)
+
+1999-12-11 Karl Fogel <kfogel@red-bean.com>
+
+ * Revert previous change -- it doesn't work remotely yet.
+
+1999-12-10 John P Cavanaugh <cavanaug@sr.hp.com>
+
+ * cvs.1: document new -C option to update.
+ (Applied by Karl Fogel <kfogel@red-bean.com>.)
+
+1999-11-29 Larry Jones <larry.jones@sdrc.com>
+
+ * cvsbug.8: Change .TH from section 1 to section 8.
+
+1999-11-10 Jim Kingdon <http://developer.redhat.com/>
+
+ * cvs.1: Don't document -H as a command option; it has been a
+ while since that worked.
+
1999-01-19 Vitaly V Fedrushkov <willy@snowyowl.csu.ac.ru>
* Makefile.in (INSTALL_DATA): Wrong manpage permissions fixed.
diff --git a/contrib/cvs/man/Makefile.in b/contrib/cvs/man/Makefile.in
index d92d494..f9b5665 100644
--- a/contrib/cvs/man/Makefile.in
+++ b/contrib/cvs/man/Makefile.in
@@ -27,7 +27,7 @@ DISTFILES = .cvsignore ChangeLog Makefile.in $(MANFILES)
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
prefix = @prefix@
-mandir = $(prefix)/man
+mandir = @mandir@
man1dir = $(mandir)/man1
man5dir = $(mandir)/man5
man8dir = $(mandir)/man8
diff --git a/contrib/cvs/man/cvs.1 b/contrib/cvs/man/cvs.1
index 8cbe2be..b29b71f 100644
--- a/contrib/cvs/man/cvs.1
+++ b/contrib/cvs/man/cvs.1
@@ -192,8 +192,10 @@ Use
.I editor
to enter revision log information.
Overrides the setting of the
-.SM CVSEDITOR
-and the
+.SM CVSEDITOR\c
+,
+.SM VISUAL\c
+, and
.SM EDITOR
environment variables.
.TP
@@ -358,6 +360,11 @@ file; see
Incorporate a set of updates from off-site into the source repository,
as a ``vendor branch''. (Changes repository.)
.TP
+.B init
+Initialize a repository by adding the CVSROOT subdirectory and some default
+control files. You must use this command or initialize the repository in
+some other way before you can use it.
+.TP
.B log
Display
log information.
@@ -473,13 +480,6 @@ is available with these commands:
.BR checkout ", " export ", "
.BR rdiff ", " rtag ", and " update .
.TP
-.B \-H
-Help; describe the options available for this command. This is the
-only option supported for
-.I all
-.B cvs
-commands.
-.TP
\fB\-k\fP \fIkflag\fP
Alter the default
processing of keywords.
@@ -1684,7 +1684,7 @@ executes recursively through subdirectories; you can prevent this by
using the standard \fB\-l\fP option, or specify the recursion
explicitly by using \fB\-R\fP.
.TP
-\fBupdate\fP [\fB\-Adf\|lPpQqR\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP|\fB\-D\fP \fIdate\fP] \fIfiles\|.\|.\|.\fP
+\fBupdate\fP [\fB\-ACdf\|lPpQqR\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP|\fB\-D\fP \fIdate\fP] \fIfiles\|.\|.\|.\fP
.I Requires:
repository, working directory.
.br
@@ -1841,6 +1841,12 @@ Use
.` "\-I !"
to avoid ignoring any files at all.
.SP
+Use the
+.` "\-C"
+option to overwrite locally modified files with clean copies from
+the repository (the modified file is saved in
+`\fB.#\fP\fIfile\fP\fB.\fP\fIrevision\fP', however).
+.SP
The standard \fBcvs\fP command options \fB\-f\fP, \fB\-k\fP,
\fB\-l\fP, \fB\-P\fP, \fB\-p\fP, and \fB\-r\fP
are also available with \fBupdate\fP.
@@ -2035,12 +2041,13 @@ and
Specifies the program to use for recording log messages during
.BR commit .
If not set, the
+.SM VISUAL
+and
.SM EDITOR
-environment variable is used instead.
-If
-.SM EDITOR
-is not set either, the default is
-.BR /usr/ucb/vi .
+environment variables are tried (in that order).
+If neither is set, a system-dependent default editor (e.g.,
+.BR vi )
+is used.
.TP
.SM CVS_IGNORE_REMOTE_ROOT
If this variable is set then
diff --git a/contrib/cvs/man/cvsbug.8 b/contrib/cvs/man/cvsbug.8
index 63574d4..ecf2eb8 100644
--- a/contrib/cvs/man/cvsbug.8
+++ b/contrib/cvs/man/cvsbug.8
@@ -18,7 +18,7 @@
.\"
.\" ---------------------------------------------------------------------------
.nh
-.TH CVSBUG 1 xVERSIONx "February 1993"
+.TH CVSBUG 8 xVERSIONx "February 1993"
.SH NAME
cvsbug \- send problem report (PR) about CVS to a central support site
.SH SYNOPSIS
diff --git a/contrib/cvs/mkinstalldirs b/contrib/cvs/mkinstalldirs
index 91f6d04..9259785 100755
--- a/contrib/cvs/mkinstalldirs
+++ b/contrib/cvs/mkinstalldirs
@@ -4,6 +4,7 @@
# Created: 1993-05-16
# Last modified: 1994-03-25
# Public domain
+#
errstatus=0
diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog
index 0d18891..a33464d 100644
--- a/contrib/cvs/src/ChangeLog
+++ b/contrib/cvs/src/ChangeLog
@@ -1,3 +1,1104 @@
+2000-09-19 Larry Jones <larry.jones@sdrc.com>
+
+ * version.c: Version 1.11.
+
+2000-09-07 Larry Jones <larry.jones@sdrc.com>
+
+ * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@
+ from autoconf.
+
+2000-08-23 Larry Jones <larry.jones@sdrc.com>
+
+ * mkmodules.c (init): Create an empty val-tags file if it doesn't
+ already exist to avoid problems with users not having sufficient
+ permissions to create it later.
+
+2000-09-06 Jim Kingdon <jkingdon@dhcp-net200-89.su.valinux.com>
+
+ * main.c (lookup_command_attribute): Add "release" to commands
+ which can be done by a read-only user.
+
+2000-08-23 Larry Jones <larry.jones@sdrc.com>
+
+ * repos.c (Name_Repository): Use pathname_levels to detect attempts
+ to get above the repository instead of checking for leading ..
+ which isn't reliable.
+ * sanity.sh (multiroot3-12 to multiroot3-15): New tests for above.
+
+2000-08-21 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (expand_keywords): Handle the unusual case of log == NULL.
+ (Reported by Craig Metz <cmetz@inner.net>.)
+
+2000-08-01 Larry Jones <larry.jones@sdrc.com>
+
+ * subr.c (pathname_levels): Fix bug that miscounts adjacent
+ slashes.
+ (Patch submitted by Tanaka Akira <akr@m17n.org>.)
+
+ * loginc.c (login): If available, use getpassphrase instead of
+ getpass to support long passwords on Solaris.
+
+2000-07-28 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (server_noop): Avoid do_cvs_command() overhead.
+ (requests): Make noop RQ_ROOTLESS.
+
+2000-07-27 Noel Cragg <noel@red-bean.com>
+
+ * root.c (parse_cvsroot): change fork method to behave like other
+ remote methods -- let the server check that the repository
+ directory is an absolute pathname.
+
+2000-07-27 Larry Jones <larry.jones@sdrc.com>
+
+ * lock.c (set_lock): Include actual lock directory in error message.
+ * sanity.sh (multiroot3-10): Change to match.
+
+ * sanity.sh (client-3): Allow for a potential "broken pipe".
+
+2000-07-26 Larry Jones <larry.jones@sdrc.com>
+
+ * commit.c (commit_filesdoneproc): Flush stdout before running script.
+ * modules.c (do_module): Ditto.
+ * update.c (update_dirleave_proc): Ditto.
+ * server.c (do_cvs_command): Give input from the protocol pipe
+ precedence over input from stdout/stderr. There's no particularly
+ good justification for this other than helping to avoid out-of-order
+ messages in sanity.sh.
+
+ * admin.c (admin_usage): Add the supported options.
+
+ * sanity.sh (info): Try to avoid out-of-order messages.
+
+ * sanity.sh (info): Fix problems when running twice in a row.
+
+2000-07-17 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (modules5-7, cvsadm-1e, emptydir-2): Allow for a nil
+ commit (can happen if the test is run twice in a row).
+
+2000-07-19 Pavel Roskin <proski@gnu.org>
+ and Larry Jones <larry.jones@sdrc.com>
+
+ * mkmodules.c (config_contents): Add a commented out example for
+ LockDir. Don't suggest PreservePermissions unless it's enabled.
+
+2000-07-17 Larry Jones <larry.jones@sdrc.com>
+
+ * login.c (get_cvs_password): Handle malformed ~/.cvspass more
+ gracefully.
+
+2000-07-12 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (modules5): New tests for module programs.
+
+2000-07-11 Larry Jones <larry.jones@sdrc.com>
+
+ * filesubr.c (copy_file, xcmp): Handle systems (like Plan 9) that
+ don't support mknod() and/or st_rdev.
+ * import.c (add_rcs_file): Ditto.
+ * rcs.c (RCS_checkout, RCS_checkin): Ditto.
+ * update.c (special_file_mismatch): Ditto.
+
+2000-07-10 Larry Jones <larry.jones@sdrc.com>
+
+ * zlib.c (gunzip_and_write): Fix type clashes.
+
+ * main.c (main): Remove unused variables.
+
+2000-07-10 Jim Meyering <meyering@lucent.com>
+
+ When a command like `cvs update -kk -jT1 -jT2' creates a new file
+ (because it had the T2 tag, but not T1), the subsequent commit of
+ that just-added file would effectively set the admin `-kk' option
+ for that file in the repository.
+
+ * update.c (join_file): Rename global-shadowing local `options'
+ to `t_options'.
+ Set file-scoped global `options' to NULL just before
+ check-out.
+ * sanity.sh (join-admin): New test for this.
+
+2000-07-08 Larry Jones <larry.jones@sdrc.com>
+
+ * version.c, cvs.h (version): New function.
+ * main.c (cmds[]): Add version command to invoke it.
+ (main): Also use it in -v.
+ * server.c (serve_version): New function.
+ (requests[]): Add version command to invoke it.
+
+2000-07-06 Karl Fogel <kfogel@red-bean.com>
+
+ * sanity.sh (pserver-14): remove this test for portability
+ reasons (it was only recently added for the 2000-07-04 change).
+
+2000-07-06 Larry Jones <larry.jones@sdrc.com>
+
+ sanity.sh (modules-148): Don't test for specific revisions.
+
+ * main.c (main): Catch SIGABRT to try to clean up after assertion
+ failures. Don't bother SIG_register'ing Lock_Cleanup because
+ main_cleanup calls it indirectly anyway.
+ * patch.c (patch): Catch SIGABRT.
+ * rcs.c (rcs_internal_lockfile): Ditto.
+ * server.c (server): Ditto.
+
+ * fileattr.c (fileattr_write): Don't delete the unrecog_head list
+ when writing...
+ (fileattr_free): Delete it when freeing!
+
+2000-07-05 Larry Jones <larry.jones@sdrc.com>
+
+ * admin.c (admin): Handle -t in client so reading from files works
+ correctly in client/server mode.
+ * sanity.sh (log2): Update to match.
+
+2000-07-04 Karl Fogel <kfogel@red-bean.com>
+
+ * server.c (pserver_authenticate_connection): use new
+ getline_safe() during authentication phase, to avoid a
+ denial-of-service attack in which client sends arbitrary
+ amounts of data with no newlines.
+ (Reported by <jpmg@eng.cam.ac.uk>.)
+
+ * sanity.sh: new test pserver-14 for above.
+
+ * myndbm.c: #include getline.h.
+ (mydbm_load_file): pass new GETLINE_NO_LIMIT flag to getstr().
+
+2000-07-03 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (modules): Rewrite using dotest. Add "modules-"
+ prefix to test names.
+
+2000-06-28 Larry Jones <larry.jones@sdrc.com>
+
+ * error.c (error_exit): Call rcs_cleanup () to release any rcs locks.
+ * rcs.c, rcs.h (rcs_cleanup): Make public, close file before trying
+ to remove (some systems won't remove open files).
+ (RCS_putdtree): Don't worry about cleaning up before call error
+ since it now does it for us.
+ (rcs_internal_lockfile, rcs_internal_unlockfile): Keep track of
+ lock file fd for rcs_cleanup ().
+
+ * client.c (handle_set_checkin_prog, handle_set_update_prog):
+ Just ignore the request when exporting.
+
+2000-06-27 Larry Jones <larry.jones@sdrc.com>
+
+ * create_adm.c, cvs.h (Create_Admin): Add dotemplate argument.
+ Change all callers.
+ * checkout.c (checkout_proc): Don't create CVS/Template if
+ exporting.
+
+2000-06-26 Pavel Roskin <proski@gnu.org>
+ and Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (switch_to_user): Only set CVS_Username if
+ AUTH_SERVER_SUPPORT is defined.
+
+2000-06-23 Larry Jones <larry.jones@sdrc.com>
+
+ * client.c (send_dirent_proc): Don't allocate ignlist if you're
+ going to skip the directory (plugs memory leak).
+ (send_dirleave_proc): New function.
+ (send_files): Use it (plugs memory leak).
+ * root.c (root_allow_free): Plug memory leaks.
+ * server.c (serve_directory, serve_notify, check_password,
+ pserver_authenticate_connection): Ditto.
+ * update.c (update): Ditto.
+
+ This completes the memory leak shoot-out -- the Purify'ed version
+ of CVS now runs the entire test suite, both local and remote (except
+ for remote crerepos, which causes Purify to choke) with *no* memory
+ leaks.
+
+ * server.c (pserver_authenticate_connection): Don't free null pointer.
+
+2000-06-21 Larry Jones <larry.jones@sdrc.com>
+
+ * client.c (update_entries, get_responses_and_close): Plug memory leaks.
+ * commit.c (find_fileproc, commit): Ditto.
+ * import.c (import): Ditto.
+ * log.c (cvslog): Ditto.
+ * recurse.c (start_recursion): Ditto.
+ * remove.c (cvsremove): Ditto.
+ * server.c (fd_buffer_initialize, server_notify, do_cvs_command): Ditto.
+ (fd_buffer_shutdown): New function.
+
+2000-06-20 Larry Jones <larry.jones@sdrc.com>
+
+ * root.c (parse_cvsroot): Put the terminating NUL byte into the
+ string *before* copying it, not after. :-(
+
+2000-06-19 Larry Jones <larry.jones@sdrc.com>
+
+ * main.c (main): Plug memory leaks.
+ * root.c (parse_cvsroot, set_local_cvsroot): Ditto.
+ * server.c (serve_root): Ditto.
+
+2000-06-16 Larry Jones <larry.jones@sdrc.com>
+
+ * fileattr.c (fileattr_read): Plug memory leak.
+ * rcs.c (RCS_whatbranch): Ditto.
+ * update.c (update_dirleave_proc): Ditto.
+
+ * ignore.c (ign_dir_add): Duplicate string so caller can free.
+
+ * modules.c (do_module): Don't write into dbm's memory!
+
+2000-06-15 Larry Jones <larry.jones@sdrc.com>
+
+ * checkout.c (checkout_proc): Fix non-ANSI code in call to
+ findslash(), minor cleanups.
+
+2000-06-14 Larry Jones <larry.jones@sdrc.com>
+
+ * tag.c (val_direntproc): Return R_PROCESS instead of 0.
+
+ * client.c (update_entries): Fix type clash calling gunzip_and_write().
+ * server.c (receive_file): Fix type clash calling gunzip_and_write().
+ (server_updated): Fix type clash calling buf_output().
+ * error.c (error): Make buf char instead of unsigned char to avoid
+ type clashes.
+
+ * modules.c (do_module): Change callback_proc to pass argc by
+ value instead of by reference: callback procs shouldn't be
+ messing with the callers argc/argv, it makes correct memory
+ management impossible. Plug memory leaks.
+ * cvs.h: Change to match.
+ * checkout.c (checkout_proc): Ditto; use a local argv array instead
+ of messing with caller's.
+ * modules.c (callback_proc): Ditto.
+ * patch.c (patch_proc): Ditto; use a local argv array instead
+ of messing with caller's.
+ * rtag.c (rtag_proc): Ditto; use a local argv array instead
+ of messing with caller's.
+ * server.c (expand_proc): Ditto.
+ * subr.c (line2argv): Change initial argv_allocated back to 1.
+
+ * checkout.c (findslash): Fix non-ANSI code.
+
+ * sanity.sh (modes3): Fix test names.
+
+2000-06-13 Larry Jones <larry.jones@sdrc.com>
+
+ * add.c (add): Plug memory leaks.
+ * admin.c (admin_fileproc): Ditto.
+ * checkout.c (build_dirs_and_chdir): Ditto.
+ * edit.c (editors_fileproc): Ditto.
+ * log.c (cvslog, log_parse_revlist, log_parse_date): Ditto.
+ * rcs.c (RCS_addaccess): Ditto.
+ * tag.c (check_fileproc): Ditto.
+ * vers_ts.c (Version_TS): Ditto.
+ * watch.c (watchers_fileproc): Ditto.
+
+2000-06-12 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (rcsbuf_valword): Set rcsbuf->vlen to keep rcsbuf_valcopy()
+ from allocating more memory than needed for @ strings. Don't declare
+ unless PRESERVE_PERMISSIONS_SUPPORT (since not defined).
+
+ * rcs.c (RCS_abandon): New function to abandon changes.
+ * rcs.h: Declare it.
+ * admin.c (admin_fileproc): Use it instead of RCS_reparsercsfile.
+
+ * commit.c (commit_fileproc): Fix memory leaks.
+ * patch.c (patch_fileproc): Ditto.
+ * rcs.c (RCS_nodeisbranch, RCS_copydeltas): Ditto.
+ * tag.c (tag_fileproc): Ditto.
+ * update.c (update): Ditto.
+
+2000-06-09 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_reparsercsfile, RCS_fully_parse, getdelta,
+ RCS_getdeltatext): Handle newphrases with composite values.
+ (rcsbuf_getkey): Don't remove @s in composite values -- it makes
+ it impossible to parse the value! Set special flag to indicate
+ a composite value.
+ (rcsbuf_valcopy, rcsbuf_valpolish_internal): Handle composite values.
+ (putrcsfield): Write composite values.
+ (RCS_checkin): Set node types in other_delta list.
+ * hash.h: Add RCSCMPFLD.
+ * hash.c (nodetypestring): Ditto.
+
+ * rcs.c (getdelta): Never allocate space for value, just return
+ pointer into rcsbuf (fixes memory leaks). Use rcsbuf_getkey to
+ read a key and value and then parse the value if needed rather
+ than trying to read it in bits and pieces with rcsbuf_getid,
+ rcsbuf_getstring, and rcsbuf_getword.
+ (RCS_reparsercsfile): Change callers to compensate.
+ (rcsbuf_valcmp, rcsbuf_valword): New functions.
+ (rcsbuf_getid, rcsbuf_getstring, rcsbuf_getword): Deleted.
+ * sanity.sh (rcs3-1): Now get slightly different error message.
+
+2000-06-08 Larry Jones <larry.jones@sdrc.com>
+
+ * main.c (usg): Update CVS home page URL.
+
+ * main.c (main): Provide an actual error message for an unknown
+ command in addition to the usage message.
+
+2000-06-07 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (serve_root, dirswitch, serve_repository,
+ serve_static_directory, serve_sticky, receive_partial_file,
+ receive_file, serve_modified, server_write_entries, serve_notify,
+ serve_checkin_prog, serve_update_prog, server): Don't set
+ pending_error before calling alloc_pending, it makes it fail;
+ use alloc_pending instead of malloc when reasonable; be sure to
+ save errno before calling functions that might change it.
+ (Patch submitted by Dietmar Petras <dietmar.petras@elsa.de>.)
+
+2000-06-03 Larry Jones <larry.jones@sdrc.com>
+
+ * commit.c (checkaddfile): Plug memory leak.
+ * rcs.c (RCS_checkin): Plug memory leaks.
+ * server.c (do_cvs_command): Plug file descriptor leaks.
+ * tag.c (check_fileproc): Plug memory leak.
+
+2000-05-26 Larry Jones <larry.jones@sdrc.com>
+
+ * recurse.c (unroll_files_proc): Plug memory leak.
+
+ * recurse.c (addfile): Fix nonportable pointer cast.
+
+ * rcs.c (rcsbuf_getstring, rcsbuf_getword, getdelta): Plug memory
+ leaks.
+
+2000-05-25 Larry Jones <larry.jones@sdrc.com>
+
+ * checkout.c (checkout, build_one_dir, checkout_proc): Move m_type
+ to file scope and use it instead of continually doing strcmp on
+ command_name.
+ (build_one_dir, checkout_proc): Don't allow export if CVSADM
+ directory already exists.
+
+2000-05-23 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_checkin, RCS_cmp_file): Plug memory leaks. (Patch
+ submitted by Chris G. Demetriou <cgd@sibyte.com>.)
+
+2000-05-20 Ian Lance Taylor <ian@zembu.com>
+
+ * client.c (connect_to_gserver): Handle server error messages
+ reasonably.
+
+2000-05-19 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (requests): Make Global_option RQ_ROOTLESS so it can be
+ used with init.
+
+2000-05-18 Larry Jones <larry.jones@sdrc.com>
+
+ * client.c (start_server): Don't do encryption, authentication,
+ compression, or case insensitivity when doing init because init
+ is ROOTLESS and they're not.
+
+ * client.c (connect_to_pserver): Include repository and username in
+ authorization failed message -- if a directory tree crosses multiple
+ repositories, it can be quite difficult for the user to figure out
+ which one is the problem.
+
+2000-05-17 Larry Jones <larry.jones@sdrc.com>
+
+ * main.c (main): Use full set of options when looking for -f to
+ avoid misparsing options that take values (previously, -sVAR=foo
+ was incorrectly parsed as though it were -s -V -A -R -= -f -o -o
+ because it didn't know that -s takes a value).
+ * sanity.sh (info-6b): New test for above.
+
+ * sanity.sh (conflicts-status): Fix tests so they work remotely, too.
+
+2000-05-17 Jim Meyering <meyering@lucent.com>
+
+ * sanity.sh (TESTDIR): Fix braino in last change:
+ cd to /tmp before invoking pwd.
+
+ * sanity.sh: Set TESTDIR so that `make check' passes even when /tmp
+ is a symlink.
+ (join-36): Use $TESTDIR rather than hard-coding `/tmp/cvs-sanity'.
+ (conflicts-132): Remove unnecessary `rm aa'.
+
+2000-05-16 Jim Kingdon <kingdon@redhat.com>
+
+ * cvs.h, checkout.c (safe_location): Make extern.
+ * import.c (import): Call it rather than reimplementing
+ (incompletely) the same check.
+
+2000-05-16 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.h, subr.c (file_has_markers): Check for any of the three
+ conflict marker lines, not just one.
+ * sanity.sh (conflicts-status): New tests for above.
+ * sanity.sh: Revise to avoid tripping the above check when merging
+ changes into sanity.sh itself.
+
+2000-05-15 Larry Jones <larry.jones@sdrc.com>
+
+ * update.c (join_file): When registering the result of the merge,
+ make sure that the version number is valid (vers->vn_rcs may be
+ null if the file doesn't exist on the branch yet). (Patch submitted
+ by Robert de Vries <rhdv@rhdv.cistron.nl>.)
+ * update.c (join_file): Correct diagnostics (previous change was not
+ correct -- the file *does* exist in the specified revision, it just
+ doesn't exist in the sandbox).
+ * sanity.sh (import-113, join): New tests and changes for above.
+
+2000-05-04 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh: Look for a useful id program. Since we're getting
+ the real username for some tests anyway, use it for all the
+ tests instead of a generic regular expression that may or may
+ not match the actual username.
+
+2000-05-04 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c: More error messages.
+
+2000-05-02 Donald Sharp <sharpd@cisco.com>
+ and Larry Jones <larry.jones@sdrc.com>
+
+ * history.c (report_hrecs): Added code to print out year instead of
+ just month/day.
+ * sanity.sh (basic2-64, history): Update to match.
+
+2000-04-19 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (dirswitch): Set pending_error_text in addition to
+ pending_error to aid in problem determination.
+
+2000-03-23 Larry Jones <larry.jones@sdrc.com>
+
+ * mkmodules.c (mkmodules): Return without doing anything if noexec
+ is set to avoid trashing existing files.
+
+2000-03-23 Larry Jones <larry.jones@sdrc.com>
+
+ * main.c: Alphabetize cmds[] and cmd_usage[] and add server
+ commands to cmd_usage[].
+
+2000-03-21 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (client-1): May get "Broken pipe" message from the
+ "server" in addition to the expected output.
+
+2000-03-17 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (switch_to_user): Set CVS_Username if it hasn't already
+ been set elsewhere. (Patch submitted by Gordon Matzigkeit
+ <gord@fig.org>).
+
+2000-03-13 Larry Jones <larry.jones@sdrc.com>
+
+ * parseinfo.c: Add extern to logHistory declaration. (Reported by
+ <John.Tytgat@aaug.net>.)
+ (parse_config): Reformat logHistory code.
+
+2000-03-10 Larry Jones <larry.jones@sdrc.com>
+
+ * add.c (add): Don't try to set cvsroot_len until after checking
+ for help only -- CVSroot_directory isn't set in that case.
+
+2000-03-03 Larry Jones <larry.jones@sdrc.com>
+
+ * mkmodules.c (init): Use mkdir_if_needed to create CVSROOT/Emptydir
+ so we don't fail if run multiple times. (Reported by KOIE Hidetaka
+ <hide@koie.org>.)
+ * sanity.sh (1a): New test for above.
+
+2000-03-02 Larry Jones <larry.jones@sdrc.com>
+
+ * main.c: Use identical #if's in the command table and the code
+ for pserver and kserver to prevent "peculiar" configurations from
+ having really perverse behavior because the command table entries
+ are present but the related code isn't.
+
+2000-03-01 Larry Jones <larry.jones@sdrc.com>
+
+ * import.c (import): Don't allow importing the repository.
+ * sanity.sh (errmsg2-20, errmsg2-21): New tests for above.
+
+2000-03-01 Larry Jones <larry.jones@sdrc.com>
+
+ * main.c (main): Update year in copyright message.
+
+2000-03-01 Larry Jones <larry.jones@sdrc.com>
+
+ * logmsg.c (do_editor): Correct previous change.
+
+2000-02-29 Larry Jones <larry.jones@sdrc.com>
+
+ * logmsg.c (do_editor): When reading temp file, check that message
+ buffer is large enough to hold the next line and expand if needed.
+
+2000-02-28 Larry Jones <larry.jones@sdrc.com>
+
+ * commit.c (commit): Use get_file() to read log file correctly
+ and in text mode rather than binary mode.
+
+ * subr.c (get_file): Ignore bufsize if buf is NULL. Include
+ terminating NUL byte when estimating required buffer size.
+
+2000-02-28 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (find_tool): New function to replace duplicated code.
+
+2000-02-25 Larry Jones <larry.jones@sdrc.com>
+
+ * import.c (add_rcs_file): Don't abort just because lstat fails.
+
+2000-02-16 Jim Meyering <meyering@lucent.com>
+
+ Avoid race condition whereby a catchable signal could
+ end up corrupting the repository.
+ * commit.c (checkaddfile): Put a critical section around the code
+ that handles the first commit on the trunk of a file that's already
+ been committed on a branch.
+ * cvs.h (Sig_inCrSect): Declare new function.
+
+2000-02-21 Karl Fogel <kfogel@red-bean.com>
+
+ * main.c (main): still check for repository, but not history file
+ (correction to 2000-02-18 change -- that's what I get for
+ believing the comment rather than the code).
+
+2000-02-21 K.J. Paradise <kj@sourcegear.com>
+
+ * history.c mkmodules.c parseinfo.c: control which actions
+ get logged to the cvs history file via CVSROOT/config file
+ and LogHistory keyword. (John P Cavanaugh <cavanaug@sr.hp.com>)
+
+2000-02-18 Karl Fogel <kfogel@red-bean.com>
+
+ * history.c (history_write): don't die if history file not
+ writable, just warn (unless `really_quiet') and skip out.
+
+ * main.c (main): don't bother checking if history file is
+ writable.
+
+ * server.c (serve_root): same.
+
+2000-02-17 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (perms symlinks symlinks2 hardlinks): Don't run by
+ default since PreservePermissions code is now disabled.
+
+2000-02-17 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (import-113): Revise to match Jim Meyering's fix.
+
+2000-02-16 Larry Jones <larry.jones@sdrc.com>
+
+ * add.c (add): Don't allow adding files or directories to Emptydir.
+ (Patch submitted by Chris Cameron <chris.cameron@ot.co.nz>.)
+ * sanity.sh (emptydir): Revise (emptydir-7 and emptydir-8) for this.
+
+2000-02-16 Jim Meyering <meyering@lucent.com>
+
+ * update.c (join_file): Correct typo in diagnostic:
+ change `file %s is present...' to `file %s is not present...'.
+
+2000-02-10 Larry Jones <larry.jones@sdrc.com>
+
+ * parseinfo.c (Parse_Info): Treat matching lines with bad expansions
+ as errors rather than just ignoring.
+
+2000-02-10 Larry Jones <larry.jones@sdrc.com>
+
+ * edit.c (edit): Check for invalid characters in hostname and CurDir.
+ (Reported by "Andrew S. Townley" <atownley@informix.com>.)
+ * sanity.sh (devcom2): New tests for above.
+
+2000-02-10 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.h: Always #include "server.h" to prevent compile errors when
+ neither CLIENT_SUPPORT nor SERVER_SUPPORT is defined.
+ (Reported by "Crow, Ian" <ian.crow@linklaters.com>.)
+ * log.c (send_one, send_arg_list): Only define when CLIENT_SUPPORT
+ is defined to prevent link errors.
+
+ * server.c (server): Always create a new temporary directory, don't
+ try to reuse an existing one since we might not have correct
+ permissions. Also, include directory name in error messages.
+
+2000-01-29 Jim Kingdon <http://developer.redhat.com/>
+
+ * ignore.c (ignore_files): Correctly set errno to 0 when we go
+ back to the top of the loop. Fixes spurious errors like "cvs
+ update: error reading current directory: No such file or
+ directory".
+
+2000-01-26 Larry Jones <larry.jones@sdrc.com>
+
+ * run.c (run_exec): Conditionalize K.J.'s change so that it only
+ applies when SETXID_SUPPORT is defined since some platforms don't
+ have setegid().
+
+2000-01-26 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh: Make TESTDIR earlier then use it to check for versions
+ of expr that don't work right with long expressions.
+
+ * sanity.sh (dotest_line_by_line): Have wc read from stdin so it
+ doesn't output the file name and confuse expr. Make the output a
+ bit less verbose and easier to read.
+
+2000-01-24 K.J. Paradise <kj@sourcegear.com>
+
+ * run.c :> prevents a user from creating a privileged shell from the
+ text editor when the SETXID_SUPPORT option is selected. This came from
+ Bob Colle <bcolle@ilx.com>, and is his completely.
+
+2000-01-22 Jim Kingdon <http://developer.redhat.com/>
+
+ * sanity.sh (emptydir): Add a case in which one might hope for a
+ non-Emptydir result, but which result?
+
+2000-01-18 Larry Jones <larry.jones@sdrc.com>
+
+ * main.c (main): Allow -z0 to disable gzip compression.
+
+2000-01-17 Larry Jones <larry.jones@sdrc.com> for
+ K.J. Paradise (kj@sourcegear.com)
+
+ * version.c: Push version number to 1.10.8.1.
+
+ * version.c: Version 1.10.8.
+
+2000-01-17 Larry Jones <larry.jones@sdrc.com>
+
+ * mkmodules.c (init): Create CVSROOT/Emptydir to avoid problems
+ with users not having sufficient permissions to create it later.
+
+2000-01-04 Larry Jones <larry.jones@sdrc.com>
+
+ * client.c (get_responses_and_close): Simplify time-stamp race
+ avoidance code.
+ * commit.c (commit): Ditto.
+ * update.c (do_update): Ditto.
+ (Prompted by patch submitted by Pavel Roskin
+ <pavel_roskin@geocities.com>.)
+
+ * hardlink.c: sizeof (char) is 1, by definition.
+ * logmsg.c: Ditto.
+ * rcs.c: Ditto.
+
+2000-01-03 Karl Fogel <kfogel@red-bean.com>
+
+ * filesubr.c, subr.c (backup_file): moved this function from
+ filesubr.c to subr.c, at JimK's suggestion.
+
+2000-01-03 Jim Kingdon <http://developer.redhat.com/>
+
+ * sanity.sh (clean): Test the contents of the .#cleanme.txt.1.1
+ file, not just its existence.
+
+2000-01-03 Karl Fogel <kfogel@red-bean.com>
+
+ * cvs.h, filesubr.c (backup_file): use `const' for suffix too;
+ correct suffix length calculation and appending behavior; discard
+ unnecessary `void' cast. Thanks to Jim Meyering for noticing.
+
+2000-01-03 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (clean): Fix up expected output.
+
+2000-01-02 John P Cavanaugh <cavanaug@sr.hp.com>
+ and Karl Fogel <kfogel@red-bean.com>
+
+ New -C option to update: overwrites local changes with clean
+ copies from the repository. (This is an unreversion of the
+ 1999-12-10 change, further modified to work remotely.)
+
+ * client.h (BACKUP_MODIFIED_FILES): new #define.
+
+ * client.c (struct send_data): new element `backup_modified'.
+ (send_files): set above element if BACKUP_MODIFIED_FILES flag is
+ present.
+
+ * filesubr.c (backup_file): new function.
+
+ * cvs.h: prototype for new function `backup_file'.
+
+ * update.c (toss_local_changes): new file-scoped global.
+ (update): set toss_local_changes if -C flag seen. If
+ client_active, send "-C" to server, and set SEND_NO_CONTENTS and
+ BACKUP_MODIFIED_FILES flags before calling send_files().
+
+ (update_fileproc): if file is modified and toss_local_changes is
+ set, then back the file up and then check out a fresh copy from
+ the repository. Also, fixed indentation and formatting for a
+ particularly bad stretch of code near (but unrelated to) these
+ changes.
+
+ * sanity.sh: new test `clean', for update -C option.
+
+1999-12-29 Jim Kingdon <http://developer.redhat.com/>
+
+ * history.c (read_hrecs): st_blksize is unsigned long, not int.
+ This isn't just cosmetic - getting it wrong will cause coredumps
+ and such on 64 bit machines.
+
+ * import.c (import_descend), ignore.c (ignore_files): Placate gcc
+ -Wall by parenthesizing foo || (bar && baz).
+
+1999-12-24 Larry Jones <larry.jones@sdrc.com>
+
+ * release.c (release): Use fputs to echo lines from update instead
+ of printf to avoid problems with lines containing "%". (Reported
+ by Jean-Luc Simard <Jean-Luc.Simard@matrox.com>.)
+
+ * history.c (read_hrecs): Allocate a single 2-block buffer instead
+ of allocating and freeing a buffer for each block.
+ (fill_hrec): Remove redundant code.
+ (select_hrec): Plug memory leak.
+
+1999-12-22 Larry Jones <larry.jones@sdrc.com>
+
+ * history.c (history): For "modified" or "checkout", sort on
+ file if user specified -l, even if user also specified a date-
+ oriented flag.
+ * sanity.sh (history): Update to match; add new tests.
+
+1999-12-15 Pavel Roskin <pavel_roskin@geocities.com>
+ and Larry Jones <larry.jones@sdrc.com>
+
+ * lock.c (lock_name): fixed assertion failure for the
+ top-level CVS directory when LockDir is used
+ * sanity.sh (lockfiles-9): new test for this case
+
+1999-12-11 Karl Fogel <kfogel@red-bean.com>
+
+ * Revert previous change -- it doesn't work remotely yet.
+
+1999-12-10 John P Cavanaugh <cavanaug@sr.hp.com>
+ and Karl Fogel <kfogel@red-bean.com>
+
+ * update.c: new -C option to update, overwrites local changes with
+ clean copies from the repository.
+ Also, fixed indentation and formatting for a particularly bad
+ stretch of code near these changes in update_fileproc().
+
+ * sanity.sh: test new update -C option.
+
+1999-12-10 Larry Jones <larry.jones@sdrc.com>
+
+ * commit.c (remove_file): Call history_write with update_dir NULL
+ like Checkin() does for add and modify.
+ * sanity.sh (basic2-64): Update to match, add "R" records to expected
+ remote output.
+
+1999-12-09 K.J. Paradise (kj@sourcegear.com)
+
+ * history.c, commit.c, sanity.sh: found (I think) final
+ cause of seg fault in history command. Also, added the "R"
+ history functionality. Fixed basic2-64 so it looks correct for
+ the change.
+
+1999-11-30 K.J. Paradise (kj@sourcegear.com)
+
+ * history.c: fixed seg fault caused by 11-03 changes.
+ off by one in block memory allocations.
+
+1999-11-29 Karl Fogel <kfogel@red-bean.com>
+
+ * login.c (logout): free `tmp_name' when done.
+ Correct a comment.
+
+1999-11-29 Larry Jones <larry.jones@sdrc.com>
+
+ * cvs.h, error.c, import.c: Rename fperror to avoid name clash
+ on LynxOS. (Reported by Markus Braun <MarkusBraun@gmx.de>.)
+
+1999-11-23 Larry Jones <larry.jones@sdrc.com>
+
+ * checkout.c (checkout_proc): Split declaration and initialization
+ of rp to placate neurotic compilers that gripe about jumping past
+ an initialization, even when the variable is not subsequently used.
+
+1999-11-19 Larry Jones <larry.jones@sdrc.com>
+
+ * server.c (switch_to_user): Correct setgid error messages.
+
+1999-11-19 Karl Fogel <kfogel@red-bean.com>
+
+ * edit.c (unedit_usage, unedit): new struct, use it. Now "cvs
+ unedit" prints an accurate usage message (formerly it printed the
+ message for "cvs edit", even though the two commands do not have
+ identical usages).
+
+1999-11-19 Larry Jones <larry.jones@sdrc.com>
+
+ * history.c: Move -e documentation from Flags to Reports.
+ (history): Add -e to list of report types in error message.
+
+ * history.c (history): Process file arguments before client/server
+ processing so they get sent to the server.
+ * sanity.sh (history): New tests for above. (Also remove comments
+ about variable spacing -- history output is in variable-width
+ columns with exactly one space between.)
+
+1999-11-19 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh: Reestablish check for running as root (using ``id -u''
+ instead of ``whoami'').
+
+ * sanity.sh(dotest, dotest_lit, dotest_fail, dotest_status,
+ dotest_sort): Eval the command so quoting and pipes work right.
+ (spacefiles, dirs, rcslib, modules, unedit-without-baserev,
+ ignore, rcs, rcs2, history, tagdate, pserver, server, server2)
+ Simplify various tests based on above.
+
+1999-11-19 Karl Fogel <kfogel@red-bean.com>
+
+ * mkmodules.c (init): make history file world-writeable after
+ creating it, since it needs to be writeable for virtually any
+ CVS operation.
+
+1999-11-10 Jim Kingdon <http://developer.redhat.com/>
+
+ * admin.c: Revert change to add -H command option. The help
+ invocation is "cvs -H admin" not "cvs admin -H" (see cvs.texinfo,
+ basicb-21 in sanity.sh; fix to cvs.1)
+
+1999-11-08 Jim Kingdon <http://developer.redhat.com/>
+
+ * log.c (cvslog): If client_active, send options to the server
+ based on our parsed options rather than trying to send the exact
+ strings specified (using canonical forms, like RFC822/1123
+ dates, in the protocol is just cleaner).
+ (send_one, send_arg_list): New functions, helpers for above.
+ * sanity.sh (logopt-6a): New test, for this fix.
+
+1999-11-09 K.J. Paradise <kj@sourcegear.com>
+
+ * admin.c: made the -H option do what it is documented to
+ do. a
+
+1999-11-08 Tom Tromey <tromey@cygnus.com>
+
+ * client.c (connect_to_gserver): Print more error text if gssapi
+ initialization fails. From Assar Westerlund <assar@sics.se>.
+
+1999-11-06 Larry Jones <larry.jones@sdrc.com>
+
+ *sanity.sh(rcs3-5): Remote output can be out-of-order, so need a
+ more general pattern to match the assertion failure.
+
+1999-11-05 K.J. Paradise (kj@sourcegear.com)
+
+ * history.c: Added a trap to verify that if a
+ read(file, buffer,blocksize) returns less than blocksize,
+ that we really are at the end of the file. I can't easily
+ come up with a test case where this code gets touched, so
+ it may cause problems. All sanity tests still pass though.
+
+1999-11-05 Jim Kingdon <http://developer.redhat.com/>
+
+ * sanity.sh (logopt): New test, for Larry's fix.
+ * sanity.sh (log-18a, rcs-15 to rcs-19): New tests, to test -d
+ and -r more thoroughly.
+
+1999-11-05 Larry Jones <larry.jones@sdrc.com>
+
+ * log.c (cvslog): Fix -s and -d with spaces on client side.
+ (log_usage): Revert Karl's change once again.
+ sanity.sh(rcs3-5): No longer get different results from local
+ and client/server.
+
+1999-11-04 Karl Fogel <kfogel@red-bean.com>
+
+ * log.c (log_usage): Revert Jim Kingdon's reversion of my change
+ of 1999-11-03. Allowing a space between option and argument
+ results in lossage; here is a reproduction recipe: run this from
+ the top of a remote copy of the cvs source tree
+
+ cvs log -d '>1999-03-01' > log-out.with-space
+
+ and then run this (note there's no space after -d now):
+
+ cvs log -d'>1999-03-01' > log-out.no-space
+
+ The resulting files differ; furthermore, a glance at the output of
+ cvs shows that the first command failed to recurse into
+ subdirectories. Until this misbehavior can be fixed in the source
+ code, the documentation should reflect the true state of affairs:
+ if one simply omits the space, everything works fine.
+
+1999-11-04 Jim Kingdon <http://developer.redhat.com/>
+
+ * log.c (log_usage): Revert Karl's change regarding -d and
+ -s. A space is allowed (see sanity.sh for example).
+
+1999-11-03 K.J. Paradise (kj@sourcegear.com>
+
+ * history.c: cleaned up my prior change a bit, per Larry Jones'
+ comments, and John O'Conner's additional comments about bits of
+ non MS-Visual C++ compliancy of my code.
+
+1999-11-04 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh: Check that tr that correctly handles NULs; if not, try
+ to find a version that does; if none can be found, warn user.
+ Also fix warnings for defective expr.
+
+1999-11-04 Karl Fogel <kfogel@red-bean.com>
+
+ Changes for empty/random passwords in anon pserver access:
+
+ * server.c (check_repository_password): if password empty, grant
+ access no matter what password is received; this is so anon CVS no
+ longer requires a password but remains backwards-compatible with
+ all those clients out there.
+
+ * client.c (connect_to_pserver): proceed with login even if
+ password not found in .cvspass file -- just use empty string as
+ password. And if such a login fails, print a descriptive error.
+
+ * login.c (get_cvs_password): don't complain if file or password
+ not found. That condition is no longer a showstopper, now that
+ empty passwords are permissible.
+ Cleaned up conditional chaining a bit, too.
+
+ * sanity.sh (pserver-9, pserver-10, pserver-11, pserver-12,
+ pserver-13): new tests, about empty-password pserver access.
+
+1999-11-03 K.J. Paradise (kj@sourcegear.com>
+
+ * history.c: modify parsing routines to parse the history
+ file a block at a time, rather than all at once. This allows
+ people with large history files and small amount of memory
+ to still get some functionality out of the history file.
+
+1999-11-03 Karl Fogel <kfogel@red-bean.com>
+
+ * log.c (log_usage): correct usage message for -d and -s options.
+ Because the space between the option letter and its argument has
+ been eliminated, I capitalized the argument portion to distinguish
+ it from the option letter. This makes it slightly inconsistent
+ with other such usage summaries, but at least it is now both
+ correct and readable.
+
+1999-10-22 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (dotest_sort): Old versions of tr don't understand \t
+ so use a literal tab instead.
+
+1999-10-21 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (dotest_sort): Convert any tabs in the output into spaces
+ before sorting to avoid POSIX.2 sort weirdness.
+ (import-106, importb-2): Change expected output per above.
+
+1999-10-18 K.J. Paradise <kj@sourcegear.com>
+
+ Bug: users 'stan' and 'cartman' both have full read/write access
+ to the cvs repository. 'cartman' does a 'cvs admin -l foo.c'.
+ 'stan' then does a 'cvs admin -u foo.c'. The lock wouldn't be
+ removed, and no warning/error would be given. This is now fixed.
+ * rcs.c:(c.6157) remove caller/user check on the multiple lock
+ detection routines. Sanity.sh runs with no errors after this fix.
+
+1999-10-14 Larry Jones <larry.jones@sdrc.com>
+
+ Make "cvs admin -e" (with no list of users) work:
+ * admin.c (admin): Remove error message.
+ (admin_fileproc): If no args for -e, call RCS_delaccess with NULL user.
+ * rcs.c (RCS_delaccess): Interpret NULL user as request to delete
+ entire access list.
+ * sanity.sh (admin-19a-*): Test.
+
+1999-09-29 Larry Jones <larry.jones@sdrc.com>
+
+ * entries.c (Subdirs_Known): Use entfilename when opening CVSADM_ENTLOG
+ like everywhere else. Although this isn't strictly necessary (since
+ we immediately close it again), it keeps the code consistent and fixes
+ a bug where an open error reported the wrong file name.
+
+1999-09-16 Larry Jones <larry.jones@sdrc.com>
+
+ * log.c (log_parse_revlist): Handle peculiar revision specs like
+ "-r.", "-r:", and "-r," correctly. (Thanks to Pavel Roskin
+ <pavel_roskin@geocities.com> for submitting a patch, this fix is
+ somewhat different.)
+ * sanity.sh (log): New tests for above.
+
+1999-09-15 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (basica-8b1): New test to check fix for bad diff options
+ causing cvs to crash.
+
+1999-09-02 Larry Jones <larry.jones@sdrc.com>
+
+ * modules.c (do_module): Handle case where module definition has
+ options and special options but no directory; fix potential problems
+ running off beginning of string while stripping trailing blanks.
+ * sanity.sh (modules2): New tests for above.
+
+1999-08-26 Larry Jones <larry.jones@sdrc.com>
+
+ * lock.c (lock_name): Remove side-effects from assert() expression
+ since they won't occur if NDEBUG is defined (not that that's a good
+ thing to do). (Reported by KOIE Hidetaka <hide@koie.org>.)
+
+1999-08-25 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh: Use "${AWK}" instead of "awk" to make it easier for
+ people to use nawk/gawk/etc.; use an explicit "-print" with find
+ since some older version don't assume it; rename tests to avoid
+ duplicate importc-8. (Changes along these lines suggested by
+ Chris Cameron <chris.cameron@ot.co.nz>.)
+
+1999-08-24 Larry Jones <larry.jones@sdrc.com>
+
+ * commit.c (check_fileproc): Don't crash when a file has no
+ repository, just treat it as unknown. (Reported by Stefaan
+ Diericx <stefaan.diericx@argenta.be>.)
+ * sanity.sh (errmsg2): New tests, for this fix.
+
+1999-08-18 Larry Jones <larry.jones@sdrc.com>
+
+ * update.c (special_file_mismatch): Initialize *_hardlinks to
+ avoid trying to free garbage later on. (Reported by Jan
+ Scheffczyk <herta@Xterminator.StudFB.UniBw-Muenchen.de>.)
+
+1999-08-17 Larry Jones <larry.jones@sdrc.com>
+
+ * sanity.sh (basicc-11): Older versions of sh don't understand
+ ``if ! test...''. (Patch submitted by David J N Begley
+ <david@avarice.nepean.uws.edu.au>.)
+
+1999-08-17 Larry Jones <larry.jones@sdrc.com>
+
+ * client.c, hardlink.c, hash.c, hash.h, main.c, recurse.c: Change
+ enum constant UNKNOWN to avoid conflicts on HPUX 11.0. (Reported
+ by Laurent Duperval <laurent.duperval@cgi.ca>.)
+
+1999-08-16 Larry Jones <larry.jones@sdrc.com>
+
+ client.c: Eliminate redundant #if. (Patch submitted by Assar
+ Westerlund <assar@sics.se>.)
+
+1999-07-30 Larry Jones <larry.jones@sdrc.com>
+
+ * rcs.c (RCS_checkin): Terminate cleanly if RCS_addbranch fails
+ rather than blithely continuing on and crashing.
+ * sanity.sh (basica): New tests, for this fix.
+
+1999-07-29 Larry Jones <larry.jones@sdrc.com>
+
+ * import.c (add_rcs_file): change "cannot lstat" message to include
+ userfile (the actual file causing the problem) instead of user
+ (which may or may not be the same).
+
+1999-07-29 Eric Sink <eric@sourcegear.com>
+
+ * version.c: Push version number to 1.10.7.1.
+
+ * version.c: Version 1.10.7.
+
1999-07-28 Eric Sink <eric@sourcegear.com>
* sanity.sh: before running basicc-11, we need to see if
diff --git a/contrib/cvs/src/Makefile.in b/contrib/cvs/src/Makefile.in
index 7cbdca7..d09b0cb 100644
--- a/contrib/cvs/src/Makefile.in
+++ b/contrib/cvs/src/Makefile.in
@@ -22,13 +22,13 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
# Where to install the executables.
-bindir = $(exec_prefix)/bin
+bindir = @bindir@
# Where to put the system-wide .cvsrc file
-libdir = $(prefix)/lib
+libdir = @libdir@
# Where to put the manual pages.
-mandir = $(prefix)/man
+mandir = @mandir@
# Use cp if you don't have install.
INSTALL = @INSTALL@
diff --git a/contrib/cvs/src/add.c b/contrib/cvs/src/add.c
index db1f527..dbefda5 100644
--- a/contrib/cvs/src/add.c
+++ b/contrib/cvs/src/add.c
@@ -59,6 +59,7 @@ add (argc, argv)
/* Nonzero if we found a slash, and are thus adding files in a
subdirectory. */
int found_slash = 0;
+ size_t cvsroot_len;
if (argc == 1 || argc == -1)
usage (add_usage);
@@ -92,6 +93,8 @@ add (argc, argv)
if (argc <= 0)
usage (add_usage);
+ cvsroot_len = strlen (CVSroot_directory);
+
/* First some sanity checks. I know that the CVS case is (sort of)
also handled by add_directory, but we need to check here so the
client won't get all confused in send_file_names. */
@@ -157,7 +160,11 @@ add (argc, argv)
start_server ();
ign_setup ();
- if (options) send_arg(options);
+ if (options)
+ {
+ send_arg (options);
+ free (options);
+ }
option_with_arg ("-m", message);
/* If !found_slash, refrain from sending "Directory", for
@@ -219,6 +226,17 @@ add (argc, argv)
/* find the repository associated with our current dir */
repository = Name_Repository (NULL, update_dir);
+ /* don't add stuff to Emptydir */
+ if (strncmp (repository, CVSroot_directory, cvsroot_len) == 0
+ && ISDIRSEP (repository[cvsroot_len])
+ && strncmp (repository + cvsroot_len + 1,
+ CVSROOTADM,
+ sizeof CVSROOTADM - 1) == 0
+ && ISDIRSEP (repository[cvsroot_len + sizeof CVSROOTADM])
+ && strcmp (repository + cvsroot_len + sizeof CVSROOTADM + 1,
+ CVSNULLREPOS) == 0)
+ error (1, 0, "cannot add to %s", repository);
+
/* before we do anything else, see if we have any
per-directory tags */
ParseTag (&tag, &date, &nonbranch);
@@ -227,7 +245,7 @@ add (argc, argv)
sprintf (rcsdir, "%s/%s", repository, p);
Create_Admin (p, argv[i], rcsdir, tag, date,
- nonbranch, 0);
+ nonbranch, 0, 1);
if (found_slash)
send_a_repository ("", repository, update_dir);
@@ -304,6 +322,17 @@ add (argc, argv)
/* Find the repository associated with our current dir. */
repository = Name_Repository (NULL, finfo.update_dir);
+ /* don't add stuff to Emptydir */
+ if (strncmp (repository, CVSroot_directory, cvsroot_len) == 0
+ && ISDIRSEP (repository[cvsroot_len])
+ && strncmp (repository + cvsroot_len + 1,
+ CVSROOTADM,
+ sizeof CVSROOTADM - 1) == 0
+ && ISDIRSEP (repository[cvsroot_len + sizeof CVSROOTADM])
+ && strcmp (repository + cvsroot_len + sizeof CVSROOTADM + 1,
+ CVSNULLREPOS) == 0)
+ error (1, 0, "cannot add to %s", repository);
+
entries = Entries_Open (0, NULL);
finfo.repository = repository;
@@ -619,6 +648,8 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname);
if (message)
free (message);
+ if (options)
+ free (options);
return (err);
}
@@ -769,10 +800,8 @@ add_directory (finfo)
#ifdef SERVER_SUPPORT
if (!server_active)
- Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0);
-#else
- Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0);
#endif
+ Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0, 1);
if (tag)
free (tag);
if (date)
diff --git a/contrib/cvs/src/admin.c b/contrib/cvs/src/admin.c
index c5af96e..637663a 100644
--- a/contrib/cvs/src/admin.c
+++ b/contrib/cvs/src/admin.c
@@ -22,7 +22,45 @@ static int admin_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static const char *const admin_usage[] =
{
- "Usage: %s %s rcs-options files...\n",
+ "Usage: %s %s [options] files...\n",
+ "\t-a users Append (comma-separated) user names to access list.\n",
+ "\t-A file Append another file's access list.\n",
+ "\t-b[rev] Set default branch (highest branch on trunk if omitted).\n",
+ "\t-c string Set comment leader.\n",
+ "\t-e[users] Remove (comma-separated) user names from access list\n",
+ "\t (all names if omitted).\n",
+ "\t-I Run interactively.\n",
+ "\t-k subst Set keyword substitution mode:\n",
+ "\t kv (Default) Substitue keyword and value.\n",
+ "\t kvl Substitue keyword, value, and locker (if any).\n",
+ "\t k Substitue keyword only.\n",
+ "\t o Preserve original string.\n",
+ "\t b Like o, but mark file as binary.\n",
+ "\t v Substitue value only.\n",
+ "\t-l[rev] Lock revision (latest revision on branch,\n",
+ "\t latest revision on trunk if omitted).\n",
+ "\t-L Set strict locking.\n",
+ "\t-m rev:msg Replace revision's log message.\n",
+ "\t-n tag[:[rev]] Tag branch or revision. If :rev is omitted,\n",
+ "\t delete the tag; if rev is omitted, tag the latest\n",
+ "\t revision on the default branch.\n",
+ "\t-N tag[:[rev]] Same as -n except override existing tag.\n",
+ "\t-o range Delete (outdate) specified range of revisions:\n",
+ "\t rev1::rev2 Between rev1 and rev2, excluding rev1 and rev2.\n",
+ "\t rev:: After rev on the same branch.\n",
+ "\t ::rev Before rev on the same branch.\n",
+ "\t rev Just rev.\n",
+ "\t rev1:rev2 Between rev1 and rev2, including rev1 and rev2.\n",
+ "\t rev: rev and following revisions on the same branch.\n",
+ "\t :rev rev and previous revisions on the same branch.\n",
+ "\t-q Run quietly.\n",
+ "\t-s state[:rev] Set revision state (latest revision on branch,\n",
+ "\t latest revision on trunk if omitted).\n",
+ "\t-t[file] Get descriptive text from file (stdin if omitted).\n",
+ "\t-t-string Set descriptive text.\n",
+ "\t-u[rev] Unlock the revision (latest revision on branch,\n",
+ "\t latest revision on trunk if omitted).\n",
+ "\t-U Unset strict locking.\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
@@ -53,9 +91,7 @@ struct admin_data
/* Keyword substitution mode (-k), e.g. "-kb". */
char *kflag;
- /* Description (-t). See sanity.sh for various moanings about
- files and stdin and such. "" if -t specified without an
- argument. It is "-t" followed by the argument. */
+ /* Description (-t). */
char *desc;
/* Interactive (-I). Problematic with client/server. */
@@ -191,11 +227,6 @@ admin (argc, argv)
break;
case 'e':
- if (optarg == NULL)
- {
- error (1, 0,
- "removing entire access list not yet implemented");
- }
arg_add (&admin_data, 'e', optarg);
break;
@@ -287,13 +318,15 @@ admin (argc, argv)
error (0, 0, "duplicate 't' option");
goto usage_error;
}
- if (optarg == NULL)
- admin_data.desc = xstrdup ("-t");
+ if (optarg != NULL && optarg[0] == '-')
+ admin_data.desc = xstrdup (optarg + 1);
else
{
- admin_data.desc = xmalloc (strlen (optarg) + 5);
- strcpy (admin_data.desc, "-t");
- strcat (admin_data.desc, optarg);
+ size_t bufsize = 0;
+ size_t len;
+
+ get_file (optarg, optarg, "r", &admin_data.desc,
+ &bufsize, &len);
}
break;
@@ -417,7 +450,26 @@ admin (argc, argv)
if (admin_data.delete_revs != NULL)
send_arg (admin_data.delete_revs);
if (admin_data.desc != NULL)
- send_arg (admin_data.desc);
+ {
+ char *p = admin_data.desc;
+ send_to_server ("Argument -t-", 0);
+ while (*p)
+ {
+ if (*p == '\n')
+ {
+ send_to_server ("\012Argumentx ", 0);
+ ++p;
+ }
+ else
+ {
+ char *q = strchr (p, '\n');
+ if (q == NULL) q = p + strlen (p);
+ send_to_server (p, q - p);
+ p = q;
+ }
+ }
+ send_to_server ("\012", 1);
+ }
if (admin_data.quiet)
send_arg ("-q");
if (admin_data.kflag != NULL)
@@ -598,20 +650,7 @@ admin_fileproc (callerdat, finfo)
if (admin_data->desc != NULL)
{
free (rcs->desc);
- rcs->desc = NULL;
- if (admin_data->desc[2] == '-')
- rcs->desc = xstrdup (admin_data->desc + 3);
- else
- {
- char *descfile = admin_data->desc + 2;
- size_t bufsize = 0;
- size_t len;
-
- /* If -t specified with no argument, read from stdin. */
- if (*descfile == '\0')
- descfile = NULL;
- get_file (descfile, descfile, "r", &rcs->desc, &bufsize, &len);
- }
+ rcs->desc = xstrdup (admin_data->desc);
}
if (admin_data->kflag != NULL)
{
@@ -642,6 +681,8 @@ admin_fileproc (callerdat, finfo)
if (arg[1] == 'a')
for (u = 0; u < argc; ++u)
RCS_addaccess (rcs, users[u]);
+ else if (argc == 0)
+ RCS_delaccess (rcs, NULL);
else
for (u = 0; u < argc; ++u)
RCS_delaccess (rcs, users[u]);
@@ -748,20 +789,24 @@ admin_fileproc (callerdat, finfo)
rev = xstrdup (p);
}
revnum = RCS_gettag (rcs, rev, 0, NULL);
- free (rev);
if (revnum != NULL)
+ {
n = findnode (rcs->versions, revnum);
- if (revnum == NULL || n == NULL)
+ free (revnum);
+ }
+ else
+ n = NULL;
+ if (n == NULL)
{
error (0, 0,
"%s: can't set state of nonexisting revision %s",
rcs->path,
rev);
- if (revnum != NULL)
- free (revnum);
+ free (rev);
status = 1;
continue;
}
+ free (rev);
delta = (RCSVers *) n->data;
free (delta->state);
delta->state = tag;
@@ -788,6 +833,7 @@ admin_fileproc (callerdat, finfo)
msg = p;
n = findnode (rcs->versions, rev);
+ free (rev);
delta = (RCSVers *) n->data;
if (delta->text == NULL)
{
@@ -823,12 +869,7 @@ admin_fileproc (callerdat, finfo)
additional message is to make it clear that the previous problems
caused CVS to forget about the idea of modifying the RCS file. */
error (0, 0, "cannot modify RCS file for `%s'", finfo->file);
-
- /* Upon failure, we want to abandon any changes made to the
- RCS data structure. Forcing a reparse does the trick,
- but leaks memory and is kludgey. Should we export
- free_rcsnode_contents for this purpose? */
- RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
+ RCS_abandon (rcs);
}
exitfunc:
diff --git a/contrib/cvs/src/checkout.c b/contrib/cvs/src/checkout.c
index a7d942f..1a66b5b 100644
--- a/contrib/cvs/src/checkout.c
+++ b/contrib/cvs/src/checkout.c
@@ -37,11 +37,10 @@
#include "cvs.h"
static char *findslash PROTO((char *start, char *p));
-static int checkout_proc PROTO((int *pargc, char **argv, char *where,
+static int checkout_proc PROTO((int argc, char **argv, char *where,
char *mwhere, char *mfile, int shorten,
int local_specified, char *omodule,
char *msg));
-static int safe_location PROTO((void));
static const char *const checkout_usage[] =
{
@@ -95,6 +94,7 @@ static char *join_rev2 = NULL;
static int join_tags_validated = 0;
static char *preload_update_dir = NULL;
static char *history_name = NULL;
+static enum mtype m_type;
int
checkout (argc, argv)
@@ -111,7 +111,6 @@ checkout (argc, argv)
char *where = NULL;
char *valid_options;
const char *const *valid_usage;
- enum mtype m_type;
/*
* A smaller subset of options are allowed for the export command, which
@@ -233,7 +232,7 @@ checkout (argc, argv)
if (where && pipeout)
error (1, 0, "-d and -p are mutually exclusive");
- if (strcmp (command_name, "export") == 0)
+ if (m_type == EXPORT)
{
if (!tag && !date)
error (1, 0, "must specify a tag or date");
@@ -294,7 +293,7 @@ checkout (argc, argv)
send_arg("-A");
if (!shorten)
send_arg("-N");
- if (checkout_prune_dirs && strcmp (command_name, "export") != 0)
+ if (checkout_prune_dirs && m_type == CHECKOUT)
send_arg("-P");
client_prune_dirs = checkout_prune_dirs;
if (cat)
@@ -325,10 +324,7 @@ checkout (argc, argv)
client_nonexpanded_setup ();
}
- send_to_server (strcmp (command_name, "export") == 0 ?
- "export\012" : "co\012",
- 0);
-
+ send_to_server (m_type == EXPORT ? "export\012" : "co\012", 0);
return get_responses_and_close ();
}
#endif /* CLIENT_SUPPORT */
@@ -355,7 +351,7 @@ checkout (argc, argv)
/* If we will be calling history_write, work out the name to pass
it. */
- if (strcmp (command_name, "export") != 0 && !pipeout)
+ if (m_type == CHECKOUT && !pipeout)
{
if (tag && date)
{
@@ -379,7 +375,10 @@ checkout (argc, argv)
return (err);
}
-static int
+/* FIXME: This is and emptydir_name are in checkout.c for historical
+ reasons, probably want to move them. */
+
+int
safe_location ()
{
char *current;
@@ -455,7 +454,12 @@ build_one_dir (repository, dirpath, sticky)
{
FILE *fp;
- if (!isfile (CVSADM) && strcmp (command_name, "export") != 0)
+ if (isfile (CVSADM))
+ {
+ if (m_type == EXPORT)
+ error (1, 0, "cannot export into a working directory");
+ }
+ else if (m_type == CHECKOUT)
{
/* I suspect that this check could be omitted. */
if (!isdir (repository))
@@ -471,7 +475,7 @@ build_one_dir (repository, dirpath, sticky)
then rewrite it later via WriteTag, once
we've had a chance to call RCS_nodeisbranch
on each file. */
- 0, 1))
+ 0, 1, 1))
return;
if (!noexec)
@@ -492,9 +496,9 @@ build_one_dir (repository, dirpath, sticky)
*/
/* ARGSUSED */
static int
-checkout_proc (pargc, argv, where_orig, mwhere, mfile, shorten,
+checkout_proc (argc, argv, where_orig, mwhere, mfile, shorten,
local_specified, omodule, msg)
- int *pargc;
+ int argc;
char **argv;
char *where_orig;
char *mwhere;
@@ -504,6 +508,7 @@ checkout_proc (pargc, argv, where_orig, mwhere, mfile, shorten,
char *omodule;
char *msg;
{
+ char *myargv[2];
int err = 0;
int which;
char *cp;
@@ -665,26 +670,10 @@ checkout_proc (pargc, argv, where_orig, mwhere, mfile, shorten,
{
/* It's a file, which means we have to screw around with
argv. */
-
- int i;
-
-
- /* Paranoia check. */
-
- if (*pargc > 1)
- {
- error (0, 0, "checkout_proc: trashing argv elements!");
- for (i = 1; i < *pargc; i++)
- {
- error (0, 0, "checkout_proc: argv[%d] `%s'",
- i, argv[i]);
- }
- }
-
- for (i = 1; i < *pargc; i++)
- free (argv[i]);
- argv[1] = xstrdup (mfile);
- (*pargc) = 2;
+ myargv[0] = argv[0];
+ myargv[1] = mfile;
+ argc = 2;
+ argv = myargv;
}
free (path);
}
@@ -745,7 +734,7 @@ internal error: %s doesn't start with %s in checkout_proc",
NT, &c, if the user specifies '\'. Likewise for the call
to findslash. */
cp = where + strlen (where);
- while (1)
+ while (cp > where)
{
struct dir_to_build *new;
@@ -761,7 +750,7 @@ internal error: %s doesn't start with %s in checkout_proc",
last path element we create should be the top-level
directory. */
- if (cp - where)
+ if (cp > where)
{
strncpy (new->dirpath, where, cp - where);
new->dirpath[cp - where] = '\0';
@@ -769,7 +758,7 @@ internal error: %s doesn't start with %s in checkout_proc",
else
{
/* where should always be at least one character long. */
- assert (strlen (where));
+ assert (where[0] != '\0');
strcpy (new->dirpath, "/");
}
new->next = head;
@@ -841,10 +830,11 @@ internal error: %s doesn't start with %s in checkout_proc",
{
/* It's a directory in the repository! */
- char *rp = strrchr (reposcopy, '/');
+ char *rp;
/* We'll always be below CVSROOT, but check for
paranoia's sake. */
+ rp = strrchr (reposcopy, '/');
if (rp == NULL)
error (1, 0,
"internal error: %s doesn't contain a slash",
@@ -890,7 +880,7 @@ internal error: %s doesn't start with %s in checkout_proc",
{
/* It may be argued that we shouldn't set any sticky
bits for the top-level repository. FIXME? */
- build_one_dir (CVSroot_directory, ".", *pargc <= 1);
+ build_one_dir (CVSroot_directory, ".", argc <= 1);
#ifdef SERVER_SUPPORT
/* We _always_ want to have a top-level admin
@@ -912,7 +902,7 @@ internal error: %s doesn't start with %s in checkout_proc",
contain a CVS subdir yet, but all the others contain
CVS and Entries.Static files */
- if (build_dirs_and_chdir (head, *pargc <= 1) != 0)
+ if (build_dirs_and_chdir (head, argc <= 1) != 0)
{
error (0, 0, "ignoring module %s", omodule);
err = 1;
@@ -925,14 +915,15 @@ internal error: %s doesn't start with %s in checkout_proc",
{
FILE *fp;
- if (!noexec && *pargc > 1)
+ if (!noexec && argc > 1)
{
/* I'm not sure whether this check is redundant. */
if (!isdir (repository))
error (1, 0, "there is no repository %s", repository);
Create_Admin (".", preload_update_dir, repository,
- (char *) NULL, (char *) NULL, 0, 0);
+ (char *) NULL, (char *) NULL, 0, 0,
+ m_type == CHECKOUT);
fp = open_file (CVSADM_ENTSTAT, "w+");
if (fclose(fp) == EOF)
error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
@@ -955,13 +946,16 @@ internal error: %s doesn't start with %s in checkout_proc",
then rewrite it later via WriteTag, once
we've had a chance to call RCS_nodeisbranch
on each file. */
- 0, 0);
+ 0, 0, m_type == CHECKOUT);
}
}
else
{
char *repos;
+ if (m_type == EXPORT)
+ error (1, 0, "cannot export into working directory");
+
/* get the contents of the previously existing repository */
repos = Name_Repository ((char *) NULL, preload_update_dir);
if (fncmp (repository, repos) != 0)
@@ -993,7 +987,7 @@ internal error: %s doesn't start with %s in checkout_proc",
which = W_REPOS;
if (tag != NULL && !tag_validated)
{
- tag_check_valid (tag, *pargc - 1, argv + 1, 0, aflag, NULL);
+ tag_check_valid (tag, argc - 1, argv + 1, 0, aflag, NULL);
tag_validated = 1;
}
}
@@ -1002,7 +996,7 @@ internal error: %s doesn't start with %s in checkout_proc",
which = W_LOCAL | W_REPOS;
if (tag != NULL && !tag_validated)
{
- tag_check_valid (tag, *pargc - 1, argv + 1, 0, aflag,
+ tag_check_valid (tag, argc - 1, argv + 1, 0, aflag,
repository);
tag_validated = 1;
}
@@ -1014,10 +1008,10 @@ internal error: %s doesn't start with %s in checkout_proc",
if (! join_tags_validated)
{
if (join_rev1 != NULL)
- tag_check_valid_join (join_rev1, *pargc - 1, argv + 1, 0, aflag,
+ tag_check_valid_join (join_rev1, argc - 1, argv + 1, 0, aflag,
repository);
if (join_rev2 != NULL)
- tag_check_valid_join (join_rev2, *pargc - 1, argv + 1, 0, aflag,
+ tag_check_valid_join (join_rev2, argc - 1, argv + 1, 0, aflag,
repository);
join_tags_validated = 1;
}
@@ -1027,12 +1021,12 @@ internal error: %s doesn't start with %s in checkout_proc",
* update recursion processor. We will be recursive unless either local
* only was specified, or we were passed arguments
*/
- if (!(local_specified || *pargc > 1))
+ if (!(local_specified || argc > 1))
{
- if (strcmp (command_name, "export") != 0 && !pipeout)
+ if (m_type == CHECKOUT && !pipeout)
history_write ('O', preload_update_dir, history_name, where,
repository);
- else if (strcmp (command_name, "export") == 0 && !pipeout)
+ else if (m_type == EXPORT && !pipeout)
history_write ('E', preload_update_dir, tag ? tag : date, where,
repository);
err += do_update (0, (char **) NULL, options, tag, date,
@@ -1050,7 +1044,7 @@ internal error: %s doesn't start with %s in checkout_proc",
/* we are only doing files, so register them */
entries = Entries_Open (0, NULL);
- for (i = 1; i < *pargc; i++)
+ for (i = 1; i < argc; i++)
{
char *line;
Vers_TS *vers;
@@ -1087,12 +1081,12 @@ internal error: %s doesn't start with %s in checkout_proc",
}
/* Don't log "export", just regular "checkouts" */
- if (strcmp (command_name, "export") != 0 && !pipeout)
+ if (m_type == CHECKOUT && !pipeout)
history_write ('O', preload_update_dir, history_name, where,
repository);
/* go ahead and call update now that everything is set */
- err += do_update (*pargc - 1, argv + 1, options, tag, date,
+ err += do_update (argc - 1, argv + 1, options, tag, date,
force_tag_match, local_specified, 1 /* update -d */,
aflag, checkout_prune_dirs, pipeout, which, join_rev1,
join_rev2, preload_update_dir);
@@ -1109,15 +1103,13 @@ findslash (start, p)
char *start;
char *p;
{
- while (p >= start && *p != '/')
- p--;
- /* FIXME: indexing off the start of the array like this is *NOT*
- OK according to ANSI, and will break some of the time on certain
- segmented architectures. */
- if (p < start)
- return (NULL);
- else
- return (p);
+ for (;;)
+ {
+ if (*p == '/') return p;
+ if (p == start) break;
+ --p;
+ }
+ return NULL;
}
/* Return a newly malloc'd string containing a pathname for CVSNULLREPOS,
@@ -1185,5 +1177,14 @@ build_dirs_and_chdir (dirs, sticky)
}
out:
+ while (dirs != NULL)
+ {
+ if (dirs->repository != NULL)
+ free (dirs->repository);
+ nextdir = dirs->next;
+ free (dirs->dirpath);
+ free (dirs);
+ dirs = nextdir;
+ }
return retval;
}
diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c
index 748132a..c451b28 100644
--- a/contrib/cvs/src/client.c
+++ b/contrib/cvs/src/client.c
@@ -1,3 +1,5 @@
+/* JT thinks BeOS is worth the trouble. */
+
/* CVS client-related stuff.
This program is free software; you can redistribute it and/or modify
@@ -60,7 +62,6 @@ extern char *strerror ();
#if HAVE_KERBEROS
#define CVS_PORT 1999
-#if HAVE_KERBEROS
#include <krb.h>
extern char *krb_realmofhost ();
@@ -74,8 +75,6 @@ static Key_schedule sched;
#endif /* HAVE_KERBEROS */
-#endif /* HAVE_KERBEROS */
-
#ifdef HAVE_GSSAPI
#ifdef HAVE_GSSAPI_H
@@ -1115,7 +1114,7 @@ call_in_directory (pathname, func, data)
strcpy (r, "/.");
Create_Admin (".", ".", repo, (char *) NULL,
- (char *) NULL, 0, 1);
+ (char *) NULL, 0, 1, 1);
free (repo);
}
@@ -1252,7 +1251,7 @@ warning: server is not creating directories one at a time");
strcpy (r, reposdirname);
Create_Admin (dir, dir, repo,
- (char *)NULL, (char *)NULL, 0, 0);
+ (char *)NULL, (char *)NULL, 0, 0, 1);
free (repo);
b = strrchr (dir, '/');
@@ -1760,6 +1759,7 @@ update_entries (data_arg, ent_list, short_pathname, filename)
}
free (mode_string);
+ free (scratch_entries);
free (entries_line);
/* The Mode, Mod-time, and Checksum responses should not carry
@@ -1847,7 +1847,8 @@ update_entries (data_arg, ent_list, short_pathname, filename)
if (use_gzip)
{
- if (gunzip_and_write (fd, short_pathname, buf, size))
+ if (gunzip_and_write (fd, short_pathname,
+ (unsigned char *) buf, size))
error (1, 0, "aborting due to compression error");
}
else if (write (fd, buf, size) != size)
@@ -2025,6 +2026,8 @@ update_entries (data_arg, ent_list, short_pathname, filename)
free (mode_string);
free (buf);
+ free (scratch_entries);
+ free (entries_line);
return;
}
@@ -2123,8 +2126,8 @@ update_entries (data_arg, ent_list, short_pathname, filename)
if (file_timestamp)
free (file_timestamp);
- free (scratch_entries);
}
+ free (scratch_entries);
free (entries_line);
}
@@ -2490,7 +2493,11 @@ handle_set_checkin_prog (args, len)
{
char *prog;
struct save_prog *p;
+
read_line (&prog);
+ if (strcmp (command_name, "export") == 0)
+ return;
+
p = (struct save_prog *) xmalloc (sizeof (struct save_prog));
p->next = checkin_progs;
p->dir = xstrdup (args);
@@ -2505,7 +2512,11 @@ handle_set_update_prog (args, len)
{
char *prog;
struct save_prog *p;
+
read_line (&prog);
+ if (strcmp (command_name, "export") == 0)
+ return;
+
p = (struct save_prog *) xmalloc (sizeof (struct save_prog));
p->next = update_progs;
p->dir = xstrdup (args);
@@ -2683,7 +2694,7 @@ send_repository (dir, repos, update_dir)
{
Node *n;
n = getnode ();
- n->type = UNKNOWN;
+ n->type = NT_UNKNOWN;
n->key = xstrdup (update_dir);
n->data = NULL;
@@ -3594,19 +3605,15 @@ get_responses_and_close ()
&& waitpid (rsh_pid, (int *) 0, 0) == -1)
error (1, errno, "waiting for process %d", rsh_pid);
+ buf_free (to_server);
+ buf_free (from_server);
server_started = 0;
- /* see if we need to sleep before returning */
+ /* see if we need to sleep before returning to avoid time-stamp races */
if (last_register_time)
{
- time_t now;
-
- for (;;)
- {
- (void) time (&now);
- if (now != last_register_time) break;
- sleep (1); /* to avoid time-stamp races */
- }
+ while (time ((time_t *) NULL) == last_register_time)
+ sleep (1);
}
return errs;
@@ -3774,6 +3781,7 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
int port_number;
struct sockaddr_in client_sai;
struct hostent *hostinfo;
+ char no_passwd = 0; /* gets set if no password found */
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == -1)
@@ -3818,6 +3826,14 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
/* Get the password, probably from ~/.cvspass. */
password = get_cvs_password ();
+
+ /* Send the empty string by default. This is so anonymous CVS
+ access doesn't require client to have done "cvs login". */
+ if (password == NULL)
+ {
+ no_passwd = 1;
+ password = scramble ("");
+ }
/* Announce that we're starting the authorization protocol. */
if (send (sock, begin, strlen (begin), 0) < 0)
@@ -3841,8 +3857,8 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
if (send (sock, end, strlen (end), 0) < 0)
error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
- /* Paranoia. */
- memset (password, 0, strlen (password));
+ /* Paranoia. */
+ memset (password, 0, strlen (password));
}
{
@@ -3935,20 +3951,28 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
return;
rejected:
+ error (0, 0,
+ "authorization failed: server %s rejected access to %s for user %s",
+ CVSroot_hostname, CVSroot_directory, CVSroot_username);
+
+ /* Output a special error message if authentication was attempted
+ with no password -- the user should be made aware that they may
+ have missed a step. */
+ if (no_passwd)
+ {
+ error (0, 0,
+ "used empty password; try \"cvs login\" with a real password");
+ }
+
if (shutdown (sock, 2) < 0)
{
- error (0, 0,
- "authorization failed: server %s rejected access",
- CVSroot_hostname);
- error (1, 0,
+ error (0, 0,
"shutdown() failed (server %s): %s",
CVSroot_hostname,
SOCK_STRERROR (SOCK_ERRNO));
}
- error (1, 0,
- "authorization failed: server %s rejected access",
- CVSroot_hostname);
+ error_exit();
}
#endif /* AUTH_CLIENT_SUPPORT */
@@ -4111,9 +4135,16 @@ connect_to_gserver (sock, hostinfo)
if (stat_maj != GSS_S_COMPLETE && stat_maj != GSS_S_CONTINUE_NEEDED)
{
OM_uint32 message_context;
+ OM_uint32 new_stat_min;
+
+ message_context = 0;
+ gss_display_status (&new_stat_min, stat_maj, GSS_C_GSS_CODE,
+ GSS_C_NULL_OID, &message_context, &tok_out);
+ error (0, 0, "GSSAPI authentication failed: %s",
+ (char *) tok_out.value);
message_context = 0;
- gss_display_status (&stat_min, stat_maj, GSS_C_GSS_CODE,
+ gss_display_status (&new_stat_min, stat_min, GSS_C_MECH_CODE,
GSS_C_NULL_OID, &message_context, &tok_out);
error (1, 0, "GSSAPI authentication failed: %s",
(char *) tok_out.value);
@@ -4137,7 +4168,29 @@ connect_to_gserver (sock, hostinfo)
recv_bytes (sock, cbuf, 2);
need = ((cbuf[0] & 0xff) << 8) | (cbuf[1] & 0xff);
- assert (need <= sizeof buf);
+
+ if (need > sizeof buf)
+ {
+ int got;
+
+ /* This usually means that the server sent us an error
+ message. Read it byte by byte and print it out.
+ FIXME: This is a terrible error handling strategy.
+ However, even if we fix the server, we will still
+ want to do this to work with older servers. */
+ buf[0] = cbuf[0];
+ buf[1] = cbuf[1];
+ got = recv (sock, buf + 2, sizeof buf - 2, 0);
+ if (got < 0)
+ error (1, 0, "recv() from server %s: %s",
+ CVSroot_hostname, SOCK_STRERROR (SOCK_ERRNO));
+ buf[got + 2] = '\0';
+ if (buf[got + 1] == '\n')
+ buf[got + 1] = '\0';
+ error (1, 0, "error from server %s: %s", CVSroot_hostname,
+ buf);
+ }
+
recv_bytes (sock, buf, need);
tok_in.length = need;
}
@@ -4171,7 +4224,7 @@ send_variable_proc (node, closure)
void
start_server ()
{
- int tofd, fromfd;
+ int tofd, fromfd, rootless;
char *log = getenv ("CVS_CLIENT_LOG");
@@ -4350,7 +4403,8 @@ the :server: access method is not supported by this port of CVS");
stored_mode = NULL;
}
- if (strcmp (command_name, "init") != 0)
+ rootless = (strcmp (command_name, "init") == 0);
+ if (!rootless)
{
send_to_server ("Root ", 0);
send_to_server (CVSroot_directory, 0);
@@ -4474,7 +4528,7 @@ the :server: access method is not supported by this port of CVS");
}
}
- if (cvsencrypt)
+ if (cvsencrypt && !rootless)
{
#ifdef ENCRYPTION
/* Turn on encryption before turning on compression. We do
@@ -4521,7 +4575,7 @@ the :server: access method is not supported by this port of CVS");
#endif /* ! ENCRYPTION */
}
- if (gzip_level)
+ if (gzip_level && !rootless)
{
if (supported_request ("Gzip-stream"))
{
@@ -4563,7 +4617,7 @@ the :server: access method is not supported by this port of CVS");
}
}
- if (cvsauthenticate && ! cvsencrypt)
+ if (cvsauthenticate && ! cvsencrypt && !rootless)
{
/* Turn on authentication after turning on compression, so
that we can compress the authentication information. We
@@ -4594,7 +4648,7 @@ the :server: access method is not supported by this port of CVS");
}
#ifdef FILENAMES_CASE_INSENSITIVE
- if (supported_request ("Case"))
+ if (supported_request ("Case") && !rootless)
send_to_server ("Case\012", 0);
#endif
@@ -4964,6 +5018,7 @@ struct send_data
int build_dirs;
int force;
int no_contents;
+ int backup_modified;
};
static int send_fileproc PROTO ((void *callerdat, struct file_info *finfo));
@@ -5085,6 +5140,18 @@ warning: ignoring -k options due to server limitations");
}
else
send_modified (filename, finfo->fullname, vers);
+
+ if (args->backup_modified)
+ {
+ char *bakname;
+ bakname = backup_file (filename, vers->vn_user);
+ /* This behavior is sufficiently unexpected to
+ justify overinformativeness, I think. */
+ if (! really_quiet)
+ printf ("(Locally modified %s moved to %s)\n",
+ filename, bakname);
+ free (bakname);
+ }
}
else
{
@@ -5193,9 +5260,6 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
dir_exists = isdir (cvsadm_name);
free (cvsadm_name);
- /* initialize the ignore list for this directory */
- ignlist = getlist ();
-
/*
* If there is an empty directory (e.g. we are doing `cvs add' on a
* newly-created directory), the server still needs to know about it.
@@ -5211,6 +5275,9 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
char *repos = Name_Repository (dir, update_dir);
send_a_repository (dir, repos, update_dir);
free (repos);
+
+ /* initialize the ignore list for this directory */
+ ignlist = getlist ();
}
else
{
@@ -5235,6 +5302,29 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
return (dir_exists ? R_PROCESS : R_SKIP_ALL);
}
+static int send_dirleave_proc PROTO ((void *, char *, int, char *, List *));
+
+/*
+ * send_dirleave_proc () is called back by the recursion code upon leaving
+ * a directory. All it does is delete the ignore list if it hasn't already
+ * been done (by send_filesdone_proc).
+ */
+/* ARGSUSED */
+static int
+send_dirleave_proc (callerdat, dir, err, update_dir, entries)
+ void *callerdat;
+ char *dir;
+ int err;
+ char *update_dir;
+ List *entries;
+{
+
+ /* Delete the ignore list if it hasn't already been done. */
+ if (ignlist)
+ dellist (&ignlist);
+ return err;
+}
+
/*
* Send each option in a string to the server, one by one.
* This assumes that the options are separated by spaces, for example
@@ -5426,9 +5516,10 @@ send_files (argc, argv, local, aflag, flags)
args.build_dirs = flags & SEND_BUILD_DIRS;
args.force = flags & SEND_FORCE;
args.no_contents = flags & SEND_NO_CONTENTS;
+ args.backup_modified = flags & BACKUP_MODIFIED_FILES;
err = start_recursion
(send_fileproc, send_filesdoneproc,
- send_dirent_proc, (DIRLEAVEPROC)NULL, (void *) &args,
+ send_dirent_proc, send_dirleave_proc, (void *) &args,
argc, argv, local, W_LOCAL, aflag, 0, (char *)NULL, 0);
if (err)
error_exit ();
diff --git a/contrib/cvs/src/client.h b/contrib/cvs/src/client.h
index c323cf3..b4d404a 100644
--- a/contrib/cvs/src/client.h
+++ b/contrib/cvs/src/client.h
@@ -109,6 +109,7 @@ send_files PROTO((int argc, char **argv, int local, int aflag,
#define SEND_BUILD_DIRS 1
#define SEND_FORCE 2
#define SEND_NO_CONTENTS 4
+#define BACKUP_MODIFIED_FILES 8
/* Send an argument to the remote server. */
void
diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c
index c4cbd24..1c1f71c 100644
--- a/contrib/cvs/src/commit.c
+++ b/contrib/cvs/src/commit.c
@@ -263,6 +263,7 @@ find_fileproc (callerdat, finfo)
else
error (0, 0, "use `%s add' to create an entry for %s",
program_name, finfo->fullname);
+ freevers_ts (&vers);
return 1;
}
else if (vers->ts_user != NULL
@@ -284,6 +285,7 @@ find_fileproc (callerdat, finfo)
cases. FIXME: we probably should be printing a message and
returning 1 for many of those cases (but I'm not sure
exactly which ones). */
+ freevers_ts (&vers);
return 0;
}
@@ -421,28 +423,12 @@ commit (argc, argv)
/* some checks related to the "-F logfile" option */
if (logfile)
{
- int n, logfd;
- struct stat statbuf;
+ size_t size = 0, len;
if (saved_message)
error (1, 0, "cannot specify both a message and a log file");
- /* FIXME: Why is this binary? Needs more investigation. */
- if ((logfd = CVS_OPEN (logfile, O_RDONLY | OPEN_BINARY)) < 0)
- error (1, errno, "cannot open log file %s", logfile);
-
- if (fstat(logfd, &statbuf) < 0)
- error (1, errno, "cannot find size of log file %s", logfile);
-
- saved_message = xmalloc (statbuf.st_size + 1);
-
- /* FIXME: Should keep reading until EOF, rather than assuming the
- first read gets the whole thing. */
- if ((n = read (logfd, saved_message, statbuf.st_size + 1)) < 0)
- error (1, errno, "cannot read log message from %s", logfile);
-
- (void) close (logfd);
- saved_message[n] = '\0';
+ get_file (logfile, logfile, "r", &saved_message, &size, &len);
}
#ifdef CLIENT_SUPPORT
@@ -473,11 +459,14 @@ commit (argc, argv)
error (1, 0, "correct above errors first!");
if (find_args.argc == 0)
+ {
/* Nothing to commit. Exit now without contacting the
server (note that this means that we won't print "?
foo" for files which merit it, because we don't know
what is in the CVSROOT/cvsignore file). */
+ dellist (&find_args.ulist);
return 0;
+ }
/* Now we keep track of which files we actually are going to
operate on, and only work with those files in the future.
@@ -583,6 +572,8 @@ commit (argc, argv)
previous versions of client/server CVS, but it probably is a Good
Thing, or at least Not Such A Bad Thing. */
send_file_names (find_args.argc, find_args.argv, 0);
+ free (find_args.argv);
+ dellist (&find_args.ulist);
send_to_server ("ci\012", 0);
err = get_responses_and_close ();
@@ -672,16 +663,11 @@ commit (argc, argv)
Lock_Cleanup ();
dellist (&mulist);
+ /* see if we need to sleep before returning to avoid time-stamp races */
if (last_register_time)
{
- time_t now;
-
- for (;;)
- {
- (void) time (&now);
- if (now != last_register_time) break;
- sleep (1); /* to avoid time-stamp races */
- }
+ while (time ((time_t *) NULL) == last_register_time)
+ sleep (1);
}
return (err);
@@ -794,6 +780,12 @@ check_fileproc (callerdat, finfo)
size_t cvsroot_len = strlen (CVSroot_directory);
+ if (!finfo->repository)
+ {
+ error (0, 0, "nothing known about `%s'", finfo->fullname);
+ return (1);
+ }
+
if (strncmp (finfo->repository, CVSroot_directory, cvsroot_len) == 0
&& ISDIRSEP (finfo->repository[cvsroot_len])
&& strncmp (finfo->repository + cvsroot_len + 1,
@@ -1290,6 +1282,8 @@ commit_fileproc (callerdat, finfo)
{
if (finfo->rcs == NULL)
error (1, 0, "internal error: no parsed RCS file");
+ if (ci->rev)
+ free (ci->rev);
ci->rev = RCS_whatbranch (finfo->rcs, ci->tag);
err = Checkin ('A', finfo, finfo->rcs->path, ci->rev,
ci->tag, ci->options, saved_message);
@@ -1400,6 +1394,8 @@ out:
}
}
}
+ if (SIG_inCrSect ())
+ SIG_endCrSect ();
return (err);
}
@@ -1500,6 +1496,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
cvs_output (": Executing '", 0);
run_print (stdout);
cvs_output ("'\n", 0);
+ cvs_flushout ();
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
free (repos);
}
@@ -1582,8 +1579,10 @@ commit_dirleaveproc (callerdat, dir, err, update_dir, entries)
this being a confusing feature! */
if (err == 0 && write_dirtag != NULL)
{
+ char *repos = Name_Repository (dir, update_dir);
WriteTag (NULL, write_dirtag, NULL, write_dirnonbranch,
- update_dir, Name_Repository (dir, update_dir));
+ update_dir, repos);
+ free (repos);
}
return (err);
@@ -1751,6 +1750,9 @@ remove_file (finfo, tag, message)
"failed to commit dead revision for `%s'", finfo->fullname);
return (1);
}
+ /* At this point, the file has been committed as removed. We should
+ probably tell the history file about it */
+ history_write ('R', NULL, finfo->rcs->head, finfo->file, finfo->repository);
if (rev != NULL)
free (rev);
@@ -1962,6 +1964,11 @@ checkaddfile (file, repository, tag, options, rcsnode)
sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
+ /* Begin a critical section around the code that spans the
+ first commit on the trunk of a file that's already been
+ committed on a branch. */
+ SIG_beginCrSect ();
+
if (RCS_setattic (rcsfile, 0))
{
retval = 1;
@@ -2044,74 +2051,76 @@ checkaddfile (file, repository, tag, options, rcsnode)
newfile = 1;
if (desc != NULL)
free (desc);
+ if (rcsnode != NULL)
+ {
+ assert (*rcsnode == NULL);
+ *rcsnode = rcsfile;
+ }
}
/* when adding a file for the first time, and using a tag, we need
to create a dead revision on the trunk. */
- if (adding_on_branch && newfile)
+ if (adding_on_branch)
{
- char *tmp;
- FILE *fp;
-
- /* move the new file out of the way. */
- fname = xmalloc (strlen (file) + sizeof (CVSADM)
- + sizeof (CVSPREFIX) + 10);
- (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
- rename_file (file, fname);
-
- /* Create empty FILE. Can't use copy_file with a DEVNULL
- argument -- copy_file now ignores device files. */
- fp = fopen (file, "w");
- if (fp == NULL)
- error (1, errno, "cannot open %s for writing", file);
- if (fclose (fp) < 0)
- error (0, errno, "cannot close %s", file);
-
- tmp = xmalloc (strlen (file) + strlen (tag) + 80);
- /* commit a dead revision. */
- (void) sprintf (tmp, "file %s was initially added on branch %s.",
- file, tag);
- retcode = RCS_checkin (rcsfile, NULL, tmp, NULL,
- RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
- free (tmp);
- if (retcode != 0)
+ if (newfile)
{
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not create initial dead revision %s", rcs);
- retval = 1;
- goto out;
- }
+ char *tmp;
+ FILE *fp;
- /* put the new file back where it was */
- rename_file (fname, file);
- free (fname);
+ /* move the new file out of the way. */
+ fname = xmalloc (strlen (file) + sizeof (CVSADM)
+ + sizeof (CVSPREFIX) + 10);
+ (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
+ rename_file (file, fname);
- /* double-check that the file was written correctly */
- freercsnode (&rcsfile);
- rcsfile = RCS_parse (file, repository);
- if (rcsfile == NULL)
- {
- error (0, 0, "could not read %s", rcs);
- retval = 1;
- goto out;
- }
- if (rcsnode != NULL)
- {
- assert (*rcsnode == NULL);
- *rcsnode = rcsfile;
- }
+ /* Create empty FILE. Can't use copy_file with a DEVNULL
+ argument -- copy_file now ignores device files. */
+ fp = fopen (file, "w");
+ if (fp == NULL)
+ error (1, errno, "cannot open %s for writing", file);
+ if (fclose (fp) < 0)
+ error (0, errno, "cannot close %s", file);
+
+ tmp = xmalloc (strlen (file) + strlen (tag) + 80);
+ /* commit a dead revision. */
+ (void) sprintf (tmp, "file %s was initially added on branch %s.",
+ file, tag);
+ retcode = RCS_checkin (rcsfile, NULL, tmp, NULL,
+ RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
+ free (tmp);
+ if (retcode != 0)
+ {
+ error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
+ "could not create initial dead revision %s", rcs);
+ retval = 1;
+ goto out;
+ }
- /* and lock it once again. */
- if (lock_RCS (file, rcsfile, NULL, repository))
- {
- error (0, 0, "cannot lock `%s'.", rcs);
- retval = 1;
- goto out;
+ /* put the new file back where it was */
+ rename_file (fname, file);
+ free (fname);
+
+ /* double-check that the file was written correctly */
+ freercsnode (&rcsfile);
+ rcsfile = RCS_parse (file, repository);
+ if (rcsfile == NULL)
+ {
+ error (0, 0, "could not read %s", rcs);
+ retval = 1;
+ goto out;
+ }
+ if (rcsnode != NULL)
+ *rcsnode = rcsfile;
+
+ /* and lock it once again. */
+ if (lock_RCS (file, rcsfile, NULL, repository))
+ {
+ error (0, 0, "cannot lock `%s'.", rcs);
+ retval = 1;
+ goto out;
+ }
}
- }
- if (adding_on_branch)
- {
/* when adding with a tag, we need to stub a branch, if it
doesn't already exist. */
@@ -2194,6 +2203,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
retval = 0;
out:
+ if (retval != 0 && SIG_inCrSect ())
+ SIG_endCrSect ();
free (rcs);
return retval;
}
diff --git a/contrib/cvs/src/create_adm.c b/contrib/cvs/src/create_adm.c
index 7f8f581..878b058 100644
--- a/contrib/cvs/src/create_adm.c
+++ b/contrib/cvs/src/create_adm.c
@@ -22,7 +22,8 @@
don't print warnings; all errors are fatal then. */
int
-Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn)
+Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn,
+ dotemplate)
char *dir;
char *update_dir;
char *repository;
@@ -30,6 +31,7 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn)
char *date;
int nonbranch;
int warn;
+ int dotemplate;
{
FILE *fout;
char *cp;
@@ -168,7 +170,7 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn)
WriteTag (dir, tag, date, nonbranch, update_dir, repository);
#ifdef SERVER_SUPPORT
- if (server_active)
+ if (server_active && dotemplate)
{
server_template (update_dir, repository);
}
diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h
index 8a1501c..0277c86 100644
--- a/contrib/cvs/src/cvs.h
+++ b/contrib/cvs/src/cvs.h
@@ -390,6 +390,7 @@ extern List *root_directories;
extern char *current_root;
extern char *emptydir_name PROTO ((void));
+extern int safe_location PROTO ((void));
extern int trace; /* Show all commands */
extern int noexec; /* Don't modify disk anywhere */
@@ -499,7 +500,7 @@ void *valloc PROTO((size_t bytes));
time_t get_date PROTO((char *date, struct timeb *now));
extern int Create_Admin PROTO ((char *dir, char *update_dir,
char *repository, char *tag, char *date,
- int nonbranch, int warn));
+ int nonbranch, int warn, int dotemplate));
extern int expand_at_signs PROTO ((char *, off_t, FILE *));
/* Locking subsystem (implemented in lock.c). */
@@ -525,7 +526,7 @@ void cat_module PROTO((int status));
void check_entries PROTO((char *dir));
void close_module PROTO((DBM * db));
void copy_file PROTO((const char *from, const char *to));
-void fperror PROTO((FILE * fp, int status, int errnum, char *message,...));
+void fperrmsg PROTO((FILE * fp, int status, int errnum, char *message,...));
void free_names PROTO((int *pargc, char *argv[]));
extern int ign_name PROTO ((char *name));
@@ -546,6 +547,7 @@ void make_directories PROTO((const char *name));
void make_directory PROTO((const char *name));
extern int mkdir_if_needed PROTO ((char *name));
void rename_file PROTO((const char *from, const char *to));
+char *backup_file PROTO((const char *file, const char *suffix));
/* Expand wildcards in each element of (ARGC,ARGV). This is according to the
files which exist in the current directory, and accordingly to OS-specific
conventions regarding wildcard syntax. It might be desirable to change the
@@ -577,7 +579,7 @@ void do_editor PROTO((char *dir, char **messagep,
void do_verify PROTO((char *message, char *repository));
-typedef int (*CALLBACKPROC) PROTO((int *pargc, char *argv[], char *where,
+typedef int (*CALLBACKPROC) PROTO((int argc, char *argv[], char *where,
char *mwhere, char *mfile, int shorten, int local_specified,
char *omodule, char *msg));
@@ -636,6 +638,7 @@ int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
int dosrcs));
void SIG_beginCrSect PROTO((void));
void SIG_endCrSect PROTO((void));
+int SIG_inCrSect PROTO((void));
void read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
char *make_message_rcslegal PROTO((char *message));
@@ -853,6 +856,7 @@ extern int cvsremove PROTO((int argc, char **argv));
extern int rtag PROTO((int argc, char **argv));
extern int cvsstatus PROTO((int argc, char **argv));
extern int cvstag PROTO((int argc, char **argv));
+extern int version PROTO((int argc, char **argv));
extern unsigned long int lookup_command_attribute PROTO((char *));
@@ -869,6 +873,8 @@ extern void tag_check_valid PROTO ((char *, int, char **, int, int, char *));
extern void tag_check_valid_join PROTO ((char *, int, char **, int, int,
char *));
+#include "server.h"
+
/* From server.c and documented there. */
extern void cvs_output PROTO ((const char *, size_t));
extern void cvs_output_binary PROTO ((char *, size_t));
@@ -876,7 +882,3 @@ extern void cvs_outerr PROTO ((const char *, size_t));
extern void cvs_flusherr PROTO ((void));
extern void cvs_flushout PROTO ((void));
extern void cvs_output_tagged PROTO ((char *, char *));
-
-#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
-#include "server.h"
-#endif
diff --git a/contrib/cvs/src/edit.c b/contrib/cvs/src/edit.c
index 59d363c..df649b6 100644
--- a/contrib/cvs/src/edit.c
+++ b/contrib/cvs/src/edit.c
@@ -427,6 +427,15 @@ edit (argc, argv)
setting_tcommit = 1;
}
+ if (strpbrk (hostname, "+,>;=\t\n") != NULL)
+ error (1, 0,
+ "host name (%s) contains an invalid character (+,>;=\\t\\n)",
+ hostname);
+ if (strpbrk (CurDir, "+,>;=\t\n") != NULL)
+ error (1, 0,
+"current directory (%s) contains an invalid character (+,>;=\\t\\n)",
+ CurDir);
+
/* No need to readlock since we aren't doing anything to the
repository. */
err = start_recursion (edit_fileproc, (FILESDONEPROC) NULL,
@@ -553,6 +562,15 @@ unedit_fileproc (callerdat, finfo)
return 0;
}
+static const char *const unedit_usage[] =
+{
+ "Usage: %s %s [-lR] [files...]\n",
+ "-l: Local directory only, not recursive\n",
+ "-R: Process directories recursively\n",
+ "(Specify the --help global option for a list of other help options)\n",
+ NULL
+};
+
int
unedit (argc, argv)
int argc;
@@ -563,7 +581,7 @@ unedit (argc, argv)
int err;
if (argc == -1)
- usage (edit_usage);
+ usage (unedit_usage);
optind = 0;
while ((c = getopt (argc, argv, "+lR")) != -1)
@@ -578,7 +596,7 @@ unedit (argc, argv)
break;
case '?':
default:
- usage (edit_usage);
+ usage (unedit_usage);
break;
}
}
@@ -1060,6 +1078,7 @@ editors_fileproc (callerdat, finfo)
cvs_output ("\n", 1);
}
out:;
+ free (them);
return 0;
}
diff --git a/contrib/cvs/src/entries.c b/contrib/cvs/src/entries.c
index 7e258a9..14163bb 100644
--- a/contrib/cvs/src/entries.c
+++ b/contrib/cvs/src/entries.c
@@ -807,7 +807,8 @@ Subdirs_Known (entries)
if (!noexec)
{
/* Create Entries.Log so that Entries_Close will do something. */
- fp = CVS_FOPEN (CVSADM_ENTLOG, "a");
+ entfilename = CVSADM_ENTLOG;
+ fp = CVS_FOPEN (entfilename, "a");
if (fp == NULL)
{
int save_errno = errno;
@@ -821,7 +822,7 @@ Subdirs_Known (entries)
else
{
if (fclose (fp) == EOF)
- error (1, errno, "cannot close %s", CVSADM_ENTLOG);
+ error (1, errno, "cannot close %s", entfilename);
}
}
}
diff --git a/contrib/cvs/src/error.c b/contrib/cvs/src/error.c
index 64b686c..fe5877f 100644
--- a/contrib/cvs/src/error.c
+++ b/contrib/cvs/src/error.c
@@ -64,7 +64,8 @@ extern char *strerror ();
void
error_exit PROTO ((void))
{
- Lock_Cleanup();
+ rcs_cleanup ();
+ Lock_Cleanup ();
#ifdef SERVER_SUPPORT
if (server_active)
server_cleanup (0);
@@ -122,7 +123,7 @@ error (status, errnum, message, va_alist)
int num;
unsigned int unum;
int ch;
- unsigned char buf[100];
+ char buf[100];
cvs_outerr (program_name, 0);
if (command_name && *command_name)
@@ -201,9 +202,9 @@ error (status, errnum, message, va_alist)
/* VARARGS */
void
#if defined (HAVE_VPRINTF) && defined (__STDC__)
-fperror (FILE *fp, int status, int errnum, char *message, ...)
+fperrmsg (FILE *fp, int status, int errnum, char *message, ...)
#else
-fperror (fp, status, errnum, message, va_alist)
+fperrmsg (fp, status, errnum, message, va_alist)
FILE *fp;
int status;
int errnum;
diff --git a/contrib/cvs/src/fileattr.c b/contrib/cvs/src/fileattr.c
index 4042d2a..bae03a6 100644
--- a/contrib/cvs/src/fileattr.c
+++ b/contrib/cvs/src/fileattr.c
@@ -126,7 +126,7 @@ fileattr_read ()
any line other than the first for that filename. This
is the way that CVS has behaved since file attributes
were first introduced. */
- free (newnode);
+ freenode (newnode);
}
else if (line[0] == 'D')
{
@@ -513,6 +513,7 @@ fileattr_write ()
FILE *fp;
char *fname;
mode_t omask;
+ struct unrecog *p;
if (!attrs_modified)
return;
@@ -616,17 +617,10 @@ fileattr_write ()
}
/* Then any other attributes. */
- while (unrecog_head != NULL)
+ for (p = unrecog_head; p != NULL; p = p->next)
{
- struct unrecog *p;
-
- p = unrecog_head;
fputs (p->line, fp);
fputs ("\012", fp);
-
- unrecog_head = p->next;
- free (p->line);
- free (p);
}
if (fclose (fp) < 0)
@@ -649,4 +643,11 @@ fileattr_free ()
if (fileattr_default_attrs != NULL)
free (fileattr_default_attrs);
fileattr_default_attrs = NULL;
+ while (unrecog_head)
+ {
+ struct unrecog *p = unrecog_head;
+ unrecog_head = p->next;
+ free (p->line);
+ free (p);
+ }
}
diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c
index f3da62a..3a800a9 100644
--- a/contrib/cvs/src/filesubr.c
+++ b/contrib/cvs/src/filesubr.c
@@ -51,9 +51,13 @@ copy_file (from, to)
if (isdevice (from))
{
+#if defined(HAVE_MKNOD) && defined(HAVE_ST_RDEV)
if (stat (from, &sb) < 0)
error (1, errno, "cannot stat %s", from);
mknod (to, sb.st_mode, sb.st_rdev);
+#else
+ error (1, 0, "cannot copy device files on this system (%s)", from);
+#endif
}
else
{
@@ -620,10 +624,15 @@ xcmp (file1, file2)
numbers match. */
if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
{
+#ifdef HAVE_ST_RDEV
if (sb1.st_rdev == sb2.st_rdev)
return 0;
else
return 1;
+#else
+ error (1, 0, "cannot compare device files on this system (%s and %s)",
+ file1, file2);
+#endif
}
if ((fd1 = open (file1, O_RDONLY)) < 0)
diff --git a/contrib/cvs/src/hardlink.c b/contrib/cvs/src/hardlink.c
index 046cf3a..309d27f 100644
--- a/contrib/cvs/src/hardlink.c
+++ b/contrib/cvs/src/hardlink.c
@@ -63,7 +63,7 @@ lookup_file_by_inode (filepath)
/* inodestr contains the hexadecimal representation of an
inode, so it requires two bytes of text to represent
each byte of the inode number. */
- inodestr = (char *) xmalloc (2*sizeof(ino_t)*sizeof(char) + 1);
+ inodestr = (char *) xmalloc (2*sizeof(ino_t) + 1);
if (stat (file, &sb) < 0)
{
if (existence_error (errno))
@@ -85,7 +85,7 @@ lookup_file_by_inode (filepath)
if (hp == NULL)
{
hp = getnode ();
- hp->type = UNKNOWN;
+ hp->type = NT_UNKNOWN;
hp->key = inodestr;
hp->data = (char *) getlist();
hp->delproc = dellist;
@@ -100,7 +100,7 @@ lookup_file_by_inode (filepath)
if (p == NULL)
{
p = getnode();
- p->type = UNKNOWN;
+ p->type = NT_UNKNOWN;
p->key = xstrdup (filepath);
p->data = NULL;
(void) addnode ((List *) hp->data, p);
@@ -128,7 +128,7 @@ update_hardlink_info (file)
/* file is a relative pathname; assume it's from the current
working directory. */
char *dir = xgetwd();
- path = xmalloc (sizeof(char) * (strlen(dir) + strlen(file) + 2));
+ path = xmalloc (strlen(dir) + strlen(file) + 2);
sprintf (path, "%s/%s", dir, file);
free (dir);
}
@@ -176,8 +176,7 @@ list_linked_files_on_disk (file)
else
{
char *dir = xgetwd();
- path = (char *) xmalloc (sizeof(char) *
- (strlen(dir) + strlen(file) + 2));
+ path = (char *) xmalloc (strlen(dir) + strlen(file) + 2);
sprintf (path, "%s/%s", dir, file);
free (dir);
}
@@ -193,7 +192,7 @@ list_linked_files_on_disk (file)
/* inodestr contains the hexadecimal representation of an
inode, so it requires two bytes of text to represent
each byte of the inode number. */
- inodestr = (char *) xmalloc (2*sizeof(ino_t)*sizeof(char) + 1);
+ inodestr = (char *) xmalloc (2*sizeof(ino_t) + 1);
sprintf (inodestr, "%lx", (unsigned long) sb.st_ino);
/* Make sure the files linked to this inode are sorted. */
@@ -280,7 +279,7 @@ find_checkedout_proc (node, data)
/* Look at this file in the hardlist and see whether the checked_out
field is 1, meaning that it has been checked out during this CVS run. */
path = (char *)
- xmalloc (sizeof(char) * (strlen (dir) + strlen (node->key) + 2));
+ xmalloc (strlen (dir) + strlen (node->key) + 2);
sprintf (path, "%s/%s", dir, node->key);
link = lookup_file_by_inode (path);
free (path);
diff --git a/contrib/cvs/src/hash.c b/contrib/cvs/src/hash.c
index af000ac..7e562b8 100644
--- a/contrib/cvs/src/hash.c
+++ b/contrib/cvs/src/hash.c
@@ -102,7 +102,7 @@ dellist (listp)
{
/* put the nodes into the cache */
#ifndef NOCACHE
- p->type = UNKNOWN;
+ p->type = NT_UNKNOWN;
p->next = nodecache;
nodecache = p;
#else
@@ -147,7 +147,7 @@ getnode ()
/* always make it clean */
memset ((char *) p, 0, sizeof (Node));
- p->type = UNKNOWN;
+ p->type = NT_UNKNOWN;
return (p);
}
@@ -211,7 +211,7 @@ freenode (p)
/* then put it in the cache */
#ifndef NOCACHE
- p->type = UNKNOWN;
+ p->type = NT_UNKNOWN;
p->next = nodecache;
nodecache = p;
#else
@@ -456,7 +456,7 @@ nodetypestring (type)
Ntype type;
{
switch (type) {
- case UNKNOWN: return("UNKNOWN");
+ case NT_UNKNOWN: return("UNKNOWN");
case HEADER: return("HEADER");
case ENTRIES: return("ENTRIES");
case FILES: return("FILES");
@@ -470,6 +470,7 @@ nodetypestring (type)
case FILEATTR: return("FILEATTR");
case VARIABLE: return("VARIABLE");
case RCSFIELD: return("RCSFIELD");
+ case RCSCMPFLD: return("RCSCMPFLD");
}
return("<trash>");
diff --git a/contrib/cvs/src/hash.h b/contrib/cvs/src/hash.h
index 06867a7..f98353d 100644
--- a/contrib/cvs/src/hash.h
+++ b/contrib/cvs/src/hash.h
@@ -16,9 +16,9 @@
*/
enum ntype
{
- UNKNOWN, HEADER, ENTRIES, FILES, LIST, RCSNODE,
+ NT_UNKNOWN, HEADER, ENTRIES, FILES, LIST, RCSNODE,
RCSVERS, DIRS, UPDATE, LOCK, NDBMNODE, FILEATTR,
- VARIABLE, RCSFIELD
+ VARIABLE, RCSFIELD, RCSCMPFLD
};
typedef enum ntype Ntype;
diff --git a/contrib/cvs/src/history.c b/contrib/cvs/src/history.c
index bc7d1a6..9f66e86 100644
--- a/contrib/cvs/src/history.c
+++ b/contrib/cvs/src/history.c
@@ -195,7 +195,7 @@ static struct hrec
} *hrec_head;
-static char *fill_hrec PROTO((char *line, struct hrec * hr));
+static void fill_hrec PROTO((char *line, struct hrec * hr));
static int accept_hrec PROTO((struct hrec * hr, struct hrec * lr));
static int select_hrec PROTO((struct hrec * hr));
static int sort_order PROTO((const PTR l, const PTR r));
@@ -233,6 +233,8 @@ static short tz_local;
static time_t tz_seconds_east_of_GMT;
static char *tz_name = "+0000";
+char *logHistory = ALL_REC_TYPES;
+
/* -r, -t, or -b options, malloc'd. These are "" if the option in
question is not specified or is overridden by another option. The
main reason for using "" rather than NULL is historical. Together
@@ -288,9 +290,9 @@ static const char *const history_usg[] =
" -o Checked out modules\n",
" -m <module> Look for specified module (repeatable)\n",
" -x [TOEFWUCGMAR] Extract by record type\n",
+ " -e Everything (same as -x, but all record types)\n",
" Flags:\n",
" -a All users (Default is self)\n",
- " -e Everything (same as -x, but all record types)\n",
" -l Last modified (committed or modified report)\n",
" -w Working directory must match\n",
" Options:\n",
@@ -523,13 +525,17 @@ history (argc, argv)
break;
}
}
- c = optind; /* Save the handled option count */
+ argc -= optind;
+ argv += optind;
+ for (i = 0; i < argc; i++)
+ save_file ("", argv[i], (char *) NULL);
+
/* ================ Now analyze the arguments a bit */
if (!report_count)
v_checkout++;
else if (report_count > 1)
- error (1, 0, "Only one report type allowed from: \"-Tcomx\".");
+ error (1, 0, "Only one report type allowed from: \"-Tcomxe\".");
#ifdef CLIENT_SUPPORT
if (client_active)
@@ -613,7 +619,8 @@ history (argc, argv)
* If the user has not specified a date oriented flag ("Since"), sort
* by Repository/file before date. Default is "just" date.
*/
- if (!since_date && !*since_rev && !*since_tag && !*backto)
+ if (last_entry
+ || (!since_date && !*since_rev && !*since_tag && !*backto))
{
repos_sort++;
file_sort++;
@@ -642,7 +649,8 @@ history (argc, argv)
/* See comments in "modified" above */
if (!last_entry && user_list)
user_sort++;
- if (!since_date && !*since_rev && !*since_tag && !*backto)
+ if (last_entry
+ || (!since_date && !*since_rev && !*since_tag && !*backto))
file_sort++;
}
@@ -657,11 +665,6 @@ history (argc, argv)
(void) strcat (rec_types, "T");
}
- argc -= c;
- argv += c;
- for (i = 0; i < argc; i++)
- save_file ("", argv[i], (char *) NULL);
-
if (histfile)
fname = xstrdup (histfile);
else
@@ -673,7 +676,11 @@ history (argc, argv)
}
read_hrecs (fname);
- qsort ((PTR) hrec_head, hrec_count, sizeof (struct hrec), sort_order);
+ if(hrec_count>0)
+ {
+ qsort ((PTR) hrec_head, hrec_count,
+ sizeof (struct hrec), sort_order);
+ }
report_hrecs ();
free (fname);
if (since_date != NULL)
@@ -706,6 +713,8 @@ history_write (type, update_dir, revs, name, repository)
if (logoff) /* History is turned off by cmd line switch */
return;
+ if ( strchr(logHistory, type) == NULL )
+ return;
fname = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM)
+ sizeof (CVSROOTADM_HISTORY) + 10);
(void) sprintf (fname, "%s/%s/%s", CVSroot_directory,
@@ -725,7 +734,14 @@ history_write (type, update_dir, revs, name, repository)
goto out;
fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT | OPEN_BINARY, 0666);
if (fd < 0)
- error (1, errno, "cannot open history file: %s", fname);
+ {
+ if (! really_quiet)
+ {
+ error (0, errno, "warning: cannot write to history file %s",
+ fname);
+ }
+ goto out;
+ }
repos = Short_Repository (repository);
@@ -965,27 +981,26 @@ expand_modules ()
*
* Split it into 7 parts and drop the parts into a "struct hrec".
* Return a pointer to the character following the newline.
+ *
*/
-#define NEXT_BAR(here) do { while (isspace((unsigned char) *line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return(rtn); *(line - 1) = '\0'; } while (0)
+#define NEXT_BAR(here) do { while (isspace(*line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return; *(line - 1) = '\0'; } while (0)
-static char *
+static void
fill_hrec (line, hr)
char *line;
struct hrec *hr;
{
- char *cp, *rtn;
+ char *cp;
int c;
int off;
static int idx = 0;
unsigned long date;
memset ((char *) hr, 0, sizeof (*hr));
+
while (isspace ((unsigned char) *line))
line++;
- if (!(rtn = strchr (line, '\n')))
- return ("");
- *rtn++ = '\0';
hr->type = line++;
(void) sscanf (line, "%lx", &date);
@@ -993,7 +1008,7 @@ fill_hrec (line, hr)
while (*line && strchr ("0123456789abcdefABCDEF", *line))
line++;
if (*line == '\0')
- return (rtn);
+ return;
line++;
NEXT_BAR (user);
@@ -1012,27 +1027,38 @@ fill_hrec (line, hr)
if (strchr ("FOET", *(hr->type)))
hr->mod = line;
- NEXT_BAR (file); /* This returns ptr to next line or final '\0' */
- return (rtn); /* If it falls through, go on to next record */
+ NEXT_BAR (file);
}
+
+#ifndef STAT_BLOCKSIZE
+#if HAVE_ST_BLKSIZE
+#define STAT_BLOCKSIZE(s) (s).st_blksize
+#else
+#define STAT_BLOCKSIZE(s) (4 * 1024)
+#endif
+#endif
+
+
/* read_hrecs's job is to read the history file and fill in all the "hrec"
* (history record) array elements with the ones we need to print.
*
* Logic:
- * - Read the whole history file into a single buffer.
- * - Walk through the buffer, parsing lines out of the buffer.
- * 1. Split line into pointer and integer fields in the "next" hrec.
- * 2. Apply tests to the hrec to see if it is wanted.
- * 3. If it *is* wanted, bump the hrec pointer down by one.
+ * - Read a block from the file.
+ * - Walk through the block parsing line into hr records.
+ * - if the hr isn't used, free its strings, if it is, bump the hrec counter
+ * - at the end of a block, copy the end of the current block to the start
+ * of space for the next block, then read in the next block. If we get less
+ * than the whole block, we're done.
*/
static void
read_hrecs (fname)
char *fname;
{
- char *cp, *cp2;
- int i, fd;
- struct hrec *hr;
+ unsigned char *cpstart, *cp, *nl;
+ char *hrline;
+ int i;
+ int fd;
struct stat st_buf;
if ((fd = CVS_OPEN (fname, O_RDONLY | OPEN_BINARY)) < 0)
@@ -1041,54 +1067,75 @@ read_hrecs (fname)
if (fstat (fd, &st_buf) < 0)
error (1, errno, "can't stat history file");
- /* Exactly enough space for lines data */
- if (!(i = st_buf.st_size))
+ if (!(st_buf.st_size))
error (1, 0, "history file is empty");
- cp = xmalloc (i + 2);
- if (read (fd, cp, i) != i)
- error (1, errno, "cannot read log file");
- (void) close (fd);
-
- if (*(cp + i - 1) != '\n')
- {
- *(cp + i) = '\n'; /* Make sure last line ends in '\n' */
- i++;
- }
- *(cp + i) = '\0';
- for (cp2 = cp; cp2 - cp < i; cp2++)
- {
- if (*cp2 != '\n' && !isprint ((unsigned char) *cp2))
- *cp2 = ' ';
- }
+ cpstart = xmalloc (2 * STAT_BLOCKSIZE(st_buf));
+ cpstart[0] = '\0';
+ cp = cpstart;
hrec_max = HREC_INCREMENT;
- hrec_head = (struct hrec *) xmalloc (hrec_max * sizeof (struct hrec));
+ hrec_head = xmalloc (hrec_max * sizeof (struct hrec));
- while (*cp)
+ for (;;)
{
+ for (nl = cp; *nl && *nl != '\n'; nl++)
+ if (!isprint(*nl)) *nl = ' ';
+
+ if (!*nl)
+ {
+ if (nl - cp >= STAT_BLOCKSIZE(st_buf))
+ {
+ error(1, 0, "history line too long (> %lu)",
+ (unsigned long) STAT_BLOCKSIZE(st_buf));
+ }
+ if (nl > cp)
+ memmove (cpstart, cp, nl - cp);
+ nl = cpstart + (nl - cp);
+ cp = cpstart;
+ i = read (fd, nl, STAT_BLOCKSIZE(st_buf));
+ if (i > 0)
+ {
+ nl[i] = '\0';
+ continue;
+ }
+ if (i < 0)
+ error (1, errno, "error reading history file");
+ if (nl == cp) break;
+ nl[1] = '\0';
+ }
+ *nl = '\0';
+
if (hrec_count == hrec_max)
{
struct hrec *old_head = hrec_head;
hrec_max += HREC_INCREMENT;
- hrec_head = (struct hrec *) xrealloc ((char *) hrec_head,
- hrec_max * sizeof (struct hrec));
- if (hrec_head != old_head)
- {
- if (last_since_tag)
- last_since_tag = hrec_head + (last_since_tag - old_head);
- if (last_backto)
- last_backto = hrec_head + (last_backto - old_head);
- }
+ hrec_head = xrealloc ((char *) hrec_head,
+ hrec_max * sizeof (struct hrec));
+ if (last_since_tag)
+ last_since_tag = hrec_head + (last_since_tag - old_head);
+ if (last_backto)
+ last_backto = hrec_head + (last_backto - old_head);
}
- hr = hrec_head + hrec_count;
- cp = fill_hrec (cp, hr); /* cp == next line or '\0' at end of buffer */
+ /* fill_hrec dates from when history read the entire
+ history file in one chunk, and then records were pulled out
+ by pointing to the various parts of this big chunk. This is
+ why there are ugly hacks here: I don't want to completely
+ re-write the whole history stuff right now. */
- if (select_hrec (hr))
+ hrline = xstrdup ((char *)cp);
+ fill_hrec (hrline, &hrec_head[hrec_count]);
+ if (select_hrec (&hrec_head[hrec_count]))
hrec_count++;
+ else
+ free(hrline);
+
+ cp = nl + 1;
}
+ free (cpstart);
+ close (fd);
/* Special selection problem: If "since_tag" is set, we have saved every
* record from the 1st occurrence of "since_tag", when we want to save
@@ -1169,11 +1216,10 @@ select_hrec (hr)
if (since_date)
{
char *ourdate = date_from_time_t (hr->date);
-
- if (RCS_datecmp (ourdate, since_date) < 0)
- return (0);
-
+ count = RCS_datecmp (ourdate, since_date);
free (ourdate);
+ if (count < 0)
+ return (0);
}
else if (*since_rev)
{
@@ -1426,9 +1472,9 @@ report_hrecs ()
else
tm = localtime (&(lr->date));
- (void) printf ("%c %02d/%02d %02d:%02d %s %-*s", ty, tm->tm_mon + 1,
- tm->tm_mday, tm->tm_hour, tm->tm_min, tz_name,
- user_len, lr->user);
+ (void) printf ("%c %04d-%02d-%02d %02d:%02d %s %-*s", ty,
+ tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
+ tm->tm_min, tz_name, user_len, lr->user);
workdir = xmalloc (strlen (lr->dir) + strlen (lr->end) + 10);
(void) sprintf (workdir, "%s%s", lr->dir, lr->end);
diff --git a/contrib/cvs/src/ignore.c b/contrib/cvs/src/ignore.c
index df08017..4ea61ad 100644
--- a/contrib/cvs/src/ignore.c
+++ b/contrib/cvs/src/ignore.c
@@ -333,9 +333,7 @@ ign_dir_add (name)
(dir_ign_max + 1) * sizeof (char *));
}
- dir_ign_list[dir_ign_current] = name;
-
- dir_ign_current += 1 ;
+ dir_ign_list[dir_ign_current++] = xstrdup (name);
}
@@ -414,9 +412,9 @@ ignore_files (ilist, entries, update_dir, proc)
{
file = dp->d_name;
if (strcmp (file, ".") == 0 || strcmp (file, "..") == 0)
- continue;
+ goto continue_loop;
if (findnode_fn (ilist, file) != NULL)
- continue;
+ goto continue_loop;
if (subdirs)
{
Node *node;
@@ -437,14 +435,14 @@ ignore_files (ilist, entries, update_dir, proc)
dir = isdir (p);
free (p);
if (dir)
- continue;
+ goto continue_loop;
}
}
/* We could be ignoring FIFOs and other files which are neither
regular files nor directories here. */
if (ign_name (file))
- continue;
+ goto continue_loop;
if (
#ifdef DT_DIR
@@ -455,9 +453,12 @@ ignore_files (ilist, entries, update_dir, proc)
if (
#ifdef DT_DIR
- dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN &&
+ dp->d_type == DT_DIR
+ || (dp->d_type == DT_UNKNOWN && S_ISDIR (sb.st_mode))
+#else
+ S_ISDIR (sb.st_mode)
#endif
- S_ISDIR(sb.st_mode))
+ )
{
if (! subdirs)
{
@@ -468,7 +469,7 @@ ignore_files (ilist, entries, update_dir, proc)
if (isdir (temp))
{
free (temp);
- continue;
+ goto continue_loop;
}
free (temp);
}
@@ -476,16 +477,20 @@ ignore_files (ilist, entries, update_dir, proc)
#ifdef S_ISLNK
else if (
#ifdef DT_DIR
- dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN &&
+ dp->d_type == DT_LNK
+ || (dp->d_type == DT_UNKNOWN && S_ISLNK(sb.st_mode))
+#else
+ S_ISLNK (sb.st_mode)
#endif
- S_ISLNK(sb.st_mode))
+ )
{
- continue;
+ goto continue_loop;
}
#endif
}
(*proc) (file, xdir);
+ continue_loop:
errno = 0;
}
if (errno != 0)
diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c
index 57ff619..e1fb460 100644
--- a/contrib/cvs/src/import.c
+++ b/contrib/cvs/src/import.c
@@ -266,12 +266,22 @@ import (argc, argv)
client_import_setup (repository);
err = import_descend (message, argv[1], argc - 2, argv + 2);
client_import_done ();
+ if (message)
+ free (message);
+ free (repository);
+ free (vbranch);
+ free (vhead);
send_to_server ("import\012", 0);
err += get_responses_and_close ();
return err;
}
#endif
+ if (!safe_location ())
+ {
+ error (1, 0, "attempt to import the repository");
+ }
+
/*
* Make all newly created directories writable. Should really use a more
* sophisticated security mechanism here.
@@ -453,9 +463,12 @@ import_descend (message, vtag, targc, targv)
}
else if (
#ifdef DT_DIR
- dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN &&
+ dp->d_type == DT_LNK
+ || (dp->d_type == DT_UNKNOWN && islink (dp->d_name))
+#else
+ islink (dp->d_name)
#endif
- islink (dp->d_name))
+ )
{
add_log ('L', dp->d_name);
err++;
@@ -725,8 +738,8 @@ add_rev (message, rcs, vfile, vers)
{
if (!noexec)
{
- fperror (logfp, 0, status == -1 ? ierrno : 0,
- "ERROR: Check-in of %s failed", rcs->path);
+ fperrmsg (logfp, 0, status == -1 ? ierrno : 0,
+ "ERROR: Check-in of %s failed", rcs->path);
error (0, status == -1 ? ierrno : 0,
"ERROR: Check-in of %s failed", rcs->path);
}
@@ -765,8 +778,8 @@ add_tags (rcs, vfile, vtag, targc, targv)
if ((retcode = RCS_settag(rcs, vtag, vbranch)) != 0)
{
ierrno = errno;
- fperror (logfp, 0, retcode == -1 ? ierrno : 0,
- "ERROR: Failed to set tag %s in %s", vtag, rcs->path);
+ fperrmsg (logfp, 0, retcode == -1 ? ierrno : 0,
+ "ERROR: Failed to set tag %s in %s", vtag, rcs->path);
error (0, retcode == -1 ? ierrno : 0,
"ERROR: Failed to set tag %s in %s", vtag, rcs->path);
return (1);
@@ -789,9 +802,9 @@ add_tags (rcs, vfile, vtag, targc, targv)
else
{
ierrno = errno;
- fperror (logfp, 0, retcode == -1 ? ierrno : 0,
- "WARNING: Couldn't add tag %s to %s", targv[i],
- rcs->path);
+ fperrmsg (logfp, 0, retcode == -1 ? ierrno : 0,
+ "WARNING: Couldn't add tag %s to %s", targv[i],
+ rcs->path);
error (0, retcode == -1 ? ierrno : 0,
"WARNING: Couldn't add tag %s to %s", targv[i],
rcs->path);
@@ -1054,7 +1067,14 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
stat the file before opening it. -twp */
if (CVS_LSTAT (userfile, &sb) < 0)
- error (1, errno, "cannot lstat %s", user);
+ {
+ /* not fatal, continue import */
+ if (add_logfp != NULL)
+ fperrmsg (add_logfp, 0, errno,
+ "ERROR: cannot lstat file %s", userfile);
+ error (0, errno, "cannot lstat file %s", userfile);
+ goto read_error;
+ }
file_type = sb.st_mode & S_IFMT;
fpuser = NULL;
@@ -1069,8 +1089,8 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
{
/* not fatal, continue import */
if (add_logfp != NULL)
- fperror (add_logfp, 0, errno,
- "ERROR: cannot read file %s", userfile);
+ fperrmsg (add_logfp, 0, errno,
+ "ERROR: cannot read file %s", userfile);
error (0, errno, "ERROR: cannot read file %s", userfile);
goto read_error;
}
@@ -1202,12 +1222,18 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
case S_IFREG: break;
case S_IFCHR:
case S_IFBLK:
+#ifdef HAVE_ST_RDEV
if (fprintf (fprcs, "special\t%s %lu;\012",
(file_type == S_IFCHR
? "character"
: "block"),
(unsigned long) sb.st_rdev) < 0)
goto write_error;
+#else
+ error (0, 0,
+"can't import %s: unable to import device files on this system",
+userfile);
+#endif
break;
default:
error (0, 0,
@@ -1253,12 +1279,18 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
case S_IFREG: break;
case S_IFCHR:
case S_IFBLK:
+#ifdef HAVE_ST_RDEV
if (fprintf (fprcs, "special\t%s %lu;\012",
(file_type == S_IFCHR
? "character"
: "block"),
(unsigned long) sb.st_rdev) < 0)
goto write_error;
+#else
+ error (0, 0,
+"can't import %s: unable to import device files on this system",
+userfile);
+#endif
break;
default:
error (0, 0,
@@ -1377,8 +1409,8 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
{
ierrno = errno;
if (add_logfp != NULL)
- fperror (add_logfp, 0, ierrno,
- "WARNING: cannot change mode of file %s", rcs);
+ fperrmsg (add_logfp, 0, ierrno,
+ "WARNING: cannot change mode of file %s", rcs);
error (0, ierrno, "WARNING: cannot change mode of file %s", rcs);
err++;
}
@@ -1397,14 +1429,14 @@ write_error_noclose:
if (fclose (fpuser) < 0)
error (0, errno, "cannot close %s", user);
if (add_logfp != NULL)
- fperror (add_logfp, 0, ierrno, "ERROR: cannot write file %s", rcs);
+ fperrmsg (add_logfp, 0, ierrno, "ERROR: cannot write file %s", rcs);
error (0, ierrno, "ERROR: cannot write file %s", rcs);
if (ierrno == ENOSPC)
{
if (CVS_UNLINK (rcs) < 0)
error (0, errno, "cannot remove %s", rcs);
if (add_logfp != NULL)
- fperror (add_logfp, 0, 0, "ERROR: out of space - aborting");
+ fperrmsg (add_logfp, 0, 0, "ERROR: out of space - aborting");
error (1, 0, "ERROR: out of space - aborting");
}
read_error:
@@ -1513,7 +1545,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
return (0);
if (save_cwd (&cwd))
{
- fperror (logfp, 0, 0, "ERROR: cannot get working directory");
+ fperrmsg (logfp, 0, 0, "ERROR: cannot get working directory");
return (1);
}
@@ -1544,7 +1576,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
if ( CVS_CHDIR (dir) < 0)
{
ierrno = errno;
- fperror (logfp, 0, ierrno, "ERROR: cannot chdir to %s", repository);
+ fperrmsg (logfp, 0, ierrno, "ERROR: cannot chdir to %s", repository);
error (0, ierrno, "ERROR: cannot chdir to %s", repository);
err = 1;
goto out;
@@ -1559,9 +1591,9 @@ import_descend_dir (message, dir, vtag, targc, targv)
(void) sprintf (rcs, "%s%s", repository, RCSEXT);
if (isfile (repository) || isfile(rcs))
{
- fperror (logfp, 0, 0,
- "ERROR: %s is a file, should be a directory!",
- repository);
+ fperrmsg (logfp, 0, 0,
+ "ERROR: %s is a file, should be a directory!",
+ repository);
error (0, 0, "ERROR: %s is a file, should be a directory!",
repository);
err = 1;
@@ -1570,8 +1602,8 @@ import_descend_dir (message, dir, vtag, targc, targv)
if (noexec == 0 && CVS_MKDIR (repository, 0777) < 0)
{
ierrno = errno;
- fperror (logfp, 0, ierrno,
- "ERROR: cannot mkdir %s -- not added", repository);
+ fperrmsg (logfp, 0, ierrno,
+ "ERROR: cannot mkdir %s -- not added", repository);
error (0, ierrno,
"ERROR: cannot mkdir %s -- not added", repository);
err = 1;
diff --git a/contrib/cvs/src/lock.c b/contrib/cvs/src/lock.c
index 3776b2c..1b98180 100644
--- a/contrib/cvs/src/lock.c
+++ b/contrib/cvs/src/lock.c
@@ -175,8 +175,12 @@ lock_name (repository, name)
assert (CVSroot_directory != NULL);
assert (strncmp (repository, CVSroot_directory,
strlen (CVSroot_directory)) == 0);
- short_repos = repository + strlen (CVSroot_directory);
- assert (*short_repos++ == '/');
+ short_repos = repository + strlen (CVSroot_directory) + 1;
+
+ if (strcmp (repository, CVSroot_directory) == 0)
+ short_repos = ".";
+ else
+ assert (short_repos[-1] == '/');
retval = xmalloc (strlen (lock_dir)
+ strlen (short_repos)
@@ -755,8 +759,8 @@ set_lock (lock, will_wait)
if (errno != EEXIST)
{
error (0, errno,
- "failed to create lock directory in repository `%s'",
- lock->repository);
+ "failed to create lock directory for `%s' (%s)",
+ lock->repository, masterlock);
return (L_ERROR);
}
diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c
index 398d650..2e230e3 100644
--- a/contrib/cvs/src/log.c
+++ b/contrib/cvs/src/log.c
@@ -149,6 +149,47 @@ static const char *const log_usage[] =
NULL
};
+#ifdef CLIENT_SUPPORT
+
+/* Helper function for send_arg_list. */
+static int send_one PROTO ((Node *, void *));
+
+static int
+send_one (node, closure)
+ Node *node;
+ void *closure;
+{
+ char *option = (char *) closure;
+
+ send_to_server ("Argument ", 0);
+ send_to_server (option, 0);
+ if (strcmp (node->key, "@@MYSELF") == 0)
+ /* It is a bare -w option. Note that we must send it as
+ -w rather than messing with getcaller() or something (which on
+ the client will return garbage). */
+ ;
+ else
+ send_to_server (node->key, 0);
+ send_to_server ("\012", 0);
+ return 0;
+}
+
+/* For each element in ARG, send an argument consisting of OPTION
+ concatenated with that element. */
+static void send_arg_list PROTO ((char *, List *));
+
+static void
+send_arg_list (option, arg)
+ char *option;
+ List *arg;
+{
+ if (arg == NULL)
+ return;
+ walklist (arg, send_one, (void *)option);
+}
+
+#endif
+
int
cvslog (argc, argv)
int argc;
@@ -158,12 +199,13 @@ cvslog (argc, argv)
int err = 0;
int local = 0;
struct log_data log_data;
- struct option_revlist *rl, **prl;
+ struct option_revlist **prl;
if (argc == -1)
usage (log_usage);
memset (&log_data, 0, sizeof log_data);
+ prl = &log_data.revlist;
optind = 0;
while ((c = getopt (argc, argv, "+bd:hlNRr::s:tw::")) != -1)
@@ -189,12 +231,8 @@ cvslog (argc, argv)
log_data.nameonly = 1;
break;
case 'r':
- rl = log_parse_revlist (optarg);
- for (prl = &log_data.revlist;
- *prl != NULL;
- prl = &(*prl)->next)
- ;
- *prl = rl;
+ *prl = log_parse_revlist (optarg);
+ prl = &(*prl)->next;
break;
case 's':
log_parse_list (&log_data.statelist, optarg);
@@ -206,7 +244,7 @@ cvslog (argc, argv)
if (optarg != NULL)
log_parse_list (&log_data.authorlist, optarg);
else
- log_parse_list (&log_data.authorlist, getcaller ());
+ log_parse_list (&log_data.authorlist, "@@MYSELF");
break;
case '?':
default:
@@ -220,18 +258,97 @@ cvslog (argc, argv)
#ifdef CLIENT_SUPPORT
if (client_active)
{
- int i;
+ struct datelist *p;
+ struct option_revlist *rp;
+ char datetmp[MAXDATELEN];
/* We're the local client. Fire up the remote server. */
start_server ();
ign_setup ();
- for (i = 1; i < argc && argv[i][0] == '-'; i++)
- send_arg (argv[i]);
+ if (log_data.default_branch)
+ send_arg ("-b");
+
+ while (log_data.datelist != NULL)
+ {
+ p = log_data.datelist;
+ log_data.datelist = p->next;
+ send_to_server ("Argument -d\012", 0);
+ send_to_server ("Argument ", 0);
+ date_to_internet (datetmp, p->start);
+ send_to_server (datetmp, 0);
+ if (p->inclusive)
+ send_to_server ("<=", 0);
+ else
+ send_to_server ("<", 0);
+ date_to_internet (datetmp, p->end);
+ send_to_server (datetmp, 0);
+ send_to_server ("\012", 0);
+ if (p->start)
+ free (p->start);
+ if (p->end)
+ free (p->end);
+ free (p);
+ }
+ while (log_data.singledatelist != NULL)
+ {
+ p = log_data.singledatelist;
+ log_data.singledatelist = p->next;
+ send_to_server ("Argument -d\012", 0);
+ send_to_server ("Argument ", 0);
+ date_to_internet (datetmp, p->end);
+ send_to_server (datetmp, 0);
+ send_to_server ("\012", 0);
+ if (p->end)
+ free (p->end);
+ free (p);
+ }
+
+ if (log_data.header)
+ send_arg ("-h");
+ if (local)
+ send_arg("-l");
+ if (log_data.notags)
+ send_arg("-N");
+ if (log_data.nameonly)
+ send_arg("-R");
+ if (log_data.long_header)
+ send_arg("-t");
+
+ while (log_data.revlist != NULL)
+ {
+ rp = log_data.revlist;
+ log_data.revlist = rp->next;
+ send_to_server ("Argument -r", 0);
+ if (rp->branchhead)
+ {
+ if (rp->first != NULL)
+ send_to_server (rp->first, 0);
+ send_to_server (".", 1);
+ }
+ else
+ {
+ if (rp->first != NULL)
+ send_to_server (rp->first, 0);
+ send_to_server (":", 1);
+ if (rp->last != NULL)
+ send_to_server (rp->last, 0);
+ }
+ send_to_server ("\012", 0);
+ if (rp->first)
+ free (rp->first);
+ if (rp->last)
+ free (rp->last);
+ free (rp);
+ }
+ send_arg_list ("-s", log_data.statelist);
+ dellist (&log_data.statelist);
+ send_arg_list ("-w", log_data.authorlist);
+ dellist (&log_data.authorlist);
- send_files (argc - i, argv + i, local, 0, SEND_NO_CONTENTS);
- send_file_names (argc - i, argv + i, SEND_EXPAND_WILD);
+ send_files (argc - optind, argv + optind, local, 0, SEND_NO_CONTENTS);
+ send_file_names (argc - optind, argv + optind, SEND_EXPAND_WILD);
send_to_server ("log\012", 0);
err = get_responses_and_close ();
@@ -239,11 +356,50 @@ cvslog (argc, argv)
}
#endif
+ /* OK, now that we know we are local/server, we can resolve @@MYSELF
+ into our user name. */
+ if (findnode (log_data.authorlist, "@@MYSELF") != NULL)
+ log_parse_list (&log_data.authorlist, getcaller ());
+
err = start_recursion (log_fileproc, (FILESDONEPROC) NULL, log_dirproc,
(DIRLEAVEPROC) NULL, (void *) &log_data,
argc - optind, argv + optind, local,
W_LOCAL | W_REPOS | W_ATTIC, 0, 1,
(char *) NULL, 1);
+
+ while (log_data.revlist)
+ {
+ struct option_revlist *rl = log_data.revlist->next;
+ if (log_data.revlist->first)
+ free (log_data.revlist->first);
+ if (log_data.revlist->last)
+ free (log_data.revlist->last);
+ free (log_data.revlist);
+ log_data.revlist = rl;
+ }
+ while (log_data.datelist)
+ {
+ struct datelist *nd = log_data.datelist->next;
+ if (log_data.datelist->start)
+ free (log_data.datelist->start);
+ if (log_data.datelist->end)
+ free (log_data.datelist->end);
+ free (log_data.datelist);
+ log_data.datelist = nd;
+ }
+ while (log_data.singledatelist)
+ {
+ struct datelist *nd = log_data.singledatelist->next;
+ if (log_data.singledatelist->start)
+ free (log_data.singledatelist->start);
+ if (log_data.singledatelist->end)
+ free (log_data.singledatelist->end);
+ free (log_data.singledatelist);
+ log_data.singledatelist = nd;
+ }
+ dellist (&log_data.statelist);
+ dellist (&log_data.authorlist);
+
return (err);
}
@@ -255,77 +411,65 @@ static struct option_revlist *
log_parse_revlist (argstring)
const char *argstring;
{
- char *copy;
+ char *orig_copy, *copy;
struct option_revlist *ret, **pr;
/* Unfortunately, rlog accepts -r without an argument to mean that
latest revision on the default branch, so we must support that
for compatibility. */
if (argstring == NULL)
- {
- ret = (struct option_revlist *) xmalloc (sizeof *ret);
- ret->first = NULL;
- ret->last = NULL;
- ret->next = NULL;
- ret->branchhead = 0;
- return ret;
- }
+ argstring = "";
ret = NULL;
pr = &ret;
/* Copy the argument into memory so that we can change it. We
don't want to change the argument because, at least as of this
- writing, we will use it if we send the arguments to the server.
- We never bother to free up our copy. */
- copy = xstrdup (argstring);
+ writing, we will use it if we send the arguments to the server. */
+ orig_copy = copy = xstrdup (argstring);
while (copy != NULL)
{
char *comma;
- char *cp;
- char *first, *last;
struct option_revlist *r;
comma = strchr (copy, ',');
if (comma != NULL)
*comma++ = '\0';
- first = copy;
- cp = strchr (copy, ':');
- if (cp == NULL)
- last = copy;
- else
- {
- *cp++ = '\0';
- last = cp;
- }
-
- if (*first == '\0')
- first = NULL;
- if (*last == '\0')
- last = NULL;
-
r = (struct option_revlist *) xmalloc (sizeof *r);
r->next = NULL;
- r->first = first;
- r->last = last;
- if (first != last
- || first[strlen (first) - 1] != '.')
- {
- r->branchhead = 0;
- }
+ r->first = copy;
+ r->branchhead = 0;
+ r->last = strchr (copy, ':');
+ if (r->last != NULL)
+ *r->last++ = '\0';
else
{
- r->branchhead = 1;
- first[strlen (first) - 1] = '\0';
+ r->last = r->first;
+ if (r->first[0] != '\0' && r->first[strlen (r->first) - 1] == '.')
+ {
+ r->branchhead = 1;
+ r->first[strlen (r->first) - 1] = '\0';
+ }
}
+ if (*r->first == '\0')
+ r->first = NULL;
+ if (*r->last == '\0')
+ r->last = NULL;
+
+ if (r->first != NULL)
+ r->first = xstrdup (r->first);
+ if (r->last != NULL)
+ r->last = xstrdup (r->last);
+
*pr = r;
pr = &r->next;
copy = comma;
}
+ free (orig_copy);
return ret;
}
@@ -342,8 +486,7 @@ log_parse_date (log_data, argstring)
/* Copy the argument into memory so that we can change it. We
don't want to change the argument because, at least as of this
writing, we will use it if we send the arguments to the server. */
- copy = xstrdup (argstring);
- orig_copy = copy;
+ orig_copy = copy = xstrdup (argstring);
while (copy != NULL)
{
struct datelist *nd, **pd;
diff --git a/contrib/cvs/src/login.c b/contrib/cvs/src/login.c
index 46707e2..1a774e0 100644
--- a/contrib/cvs/src/login.c
+++ b/contrib/cvs/src/login.c
@@ -12,6 +12,12 @@
#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */
+#ifdef HAVE_GETPASSPHRASE
+#define GETPASS getpassphrase
+#else
+#define GETPASS getpass
+#endif
+
/* There seems to be very little agreement on which system header
getpass is declared in. With a lot of fancy autoconfiscation,
we could perhaps detect this, but for now we'll just rely on
@@ -20,7 +26,7 @@
varadic, believe it or not). On Cray, getpass will be declared
in either stdlib.h or unistd.h. */
#ifndef _CRAY
-extern char *getpass ();
+extern char *GETPASS ();
#endif
#ifndef CVS_PASSWORD_FILE
@@ -142,7 +148,7 @@ login (argc, argv)
fflush (stdout);
passfile = construct_cvspass_filename ();
- typed_password = getpass ("CVS password: ");
+ typed_password = GETPASS ("CVS password: ");
typed_password = scramble (typed_password);
/* Force get_cvs_password() to use this one (when the client
@@ -289,14 +295,15 @@ login (argc, argv)
}
/* Returns the _scrambled_ password. The server must descramble
- before hashing and comparing. */
+ before hashing and comparing. If password file not found, or
+ password not found in the file, just return NULL. */
char *
get_cvs_password ()
{
int found_it = 0;
int root_len;
- char *password;
- char *linebuf = (char *) NULL;
+ char *password = NULL;
+ char *linebuf = NULL;
size_t linebuf_len;
FILE *fp;
char *passfile;
@@ -339,11 +346,10 @@ get_cvs_password ()
passfile = construct_cvspass_filename ();
fp = CVS_FOPEN (passfile, "r");
- if (fp == NULL)
+ if (fp == NULL)
{
- error (0, errno, "could not open %s", passfile);
free (passfile);
- error (1, 0, "use \"cvs login\" to log in first");
+ return NULL;
}
root_len = strlen (CVSroot_original);
@@ -369,23 +375,19 @@ get_cvs_password ()
char *tmp;
strtok (linebuf, " ");
- password = strtok (NULL, "\n");
+ tmp = strtok (NULL, "\n");
+ if (tmp == NULL)
+ error (1, 0, "bad entry in %s for %s", passfile, CVSroot_original);
/* Give it permanent storage. */
- tmp = xstrdup (password);
- memset (password, 0, strlen (password));
- free (linebuf);
- return tmp;
- }
- else
- {
- if (linebuf)
- free (linebuf);
- error (0, 0, "cannot find password");
- error (1, 0, "use \"cvs login\" to log in first");
+ password = xstrdup (tmp);
+ memset (tmp, 0, strlen (password));
}
- /* NOTREACHED */
- return NULL;
+
+ if (linebuf)
+ free (linebuf);
+ free (passfile);
+ return password;
}
static const char *const logout_usage[] =
@@ -395,7 +397,7 @@ static const char *const logout_usage[] =
NULL
};
-/* Remove any entry for the CVSRoot repository found in "CVS/.cvspass". */
+/* Remove any entry for the CVSRoot repository found in .cvspass. */
int
logout (argc, argv)
int argc;
@@ -403,7 +405,7 @@ logout (argc, argv)
{
char *passfile;
FILE *fp;
- char *tmp_name;
+ char *tmp_name = NULL;
FILE *tmp_fp;
char *linebuf = (char *) NULL;
size_t linebuf_len;
@@ -498,6 +500,10 @@ logout (argc, argv)
error (0, errno, "cannot remove %s", tmp_name);
chmod (passfile, 0600);
}
+
+ if (tmp_name)
+ free (tmp_name);
+
return 0;
}
diff --git a/contrib/cvs/src/logmsg.c b/contrib/cvs/src/logmsg.c
index 6d45ca3..cb08cdf 100644
--- a/contrib/cvs/src/logmsg.c
+++ b/contrib/cvs/src/logmsg.c
@@ -182,7 +182,6 @@ do_editor (dir, messagep, repository, changes)
char *fname;
struct stat pre_stbuf, post_stbuf;
int retcode = 0;
- char *p;
if (noexec || reuse_log_message)
return;
@@ -216,7 +215,6 @@ do_editor (dir, messagep, repository, changes)
{
FILE *tfp;
char buf[1024];
- char *p;
size_t n;
size_t nwrite;
@@ -231,9 +229,9 @@ do_editor (dir, messagep, repository, changes)
{
while (!feof (tfp))
{
+ char *p = buf;
n = fread (buf, 1, sizeof buf, tfp);
nwrite = n;
- p = buf;
while (nwrite > 0)
{
n = fwrite (p, 1, nwrite, fp);
@@ -315,7 +313,8 @@ do_editor (dir, messagep, repository, changes)
if (*messagep)
{
- p = *messagep;
+ size_t message_len = post_stbuf.st_size + 1;
+ size_t offset = 0;
while (1)
{
line_length = getline (&line, &line_chars_allocated, fp);
@@ -327,8 +326,11 @@ do_editor (dir, messagep, repository, changes)
}
if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0)
continue;
- (void) strcpy (p, line);
- p += line_length;
+ if (offset + line_length >= message_len)
+ expand_string (messagep, &message_len,
+ offset + line_length + 1);
+ (void) strcpy (*messagep + offset, line);
+ offset += line_length;
}
}
if (fclose (fp) < 0)
@@ -759,7 +761,7 @@ logfile_write (repository, filter, message, logfp, changes)
}
len = fmt_end - fmt_begin;
- str_list_format = xmalloc (sizeof (char) * (len + 1));
+ str_list_format = xmalloc (len + 1);
strncpy (str_list_format, fmt_begin, len);
str_list_format[len] = '\0';
diff --git a/contrib/cvs/src/main.c b/contrib/cvs/src/main.c
index e211db6..86913e1 100644
--- a/contrib/cvs/src/main.c
+++ b/contrib/cvs/src/main.c
@@ -111,30 +111,31 @@ static const struct cmd
{ "history", "hi", "his", history },
{ "import", "im", "imp", import },
{ "init", NULL, NULL, init },
-#ifdef SERVER_SUPPORT
+#if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT)
{ "kserver", NULL, NULL, server }, /* placeholder */
#endif
{ "log", "lo", "rlog", cvslog },
#ifdef AUTH_CLIENT_SUPPORT
{ "login", "logon", "lgn", login },
{ "logout", NULL, NULL, logout },
-#ifdef SERVER_SUPPORT
+#endif /* AUTH_CLIENT_SUPPORT */
+#if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
{ "pserver", NULL, NULL, server }, /* placeholder */
#endif
-#endif /* AUTH_CLIENT_SUPPORT */
{ "rdiff", "patch", "pa", patch },
{ "release", "re", "rel", release },
{ "remove", "rm", "delete", cvsremove },
- { "status", "st", "stat", cvsstatus },
{ "rtag", "rt", "rfreeze", rtag },
+#ifdef SERVER_SUPPORT
+ { "server", NULL, NULL, server },
+#endif
+ { "status", "st", "stat", cvsstatus },
{ "tag", "ta", "freeze", cvstag },
{ "unedit", NULL, NULL, unedit },
{ "update", "up", "upd", update },
+ { "version", "ve", "ver", version },
{ "watch", NULL, NULL, watch },
{ "watchers", NULL, NULL, watchers },
-#ifdef SERVER_SUPPORT
- { "server", NULL, NULL, server },
-#endif
{ NULL, NULL, NULL, NULL },
};
@@ -179,7 +180,7 @@ static const char *const usg[] =
version control means. */
"For CVS updates and additional information, see\n",
- " Cyclic Software at http://www.cyclic.com/ or\n",
+ " the CVS home page at http://www.cvshome.org/ or\n",
" Pascal Molli's CVS site at http://www.loria.fr/~molli/cvs-index.html\n",
NULL,
};
@@ -199,15 +200,24 @@ static const char *const cmd_usage[] =
" history Show repository access history\n",
" import Import sources into CVS, using vendor branches\n",
" init Create a CVS repository if it doesn't exist\n",
+#if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT)
+ " kserver Kerberos server mode\n",
+#endif
" log Print out history information for files\n",
#ifdef AUTH_CLIENT_SUPPORT
- " login Prompt for password for authenticating server.\n",
- " logout Removes entry in .cvspass for remote repository.\n",
+ " login Prompt for password for authenticating server\n",
+ " logout Removes entry in .cvspass for remote repository\n",
#endif /* AUTH_CLIENT_SUPPORT */
+#if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
+ " pserver Password server mode\n",
+#endif
" rdiff Create 'patch' format diffs between releases\n",
" release Indicate that a Module is no longer in use\n",
" remove Remove an entry from the repository\n",
" rtag Add a symbolic tag to a module\n",
+#ifdef SERVER_SUPPORT
+ " server Server mode\n",
+#endif
" status Display status information on checked out files\n",
" tag Add a symbolic tag to checked out version of files\n",
" unedit Undo an edit command\n",
@@ -343,6 +353,7 @@ lookup_command_attribute (cmd_name)
(strcmp (cmd_name, "log") != 0) &&
(strcmp (cmd_name, "noop") != 0) &&
(strcmp (cmd_name, "watchers") != 0) &&
+ (strcmp (cmd_name, "release") != 0) &&
(strcmp (cmd_name, "status") != 0))
{
ret |= CVS_CMD_MODIFIES_REPOSITORY;
@@ -362,6 +373,11 @@ main_cleanup (sig)
switch (sig)
{
+#ifdef SIGABRT
+ case SIGABRT:
+ name = "abort";
+ break;
+#endif
#ifdef SIGHUP
case SIGHUP:
name = "hangup";
@@ -405,8 +421,6 @@ main (argc, argv)
char **argv;
{
char *CVSroot = CVSROOT_DFLT;
- extern char *version_string;
- extern char *config_string;
char *cp, *end;
const struct cmd *cm;
int c, err = 0;
@@ -418,6 +432,7 @@ main (argc, argv)
int help = 0; /* Has the user asked for help? This
lets us support the `cvs -H cmd'
convention to give help for cmd. */
+ static const char short_options[] = "+Qqrwtnlvb:T:e:d:Hfz:s:xa";
static struct option long_options[] =
{
{"help", 0, NULL, 'H'},
@@ -492,7 +507,7 @@ main (argc, argv)
opterr = 0;
while ((c = getopt_long
- (argc, argv, "+f", NULL, NULL))
+ (argc, argv, short_options, long_options, &option_index))
!= EOF)
{
if (c == 'f')
@@ -509,7 +524,7 @@ main (argc, argv)
opterr = 1;
while ((c = getopt_long
- (argc, argv, "+Qqrwtnlvb:T:e:d:Hfz:s:xa", long_options, &option_index))
+ (argc, argv, short_options, long_options, &option_index))
!= EOF)
{
switch (c)
@@ -551,14 +566,11 @@ main (argc, argv)
logoff = 1;
break;
case 'v':
- /* Having the year here is a good idea, so people have
- some idea of how long ago their version of CVS was
- released. */
- (void) fputs (version_string, stdout);
- (void) fputs (config_string, stdout);
+ (void) fputs ("\n", stdout);
+ version (0, (char **) NULL);
(void) fputs ("\n", stdout);
(void) fputs ("\
-Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
+Copyright (c) 1989-2000 Brian Berliner, david d `zoo' zuhn, \n\
Jeff Polk, and other authors\n", stdout);
(void) fputs ("\n", stdout);
(void) fputs ("CVS may be copied only under the terms of the GNU General Public License,\n", stdout);
@@ -602,9 +614,9 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
case 'z':
#ifdef CLIENT_SUPPORT
gzip_level = atoi (optarg);
- if (gzip_level <= 0 || gzip_level > 9)
+ if (gzip_level < 0 || gzip_level > 9)
error (1, 0,
- "gzip compression level must be between 1 and 9");
+ "gzip compression level must be between 0 and 9");
#endif
/* If no CLIENT_SUPPORT, we just silently ignore the gzip
level, so that users can have it in their .cvsrc and not
@@ -657,7 +669,10 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
}
if (!cm->fullname)
- usage (cmd_usage); /* no match */
+ {
+ fprintf (stderr, "Unknown command: `%s'\n\n", command_name);
+ usage (cmd_usage);
+ }
else
command_name = cm->fullname; /* Global pointer for later use */
@@ -765,25 +780,23 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
#ifndef DONT_USE_SIGNALS
/* make sure we clean up on error */
+#ifdef SIGABRT
+ (void) SIG_register (SIGABRT, main_cleanup);
+#endif
#ifdef SIGHUP
(void) SIG_register (SIGHUP, main_cleanup);
- (void) SIG_register (SIGHUP, Lock_Cleanup);
#endif
#ifdef SIGINT
(void) SIG_register (SIGINT, main_cleanup);
- (void) SIG_register (SIGINT, Lock_Cleanup);
#endif
#ifdef SIGQUIT
(void) SIG_register (SIGQUIT, main_cleanup);
- (void) SIG_register (SIGQUIT, Lock_Cleanup);
#endif
#ifdef SIGPIPE
(void) SIG_register (SIGPIPE, main_cleanup);
- (void) SIG_register (SIGPIPE, Lock_Cleanup);
#endif
#ifdef SIGTERM
(void) SIG_register (SIGTERM, main_cleanup);
- (void) SIG_register (SIGTERM, Lock_Cleanup);
#endif
#endif /* !DONT_USE_SIGNALS */
@@ -878,7 +891,7 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
{
Node *n;
n = getnode ();
- n->type = UNKNOWN;
+ n->type = NT_UNKNOWN;
n->key = xstrdup (CVSroot);
n->data = NULL;
@@ -921,11 +934,8 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
current_root);
/*
- * Check to see if we can write into the history file. If not,
- * we assume that we can't work in the repository.
- * BUT, only if the history file exists.
+ * Check to see if the repository exists.
*/
-
if (!client_active)
{
char *path;
@@ -933,8 +943,7 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
path = xmalloc (strlen (CVSroot_directory)
+ sizeof (CVSROOTADM)
- + 20
- + sizeof (CVSROOTADM_HISTORY));
+ + 20);
(void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
if (!isaccessible (path, R_OK | X_OK))
{
@@ -945,14 +954,6 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
error (1, save_errno, "%s", path);
}
}
- (void) strcat (path, "/");
- (void) strcat (path, CVSROOTADM_HISTORY);
- if (isfile (path) && !isaccessible (path, R_OK | W_OK))
- {
- save_errno = errno;
- error (0, 0, "Sorry, you don't have read/write access to the history file");
- error (1, save_errno, "%s", path);
- }
free (path);
}
@@ -961,12 +962,17 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
/* FIXME (njc): should we always set this with the CVSROOT from the command line? */
if (cvs_update_env)
{
+ static char *prev;
char *env;
env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot)
+ 1 + 1);
(void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
(void) putenv (env);
- /* do not free env, as putenv has control of it */
+ /* do not free env yet, as putenv has control of it */
+ /* but do free the previous value, if any */
+ if (prev != NULL)
+ free (prev);
+ prev = env;
}
#endif
}
diff --git a/contrib/cvs/src/mkmodules.c b/contrib/cvs/src/mkmodules.c
index 4244258..4e4b5d0 100644
--- a/contrib/cvs/src/mkmodules.c
+++ b/contrib/cvs/src/mkmodules.c
@@ -280,14 +280,23 @@ static const char *const config_contents[] = {
"# Set this to \"no\" if pserver shouldn't check system users/passwords\n",
"#SystemAuth=no\n",
"\n",
+ "# Put CVS lock files in this directory rather than directly in the repository.\n",
+ "#LockDir=/var/lock/cvs\n",
+ "\n",
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
"# Set `PreservePermissions' to `yes' to save file status information\n",
"# in the repository.\n",
"#PreservePermissions=no\n",
"\n",
+#endif
"# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top\n",
"# level of the new working directory when using the `cvs checkout'\n",
"# command.\n",
"#TopLevelAdmin=no\n",
+ "\n",
+ "# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the\n",
+ "# history file, or a subset as needed (ie `TMAR' logs all write operations)\n",
+ "#LogHistory=TOFEWGCMAR\n",
NULL
};
@@ -372,6 +381,9 @@ mkmodules (dir)
size_t line_allocated = 0;
const struct admin_file *fileptr;
+ if (noexec)
+ return 0;
+
if (save_cwd (&cwd))
error_exit ();
@@ -865,6 +877,9 @@ init (argc, argv)
if ( CVS_CHDIR (adm) < 0)
error (1, errno, "cannot change to directory %s", adm);
+ /* Make Emptydir so it's there if we need it */
+ mkdir_if_needed (CVSNULLREPOS);
+
/* 80 is long enough for all the administrative file names, plus
"/" and so on. */
info = xmalloc (strlen (adm) + 80);
@@ -926,6 +941,29 @@ init (argc, argv)
fp = open_file (info, "w");
if (fclose (fp) < 0)
error (1, errno, "cannot close %s", info);
+
+ /* Make the new history file world-writeable, since every CVS
+ user will need to be able to write to it. We use chmod()
+ because xchmod() is too shy. */
+ chmod (info, 0666);
+ }
+
+ /* Make an empty val-tags file to prevent problems creating it later. */
+ strcpy (info, adm);
+ strcat (info, "/");
+ strcat (info, CVSROOTADM_VALTAGS);
+ if (!isfile (info))
+ {
+ FILE *fp;
+
+ fp = open_file (info, "w");
+ if (fclose (fp) < 0)
+ error (1, errno, "cannot close %s", info);
+
+ /* Make the new val-tags file world-writeable, since every CVS
+ user will need to be able to write to it. We use chmod()
+ because xchmod() is too shy. */
+ chmod (info, 0666);
}
free (info);
diff --git a/contrib/cvs/src/modules.c b/contrib/cvs/src/modules.c
index 9907cc8..0381ec9 100644
--- a/contrib/cvs/src/modules.c
+++ b/contrib/cvs/src/modules.c
@@ -120,10 +120,9 @@ do_module (db, mname, m_type, msg, callback_proc, where,
int modargc;
int xmodargc;
char **modargv;
- char **xmodargv;
+ char **xmodargv = NULL;
/* Found entry from modules file, including options and such. */
char *value = NULL;
- char *zvalue = NULL;
char *mwhere = NULL;
char *mfile = NULL;
char *spec_opt = NULL;
@@ -186,25 +185,21 @@ do_module (db, mname, m_type, msg, callback_proc, where,
val.dptr = NULL;
if (val.dptr != NULL)
{
- /* null terminate the value XXX - is this space ours? */
- val.dptr[val.dsize] = '\0';
+ /* copy and null terminate the value */
+ value = xmalloc (val.dsize + 1);
+ memcpy (value, val.dptr, val.dsize);
+ value[val.dsize] = '\0';
/* If the line ends in a comment, strip it off */
- if ((cp = strchr (val.dptr, '#')) != NULL)
- {
- do
- *cp-- = '\0';
- while (isspace ((unsigned char) *cp));
- }
+ if ((cp = strchr (value, '#')) != NULL)
+ *cp = '\0';
else
- {
- /* Always strip trailing spaces */
- cp = strchr (val.dptr, '\0');
- while (cp > val.dptr && isspace ((unsigned char) *--cp))
- *cp = '\0';
- }
+ cp = value + val.dsize;
+
+ /* Always strip trailing spaces */
+ while (cp > value && isspace ((unsigned char) *--cp))
+ *cp = '\0';
- value = val.dptr;
mwhere = xstrdup (mname);
goto found;
}
@@ -297,7 +292,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
error_exit ();
cwd_saved = 1;
- err += callback_proc (&modargc, modargv, where, mwhere, mfile,
+ err += callback_proc (modargc, modargv, where, mwhere, mfile,
shorten,
local_specified, mname, msg);
@@ -332,17 +327,20 @@ do_module (db, mname, m_type, msg, callback_proc, where,
{
char *cp2;
- /* null terminate the value XXX - is this space ours? */
- val.dptr[val.dsize] = '\0';
+ /* copy and null terminate the value */
+ value = xmalloc (val.dsize + 1);
+ memcpy (value, val.dptr, val.dsize);
+ value[val.dsize] = '\0';
/* If the line ends in a comment, strip it off */
- if ((cp2 = strchr (val.dptr, '#')) != NULL)
- {
- do
- *cp2-- = '\0';
- while (isspace ((unsigned char) *cp2));
- }
- value = val.dptr;
+ if ((cp2 = strchr (value, '#')) != NULL)
+ *cp2 = '\0';
+ else
+ cp2 = value + val.dsize;
+
+ /* Always strip trailing spaces */
+ while (cp2 > value && isspace ((unsigned char) *--cp2))
+ *cp2 = '\0';
/* mwhere gets just the module name */
mwhere = xstrdup (mname);
@@ -375,11 +373,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
error_exit ();
cwd_saved = 1;
- /* copy value to our own string since if we go recursive we'll be
- really screwed if we do another dbm lookup */
assert (value != NULL);
- zvalue = xstrdup (value);
- value = zvalue;
/* search the value for the special delimiter and save for later */
if ((cp = strchr (value, CVSMODULE_SPEC)) != NULL)
@@ -387,62 +381,9 @@ do_module (db, mname, m_type, msg, callback_proc, where,
*cp = '\0'; /* null out the special char */
spec_opt = cp + 1; /* save the options for later */
- if (cp != value) /* strip whitespace if necessary */
- while (isspace ((unsigned char) *--cp))
- *cp = '\0';
-
- if (cp == value)
- {
- /*
- * we had nothing but special options, so skip arg
- * parsing and regular stuff entirely
- *
- * If there were only special ones though, we must
- * make the appropriate directory and cd to it
- */
- char *dir;
-
- /* XXX - XXX - MAJOR HACK - DO NOT SHIP - this needs to
- be !pipeout, but we don't know that here yet */
- if (!run_module_prog)
- goto out;
-
- dir = where ? where : mname;
- /* XXX - think about making null repositories at each dir here
- instead of just at the bottom */
- make_directories (dir);
- if ( CVS_CHDIR (dir) < 0)
- {
- error (0, errno, "cannot chdir to %s", dir);
- spec_opt = NULL;
- err++;
- goto out;
- }
- if (!isfile (CVSADM))
- {
- char *nullrepos;
-
- nullrepos = emptydir_name ();
-
- Create_Admin (".", dir,
- nullrepos, (char *) NULL, (char *) NULL, 0, 0);
- if (!noexec)
- {
- FILE *fp;
-
- fp = open_file (CVSADM_ENTSTAT, "w+");
- if (fclose (fp) == EOF)
- error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
-#ifdef SERVER_SUPPORT
- if (server_active)
- server_set_entstat (dir, nullrepos);
-#endif
- }
- free (nullrepos);
- }
- out:
- goto do_special;
- }
+ /* strip whitespace if necessary */
+ while (cp > value && isspace ((unsigned char) *--cp))
+ *cp = '\0';
}
/* don't do special options only part of a module was specified */
@@ -460,7 +401,8 @@ do_module (db, mname, m_type, msg, callback_proc, where,
/* Put the value on a line with XXX prepended for getopt to eat */
line = xmalloc (strlen (value) + 10);
- (void) sprintf (line, "%s %s", "XXX", value);
+ strcpy(line, "XXX ");
+ strcpy(line + 4, value);
/* turn the line into an argv[] array */
line2argv (&xmodargc, &xmodargv, line, " \t");
@@ -478,56 +420,56 @@ do_module (db, mname, m_type, msg, callback_proc, where,
alias = 1;
break;
case 'd':
- nonalias_opt = 1;
if (mwhere)
free (mwhere);
mwhere = xstrdup (optarg);
+ nonalias_opt = 1;
break;
case 'i':
- nonalias_opt = 1;
if (checkin_prog)
free (checkin_prog);
checkin_prog = xstrdup (optarg);
+ nonalias_opt = 1;
break;
case 'l':
- nonalias_opt = 1;
local_specified = 1;
+ nonalias_opt = 1;
break;
case 'o':
- nonalias_opt = 1;
if (checkout_prog)
free (checkout_prog);
checkout_prog = xstrdup (optarg);
+ nonalias_opt = 1;
break;
case 'e':
- nonalias_opt = 1;
if (export_prog)
free (export_prog);
export_prog = xstrdup (optarg);
+ nonalias_opt = 1;
break;
case 't':
- nonalias_opt = 1;
if (tag_prog)
free (tag_prog);
tag_prog = xstrdup (optarg);
+ nonalias_opt = 1;
break;
case 'u':
- nonalias_opt = 1;
if (update_prog)
free (update_prog);
update_prog = xstrdup (optarg);
+ nonalias_opt = 1;
break;
case '?':
error (0, 0,
"modules file has invalid option for key %s value %s",
- key.dptr, val.dptr);
+ key.dptr, value);
err++;
goto do_module_return;
}
}
modargc -= optind;
modargv += optind;
- if (modargc == 0)
+ if (modargc == 0 && spec_opt == NULL)
{
error (0, 0, "modules file missing directory for module %s", mname);
++err;
@@ -575,15 +517,66 @@ module `%s' is a request for a file in a module which is not a directory",
}
/* otherwise, process this module */
- err += callback_proc (&modargc, modargv, where, mwhere, mfile, shorten,
- local_specified, mname, msg);
+ if (modargc > 0)
+ {
+ err += callback_proc (modargc, modargv, where, mwhere, mfile, shorten,
+ local_specified, mname, msg);
+ }
+ else
+ {
+ /*
+ * we had nothing but special options, so we must
+ * make the appropriate directory and cd to it
+ */
+ char *dir;
+
+ /* XXX - XXX - MAJOR HACK - DO NOT SHIP - this needs to
+ be !pipeout, but we don't know that here yet */
+ if (!run_module_prog)
+ goto do_special;
- free_names (&xmodargc, xmodargv);
+ dir = where ? where : (mwhere ? mwhere : mname);
+ /* XXX - think about making null repositories at each dir here
+ instead of just at the bottom */
+ make_directories (dir);
+ if ( CVS_CHDIR (dir) < 0)
+ {
+ error (0, errno, "cannot chdir to %s", dir);
+ spec_opt = NULL;
+ err++;
+ goto do_special;
+ }
+ if (!isfile (CVSADM))
+ {
+ char *nullrepos;
+
+ nullrepos = emptydir_name ();
+
+ Create_Admin (".", dir,
+ nullrepos, (char *) NULL, (char *) NULL, 0, 0, 1);
+ if (!noexec)
+ {
+ FILE *fp;
+
+ fp = open_file (CVSADM_ENTSTAT, "w+");
+ if (fclose (fp) == EOF)
+ error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
+#ifdef SERVER_SUPPORT
+ if (server_active)
+ server_set_entstat (dir, nullrepos);
+#endif
+ }
+ free (nullrepos);
+ }
+ }
/* if there were special include args, process them now */
do_special:
+ free_names (&xmodargc, xmodargv);
+ xmodargv = NULL;
+
/* blow off special options if -l was specified */
if (local_specified)
spec_opt = NULL;
@@ -635,7 +628,7 @@ module `%s' is a request for a file in a module which is not a directory",
/* strip whitespace off the end */
do
*cp = '\0';
- while (isspace ((unsigned char) *--cp));
+ while (cp > spec_opt && isspace ((unsigned char) *--cp));
}
else
next_opt = NULL;
@@ -745,6 +738,7 @@ module `%s' is a request for a file in a module which is not a directory",
cvs_output (": Executing '", 0);
run_print (stdout);
cvs_output ("'\n", 0);
+ cvs_flushout ();
}
err += run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
free (expanded_path);
@@ -755,6 +749,8 @@ module `%s' is a request for a file in a module which is not a directory",
do_module_return:
/* clean up */
+ if (xmodargv != NULL)
+ free_names (&xmodargc, xmodargv);
if (mwhere)
free (mwhere);
if (checkin_prog)
@@ -769,8 +765,8 @@ module `%s' is a request for a file in a module which is not a directory",
free (update_prog);
if (cwd_saved)
free_cwd (&cwd);
- if (zvalue != NULL)
- free (zvalue);
+ if (value != NULL)
+ free (value);
if (xvalue != NULL)
free (xvalue);
diff --git a/contrib/cvs/src/myndbm.c b/contrib/cvs/src/myndbm.c
index f674ac1..7795f66 100644
--- a/contrib/cvs/src/myndbm.c
+++ b/contrib/cvs/src/myndbm.c
@@ -211,7 +211,8 @@ mydbm_load_file (fp, list)
value = xmalloc (value_allocated);
cont = 0;
- while ((line_length = getstr (&line, &line_size, fp, '\012', 0)) >= 0)
+ while ((line_length =
+ getstr (&line, &line_size, fp, '\012', 0, GETLINE_NO_LIMIT)) >= 0)
{
if (line_length > 0 && line[line_length - 1] == '\012')
{
diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c
index 1c1ab70..0bf6d3c 100644
--- a/contrib/cvs/src/parseinfo.c
+++ b/contrib/cvs/src/parseinfo.c
@@ -10,6 +10,8 @@
#include "getline.h"
#include <assert.h>
+extern char *logHistory;
+
/*
* Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
* the first line in the file that matches the REPOSITORY, or if ALL != 0, any lines
@@ -32,7 +34,7 @@ Parse_Info (infofile, repository, callproc, all)
char *default_value = NULL;
char *expanded_value= NULL;
int callback_done, line_number;
- char *cp, *exp, *value, *srepos;
+ char *cp, *exp, *value, *srepos, bad;
const char *regex_err;
if (CVSroot_original == NULL)
@@ -110,10 +112,6 @@ Parse_Info (infofile, repository, callproc, all)
if (expanded_value != NULL)
free (expanded_value);
expanded_value = expand_path (value, infofile, line_number);
- if (!expanded_value)
- {
- continue;
- }
/*
* At this point, exp points to the regular expression, and value
@@ -127,9 +125,10 @@ Parse_Info (infofile, repository, callproc, all)
{
/* Is it OK to silently ignore all but the last DEFAULT
expression? */
- if (default_value != NULL)
+ if (default_value != NULL && default_value != &bad)
free (default_value);
- default_value = xstrdup (expanded_value);
+ default_value = (expanded_value != NULL ?
+ xstrdup (expanded_value) : &bad);
continue;
}
@@ -140,11 +139,13 @@ Parse_Info (infofile, repository, callproc, all)
*/
if (strcmp (exp, "ALL") == 0)
{
- if (all)
- err += callproc (repository, expanded_value);
- else
+ if (!all)
error(0, 0, "Keyword `ALL' is ignored at line %d in %s file",
line_number, infofile);
+ else if (expanded_value != NULL)
+ err += callproc (repository, expanded_value);
+ else
+ err++;
continue;
}
@@ -163,7 +164,10 @@ Parse_Info (infofile, repository, callproc, all)
continue; /* no match */
/* it did, so do the callback and note that we did one */
- err += callproc (repository, expanded_value);
+ if (expanded_value != NULL)
+ err += callproc (repository, expanded_value);
+ else
+ err++;
callback_done = 1;
}
if (ferror (fp_info))
@@ -173,10 +177,15 @@ Parse_Info (infofile, repository, callproc, all)
/* if we fell through and didn't callback at all, do the default */
if (callback_done == 0 && default_value != NULL)
- err += callproc (repository, default_value);
+ {
+ if (default_value != &bad)
+ err += callproc (repository, default_value);
+ else
+ err++;
+ }
/* free up space if necessary */
- if (default_value != NULL)
+ if (default_value != NULL && default_value != &bad)
free (default_value);
if (expanded_value != NULL)
free (expanded_value);
@@ -367,6 +376,14 @@ warning: this CVS does not support PreservePermissions");
opendir it or something, but I don't see any particular
reason to do that now rather than waiting until lock.c. */
}
+ else if (strcmp (line, "LogHistory") == 0)
+ {
+ if (strcmp (p, "all") != 0)
+ {
+ logHistory=malloc(strlen (p) + 1);
+ strcpy (logHistory, p);
+ }
+ }
else
{
/* We may be dealing with a keyword which was added in a
diff --git a/contrib/cvs/src/patch.c b/contrib/cvs/src/patch.c
index f16a331..9aa26f3 100644
--- a/contrib/cvs/src/patch.c
+++ b/contrib/cvs/src/patch.c
@@ -20,7 +20,7 @@ static Dtype patch_dirproc PROTO ((void *callerdat, char *dir,
char *repos, char *update_dir,
List *entries));
static int patch_fileproc PROTO ((void *callerdat, struct file_info *finfo));
-static int patch_proc PROTO((int *pargc, char **argv, char *xwhere,
+static int patch_proc PROTO((int argc, char **argv, char *xwhere,
char *mwhere, char *mfile, int shorten,
int local_specified, char *mname, char *msg));
@@ -230,6 +230,9 @@ patch (argc, argv)
#endif
/* clean up if we get a signal */
+#ifdef SIGABRT
+ (void) SIG_register (SIGABRT, patch_cleanup);
+#endif
#ifdef SIGHUP
(void) SIG_register (SIGHUP, patch_cleanup);
#endif
@@ -261,9 +264,9 @@ patch (argc, argv)
*/
/* ARGSUSED */
static int
-patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
+patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
mname, msg)
- int *pargc;
+ int argc;
char **argv;
char *xwhere;
char *mwhere;
@@ -273,6 +276,7 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
char *mname;
char *msg;
{
+ char *myargv[2];
int err = 0;
int which;
char *repository;
@@ -314,13 +318,10 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
}
else
{
- int i;
-
- /* a file means muck argv */
- for (i = 1; i < *pargc; i++)
- free (argv[i]);
- argv[1] = xstrdup (mfile);
- (*pargc) = 2;
+ myargv[0] = argv[0];
+ myargv[1] = mfile;
+ argc = 2;
+ argv = myargv;
}
free (path);
}
@@ -341,19 +342,19 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
if (rev1 != NULL && !rev1_validated)
{
- tag_check_valid (rev1, *pargc - 1, argv + 1, local, 0, NULL);
+ tag_check_valid (rev1, argc - 1, argv + 1, local, 0, NULL);
rev1_validated = 1;
}
if (rev2 != NULL && !rev2_validated)
{
- tag_check_valid (rev2, *pargc - 1, argv + 1, local, 0, NULL);
+ tag_check_valid (rev2, argc - 1, argv + 1, local, 0, NULL);
rev2_validated = 1;
}
/* start the recursion processor */
err = start_recursion (patch_fileproc, (FILESDONEPROC) NULL, patch_dirproc,
(DIRLEAVEPROC) NULL, NULL,
- *pargc - 1, argv + 1, local,
+ argc - 1, argv + 1, local,
which, 0, 1, where, 1);
free (where);
@@ -735,6 +736,10 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs);
tmpfile1 = tmpfile2 = tmpfile3 = NULL;
out2:
+ if (vers_tag != NULL)
+ free (vers_tag);
+ if (vers_head != NULL)
+ free (vers_head);
if (rcs != NULL)
free (rcs);
return (ret);
diff --git a/contrib/cvs/src/rcs.c b/contrib/cvs/src/rcs.c
index 64524b1..b28572c 100644
--- a/contrib/cvs/src/rcs.c
+++ b/contrib/cvs/src/rcs.c
@@ -60,6 +60,7 @@ static int rcsbuf_getkey PROTO ((struct rcsbuffer *, char **keyp,
static int rcsbuf_getrevnum PROTO ((struct rcsbuffer *, char **revp));
static char *rcsbuf_fill PROTO ((struct rcsbuffer *, char *ptr, char **keyp,
char **valp));
+static int rcsbuf_valcmp PROTO ((struct rcsbuffer *));
static char *rcsbuf_valcopy PROTO ((struct rcsbuffer *, char *val, int polish,
size_t *lenp));
static void rcsbuf_valpolish PROTO ((struct rcsbuffer *, char *val, int polish,
@@ -154,6 +155,7 @@ static const char spacetab[] = {
#define whitespace(c) (spacetab[(unsigned char)c] != 0)
static char *rcs_lockfile;
+static int rcs_lockfd = -1;
/* A few generic thoughts on error handling, in particular the
printing of unexpected characters that we find in the RCS file
@@ -542,9 +544,10 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
if (rdata->other == NULL)
rdata->other = getlist ();
kv = getnode ();
- kv->type = RCSFIELD;
+ kv->type = rcsbuf_valcmp (&rcsbuf) ? RCSCMPFLD : RCSFIELD;
kv->key = xstrdup (key);
- kv->data = rcsbuf_valcopy (&rcsbuf, value, 1, (size_t *) NULL);
+ kv->data = rcsbuf_valcopy (&rcsbuf, value, kv->type == RCSFIELD,
+ (size_t *) NULL);
if (addnode (rdata->other, kv) != 0)
{
error (0, 0, "warning: duplicate key `%s' in RCS file `%s'",
@@ -590,9 +593,7 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
key, rcsfile);
free (rdata->desc);
}
- /* Don't need to rcsbuf_valcopy `value' because
- getdelta already did that. */
- rdata->desc = xstrdup (value);
+ rdata->desc = rcsbuf_valcopy (&rcsbuf, value, 1, (size_t *) NULL);
}
rdata->delta_pos = rcsbuf_ftell (&rcsbuf);
@@ -748,9 +749,10 @@ RCS_fully_parse (rcs)
if (vnode->other == NULL)
vnode->other = getlist ();
kv = getnode ();
- kv->type = RCSFIELD;
+ kv->type = rcsbuf_valcmp (&rcsbuf) ? RCSCMPFLD : RCSFIELD;
kv->key = xstrdup (key);
- kv->data = rcsbuf_valcopy (&rcsbuf, value, 1, (size_t *) NULL);
+ kv->data = rcsbuf_valcopy (&rcsbuf, value, kv->type == RCSFIELD,
+ (size_t *) NULL);
if (addnode (vnode->other, kv) != 0)
{
error (0, 0,
@@ -1028,6 +1030,9 @@ rcsbuf_close (rcsbuf)
characters. Call rcsbuf_valcopy or rcsbuf_valpolish to do
appropriate massaging. */
+/* Note that the extreme hair in rcsbuf_getkey is because profiling
+ statistics show that it was worth it. */
+
static int
rcsbuf_getkey (rcsbuf, keyp, valp)
struct rcsbuffer *rcsbuf;
@@ -1283,13 +1288,10 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
}
/* The value extends past the '@' string. We need to undo the
- closing of the '@' done in the default case above. This
+ '@' stripping done in the default case above. This
case never happens in a plain RCS file, but it can happen
if user defined phrases are used. */
- if (rcsbuf->vlen != 0)
- (*valp)[rcsbuf->vlen] = ' ';
- else
- *valp = ptr;
+ ((*valp)--)[rcsbuf->vlen++] = '@';
}
/* Here we have a value which is not a simple '@' string. We need
@@ -1346,8 +1348,8 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
return 1;
}
- /* We found an '@' string in the value. We set
- RCSBUF->AT_STRING, which means that we won't be able to
+ /* We found an '@' string in the value. We set RCSBUF->AT_STRING
+ and RCSBUF->EMBEDDED_AT to indicate that we won't be able to
compress whitespace correctly for this type of value.
Since this type of value never arises in a normal RCS file,
this should not be a big deal. It means that if anybody
@@ -1356,8 +1358,7 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
themselves. */
rcsbuf->at_string = 1;
-
- *pat = ' ';
+ rcsbuf->embedded_at = -1;
ptr = pat + 1;
@@ -1392,495 +1393,16 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
break;
/* We found an '@' pair in the string. Keep looking. */
- ++rcsbuf->embedded_at;
ptr = pat + 2;
}
/* Here PAT points to the final '@' in the string. */
-
- *pat = ' ';
-
ptr = pat + 1;
}
#undef my_whitespace
}
-/* TODO: Eliminate redundant code in rcsbuf_getkey, rcsbuf_getid,
- rcsbuf_getstring, rcsbuf_getword. These last three functions were
- all created by hacking monstrous swaths of code from rcsbuf_getkey,
- and some engineering would make the code easier to read and
- maintain.
-
- Note that the extreme hair in rcsbuf_getkey is because profiling
- statistics show that it was worth it.
-
- We probably could be processing "hardlinks" by first calling
- rcsbuf_getkey, and breaking up the value afterwards; the code to
- break it up would not need to be hacked for speed. This would
- remove the need for rcsbuf_getword, rcsbuf_getid, and
- rcsbuf_getstring, as the other calls are easy to remove. */
-
-/* Read an `id' (in the sense of rcsfile(5)) from RCSBUF, and store in
- IDP. */
-
-static int
-rcsbuf_getid (rcsbuf, idp)
- struct rcsbuffer *rcsbuf;
- char **idp;
-{
- register const char * const my_spacetab = spacetab;
- register char *ptr, *ptrend;
- char c;
-
-#define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0)
-
- rcsbuf->vlen = 0;
- rcsbuf->at_string = 0;
- rcsbuf->embedded_at = 0;
-
- ptr = rcsbuf->ptr;
- ptrend = rcsbuf->ptrend;
-
- /* Sanity check. */
- if (ptr < rcsbuf_buffer || ptr > rcsbuf_buffer + rcsbuf_buffer_size)
- abort ();
-
- /* If the pointer is more than RCSBUF_BUFSIZE bytes into the
- buffer, move back to the start of the buffer. This keeps the
- buffer from growing indefinitely. */
- if (ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
- {
- int len;
-
- len = ptrend - ptr;
-
- /* Sanity check: we don't read more than RCSBUF_BUFSIZE bytes
- at a time, so we can't have more bytes than that past PTR. */
- if (len > RCSBUF_BUFSIZE)
- abort ();
-
- /* Update the POS field, which holds the file offset of the
- first byte in the RCSBUF_BUFFER buffer. */
- rcsbuf->pos += ptr - rcsbuf_buffer;
-
- memcpy (rcsbuf_buffer, ptr, len);
- ptr = rcsbuf_buffer;
- ptrend = ptr + len;
- rcsbuf->ptrend = ptrend;
- }
-
- /* Skip leading whitespace. */
-
- while (1)
- {
- if (ptr >= ptrend)
- {
- ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
- if (ptr == NULL)
- return 0;
- ptrend = rcsbuf->ptrend;
- }
-
- c = *ptr;
- if (! my_whitespace (c))
- break;
-
- ++ptr;
- }
-
- /* We've found the start of the key. */
-
- *idp = ptr;
-
- if (c != ';')
- {
- while (1)
- {
- ++ptr;
- if (ptr >= ptrend)
- {
- ptr = rcsbuf_fill (rcsbuf, ptr, idp, (char **) NULL);
- if (ptr == NULL)
- error (1, 0, "EOF in key in RCS file %s",
- rcsbuf->filename);
- ptrend = rcsbuf->ptrend;
- }
- c = *ptr;
- if (c == ';' || my_whitespace (c))
- break;
- }
- }
-
- /* Here *IDP points to the id in the buffer, C is the character
- we found at the end of the key, and PTR points to the location in
- the buffer where we found C. We may not set *PTR to \0, because
- it may overwrite a terminating semicolon. The calling function
- must copy and terminate the id on its own. */
-
- rcsbuf->ptr = ptr;
- return 1;
-
-#undef my_whitespace
-}
-
-/* Read an RCS @-delimited string. Store the result in STRP. */
-
-static int
-rcsbuf_getstring (rcsbuf, strp)
- struct rcsbuffer *rcsbuf;
- char **strp;
-{
- register const char * const my_spacetab = spacetab;
- register char *ptr, *ptrend;
- char *pat;
- size_t vlen;
- char c;
-
-#define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0)
-
- rcsbuf->vlen = 0;
- rcsbuf->at_string = 0;
- rcsbuf->embedded_at = 0;
-
- ptr = rcsbuf->ptr;
- ptrend = rcsbuf->ptrend;
-
- /* Sanity check. */
- if (ptr < rcsbuf_buffer || ptr > rcsbuf_buffer + rcsbuf_buffer_size)
- abort ();
-
- /* If the pointer is more than RCSBUF_BUFSIZE bytes into the
- buffer, move back to the start of the buffer. This keeps the
- buffer from growing indefinitely. */
- if (ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
- {
- int len;
-
- len = ptrend - ptr;
-
- /* Sanity check: we don't read more than RCSBUF_BUFSIZE bytes
- at a time, so we can't have more bytes than that past PTR. */
- if (len > RCSBUF_BUFSIZE)
- abort ();
-
- /* Update the POS field, which holds the file offset of the
- first byte in the RCSBUF_BUFFER buffer. */
- rcsbuf->pos += ptr - rcsbuf_buffer;
-
- memcpy (rcsbuf_buffer, ptr, len);
- ptr = rcsbuf_buffer;
- ptrend = ptr + len;
- rcsbuf->ptrend = ptrend;
- }
-
- /* Skip leading whitespace. */
-
- while (1)
- {
- if (ptr >= ptrend)
- {
- ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
- if (ptr == NULL)
- error (1, 0, "unexpected end of file reading %s",
- rcsbuf->filename);
- ptrend = rcsbuf->ptrend;
- }
-
- c = *ptr;
- if (! my_whitespace (c))
- break;
-
- ++ptr;
- }
-
- /* PTR should now point to the start of a string. */
- if (c != '@')
- error (1, 0, "expected @-string at '\\x%x' in %s",
- c, rcsbuf->filename);
-
- /* Optimize the common case of a value composed of a single
- '@' string. */
-
- rcsbuf->at_string = 1;
-
- ++ptr;
-
- *strp = ptr;
-
- while (1)
- {
- while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
- {
- /* Note that we pass PTREND as the PTR value to
- rcsbuf_fill, so that we will wind up setting PTR to
- the location corresponding to the old PTREND, so
- that we don't search the same bytes again. */
- ptr = rcsbuf_fill (rcsbuf, ptrend, NULL, strp);
- if (ptr == NULL)
- error (1, 0,
- "EOF while looking for end of string in RCS file %s",
- rcsbuf->filename);
- ptrend = rcsbuf->ptrend;
- }
-
- /* Handle the special case of an '@' right at the end of
- the known bytes. */
- if (pat + 1 >= ptrend)
- {
- /* Note that we pass PAT, not PTR, here. */
- pat = rcsbuf_fill (rcsbuf, pat, NULL, strp);
- if (pat == NULL)
- {
- /* EOF here is OK; it just means that the last
- character of the file was an '@' terminating a
- value for a key type which does not require a
- trailing ';'. */
- pat = rcsbuf->ptrend - 1;
-
- }
- ptrend = rcsbuf->ptrend;
-
- /* Note that the value of PTR is bogus here. This is
- OK, because we don't use it. */
- }
-
- if (pat + 1 >= ptrend || pat[1] != '@')
- break;
-
- /* We found an '@' pair in the string. Keep looking. */
- ++rcsbuf->embedded_at;
- ptr = pat + 2;
- }
-
- /* Here PAT points to the final '@' in the string. */
-
- *pat = '\0';
-
- vlen = pat - *strp;
- if (vlen == 0)
- *strp = NULL;
- rcsbuf->vlen = vlen;
- rcsbuf->ptr = pat + 1;
-
- return 1;
-
-#undef my_whitespace
-}
-
-/* Read an RCS `word', in the sense of rcsfile(5) (an id, a num, a
- @-delimited string, or `:'). Store the result in WORDP. If a
- `;' is reached without reading any text, the result is NULL. */
-
-static int
-rcsbuf_getword (rcsbuf, wordp)
- struct rcsbuffer *rcsbuf;
- char **wordp;
-{
- register const char * const my_spacetab = spacetab;
- register char *ptr, *ptrend;
- char c;
-
-#define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0)
-
- rcsbuf->vlen = 0;
- rcsbuf->at_string = 0;
- rcsbuf->embedded_at = 0;
-
- ptr = rcsbuf->ptr;
- ptrend = rcsbuf->ptrend;
-
- /* Sanity check. */
- if (ptr < rcsbuf_buffer || ptr > rcsbuf_buffer + rcsbuf_buffer_size)
- abort ();
-
- /* If the pointer is more than RCSBUF_BUFSIZE bytes into the
- buffer, move back to the start of the buffer. This keeps the
- buffer from growing indefinitely. */
- if (ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
- {
- int len;
-
- len = ptrend - ptr;
-
- /* Sanity check: we don't read more than RCSBUF_BUFSIZE bytes
- at a time, so we can't have more bytes than that past PTR. */
- if (len > RCSBUF_BUFSIZE)
- abort ();
-
- /* Update the POS field, which holds the file offset of the
- first byte in the RCSBUF_BUFFER buffer. */
- rcsbuf->pos += ptr - rcsbuf_buffer;
-
- memcpy (rcsbuf_buffer, ptr, len);
- ptr = rcsbuf_buffer;
- ptrend = ptr + len;
- rcsbuf->ptrend = ptrend;
- }
-
- /* Skip leading whitespace. */
-
- while (1)
- {
- if (ptr >= ptrend)
- {
- ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
- if (ptr == NULL)
- error (1, 0, "unexpected end of file reading %s",
- rcsbuf->filename);
- ptrend = rcsbuf->ptrend;
- }
-
- c = *ptr;
- if (! my_whitespace (c))
- break;
-
- ++ptr;
- }
-
- /* If we have reached `;', there is no value. */
- if (c == ';')
- {
- *wordp = NULL;
- *ptr++ = '\0';
- rcsbuf->ptr = ptr;
- rcsbuf->vlen = 0;
- return 1;
- }
-
- /* PTR now points to the start of a value. Find out whether it is
- a num, an id, a string or a colon. */
- if (c == ':')
- {
- *wordp = ptr++;
- rcsbuf->ptr = ptr;
- rcsbuf->vlen = 1;
- return 1;
- }
-
- if (c == '@')
- {
- char *pat;
- size_t vlen;
-
- /* Optimize the common case of a value composed of a single
- '@' string. */
-
- rcsbuf->at_string = 1;
-
- ++ptr;
-
- *wordp = ptr;
-
- while (1)
- {
- while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
- {
- /* Note that we pass PTREND as the PTR value to
- rcsbuf_fill, so that we will wind up setting PTR to
- the location corresponding to the old PTREND, so
- that we don't search the same bytes again. */
- ptr = rcsbuf_fill (rcsbuf, ptrend, NULL, wordp);
- if (ptr == NULL)
- error (1, 0,
- "EOF while looking for end of string in RCS file %s",
- rcsbuf->filename);
- ptrend = rcsbuf->ptrend;
- }
-
- /* Handle the special case of an '@' right at the end of
- the known bytes. */
- if (pat + 1 >= ptrend)
- {
- /* Note that we pass PAT, not PTR, here. */
- pat = rcsbuf_fill (rcsbuf, pat, NULL, wordp);
- if (pat == NULL)
- {
- /* EOF here is OK; it just means that the last
- character of the file was an '@' terminating a
- value for a key type which does not require a
- trailing ';'. */
- pat = rcsbuf->ptrend - 1;
-
- }
- ptrend = rcsbuf->ptrend;
-
- /* Note that the value of PTR is bogus here. This is
- OK, because we don't use it. */
- }
-
- if (pat + 1 >= ptrend || pat[1] != '@')
- break;
-
- /* We found an '@' pair in the string. Keep looking. */
- ++rcsbuf->embedded_at;
- ptr = pat + 2;
- }
-
- /* Here PAT points to the final '@' in the string. */
-
- *pat = '\0';
-
- vlen = pat - *wordp;
- if (vlen == 0)
- *wordp = NULL;
- rcsbuf->vlen = vlen;
- rcsbuf->ptr = pat + 1;
-
- return 1;
- }
-
- /* C is neither `:', `;' nor `@', so it should be the start of a num
- or an id. Make sure it is not another special character. */
- if (c == '$' || c == '.' || c == ',')
- {
- error (1, 0, "illegal special character in RCS field in %s",
- rcsbuf->filename);
- }
-
- *wordp = ptr;
- while (1)
- {
- if (ptr >= ptrend)
- {
- ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, wordp);
- if (ptr == NULL)
- error (1, 0, "unexpected end of file reading %s",
- rcsbuf->filename);
- ptrend = rcsbuf->ptrend;
- }
-
- /* Legitimate ID characters are digits, dots and any `graphic
- printing character that is not a special.' This test ought
- to do the trick. */
- c = *ptr;
- if (isprint ((unsigned char) c) &&
- c != ';' && c != '$' && c != ',' && c != '@' && c != ':')
- {
- ++ptr;
- continue;
- }
- break;
- }
-
- /* PTR points to the last non-id character in this word, and C is
- the character in its memory cell. Check to make sure that it
- is a legitimate word delimiter -- whitespace or semicolon. */
- if (c == ';' || my_whitespace (c))
- {
- rcsbuf->vlen = ptr - *wordp;
- rcsbuf->ptr = ptr;
- return 1;
- }
-
- error (1, 0, "illegal special character in RCS field in %s",
- rcsbuf->filename);
- /* Shut up compiler warnings. */
- return 0;
-
-#undef my_whitespace
-}
-
/* Read an RCS revision number from an RCS file. This sets *REVP to
point to the revision number; it will point to space that is
managed by the rcsbuf functions, and is only good until the next
@@ -1984,6 +1506,8 @@ rcsbuf_fill (rcsbuf, ptr, keyp, valp)
koff = *keyp - rcsbuf_buffer;
if (valp != NULL && *valp != NULL)
voff = *valp - rcsbuf_buffer;
+ koff = keyp == NULL ? 0 : *keyp - rcsbuf_buffer;
+ voff = valp == NULL ? 0 : *valp - rcsbuf_buffer;
expand_string (&rcsbuf_buffer, &rcsbuf_buffer_size,
rcsbuf_buffer_size + RCSBUF_BUFSIZE);
@@ -2009,6 +1533,16 @@ rcsbuf_fill (rcsbuf, ptr, keyp, valp)
return ptr;
}
+/* Test whether the last value returned by rcsbuf_getkey is a composite
+ value or not. */
+
+static int
+rcsbuf_valcmp (rcsbuf)
+ struct rcsbuffer *rcsbuf;
+{
+ return rcsbuf->at_string && rcsbuf->embedded_at < 0;
+}
+
/* Copy the value VAL returned by rcsbuf_getkey into a memory buffer,
returning the memory buffer. Polish the value like
rcsbuf_valpolish, q.v. */
@@ -2032,7 +1566,7 @@ rcsbuf_valcopy (rcsbuf, val, polish, lenp)
}
vlen = rcsbuf->vlen;
- embedded_at = rcsbuf->embedded_at;
+ embedded_at = rcsbuf->embedded_at < 0 ? 0 : rcsbuf->embedded_at;
ret = xmalloc (vlen - embedded_at + 1);
@@ -2139,6 +1673,7 @@ rcsbuf_valpolish_internal (rcsbuf, to, from, lenp)
orig_to = to;
embedded_at = rcsbuf->embedded_at;
+ assert (embedded_at > 0);
if (lenp != NULL)
*lenp = len - embedded_at;
@@ -2187,6 +1722,112 @@ rcsbuf_valpolish_internal (rcsbuf, to, from, lenp)
}
}
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
+
+/* Copy the next word from the value VALP returned by rcsbuf_getkey into a
+ memory buffer, updating VALP and returning the memory buffer. Return
+ NULL when there are no more words. */
+
+static char *
+rcsbuf_valword (rcsbuf, valp)
+ struct rcsbuffer *rcsbuf;
+ char **valp;
+{
+ register const char * const my_spacetab = spacetab;
+ register char *ptr, *pat;
+ char c;
+
+#define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0)
+
+ if (*valp == NULL)
+ return NULL;
+
+ for (ptr = *valp; my_whitespace (*ptr); ++ptr) ;
+ if (*ptr == '\0')
+ {
+ assert (ptr - *valp == rcsbuf->vlen);
+ *valp = NULL;
+ rcsbuf->vlen = 0;
+ return NULL;
+ }
+
+ /* PTR now points to the start of a value. Find out whether it is
+ a num, an id, a string or a colon. */
+ c = *ptr;
+ if (c == ':')
+ {
+ rcsbuf->vlen -= ++ptr - *valp;
+ *valp = ptr;
+ return xstrdup (":");
+ }
+
+ if (c == '@')
+ {
+ int embedded_at = 0;
+ size_t vlen;
+
+ pat = ++ptr;
+ while ((pat = strchr (pat, '@')) != NULL)
+ {
+ if (pat[1] != '@')
+ break;
+ ++embedded_at;
+ pat += 2;
+ }
+
+ /* Here PAT points to the final '@' in the string. */
+ *pat++ = '\0';
+ assert (rcsbuf->at_string);
+ vlen = rcsbuf->vlen - (pat - *valp);
+ rcsbuf->vlen = pat - ptr - 1;
+ rcsbuf->embedded_at = embedded_at;
+ ptr = rcsbuf_valcopy (rcsbuf, ptr, 0, (size_t *) NULL);
+ *valp = pat;
+ rcsbuf->vlen = vlen;
+ if (strchr (pat, '@') == NULL)
+ rcsbuf->at_string = 0;
+ else
+ rcsbuf->embedded_at = -1;
+ return ptr;
+ }
+
+ /* *PTR is neither `:', `;' nor `@', so it should be the start of a num
+ or an id. Make sure it is not another special character. */
+ if (c == '$' || c == '.' || c == ',')
+ {
+ error (1, 0, "illegal special character in RCS field in %s",
+ rcsbuf->filename);
+ }
+
+ pat = ptr;
+ while (1)
+ {
+ /* Legitimate ID characters are digits, dots and any `graphic
+ printing character that is not a special.' This test ought
+ to do the trick. */
+ c = *++pat;
+ if (!isprint ((unsigned char) c) ||
+ c == ';' || c == '$' || c == ',' || c == '@' || c == ':')
+ break;
+ }
+
+ /* PAT points to the last non-id character in this word, and C is
+ the character in its memory cell. Check to make sure that it
+ is a legitimate word delimiter -- whitespace or end. */
+ if (c != '\0' && !my_whitespace (c))
+ error (1, 0, "illegal special character in RCS field in %s",
+ rcsbuf->filename);
+
+ *pat = '\0';
+ rcsbuf->vlen -= pat - *valp;
+ *valp = pat;
+ return xstrdup (ptr);
+
+#undef my_whitespace
+}
+
+#endif
+
/* Return the current position of an rcsbuf. */
static unsigned long
@@ -2864,8 +2505,8 @@ RCS_nodeisbranch (rcs, rev)
return (1);
}
free (magic);
- free (version);
}
+ free (version);
return (0);
}
@@ -2914,8 +2555,8 @@ RCS_whatbranch (rcs, rev)
return (magic);
}
free (magic);
- free (version);
}
+ free (version);
return ((char *) NULL);
}
@@ -4067,6 +3708,7 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
uses for ci -k. */
if (kw == KEYWORD_LOG
&& (sizeof "checked in with -k by " <= loglen
+ || log == NULL
|| strncmp (log, "checked in with -k by ",
sizeof "checked in with -k by " - 1) != 0))
{
@@ -4085,6 +3727,10 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
if (expand != KFLAG_V)
++s;
+ /* CVS never has empty log messages, but old RCS files might. */
+ if (log == NULL)
+ log = "";
+
/* Find the start of the line. */
start = srch;
while (start > buf && start[-1] != '\n')
@@ -4655,6 +4301,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
#ifdef PRESERVE_PERMISSIONS_SUPPORT
else if (special_file)
{
+#ifdef HAVE_MKNOD
char *dest;
/* Can send either to WORKFILE or to SOUT, as long as SOUT is
@@ -4675,6 +4322,11 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (mknod (dest, special_file, devnum) < 0)
error (1, errno, "could not create special file %s",
dest);
+#else
+ error (1, 0,
+"cannot create %s: unable to create special files on this system",
+workfile);
+#endif
}
#endif
else
@@ -5038,8 +4690,10 @@ RCS_addbranch (rcs, branch)
if (nodep == NULL)
{
error (0, 0, "%s: can't find branch point %s", rcs->path, branchpoint);
+ free (branchpoint);
return NULL;
}
+ free (branchpoint);
branchnode = (RCSVers *) nodep->data;
/* If BRANCH was a full branch number, make sure it is higher than MAX. */
@@ -5241,6 +4895,7 @@ RCS_checkin (rcs, workfile, message, rev, flags)
if (S_ISLNK (sb.st_mode))
{
np = getnode();
+ np->type = RCSFIELD;
np->key = xstrdup ("symlink");
np->data = xreadlink (workfile);
addnode (delta->other_delta, np);
@@ -5249,18 +4904,21 @@ RCS_checkin (rcs, workfile, message, rev, flags)
{
(void) sprintf (buf, "%u", sb.st_uid);
np = getnode();
+ np->type = RCSFIELD;
np->key = xstrdup ("owner");
np->data = xstrdup (buf);
addnode (delta->other_delta, np);
(void) sprintf (buf, "%u", sb.st_gid);
np = getnode();
+ np->type = RCSFIELD;
np->key = xstrdup ("group");
np->data = xstrdup (buf);
addnode (delta->other_delta, np);
(void) sprintf (buf, "%o", sb.st_mode & 07777);
np = getnode();
+ np->type = RCSFIELD;
np->key = xstrdup ("permissions");
np->data = xstrdup (buf);
addnode (delta->other_delta, np);
@@ -5271,7 +4929,9 @@ RCS_checkin (rcs, workfile, message, rev, flags)
case S_IFREG: break;
case S_IFCHR:
case S_IFBLK:
+#ifdef HAVE_ST_RDEV
np = getnode();
+ np->type = RCSFIELD;
np->key = xstrdup ("special");
sprintf (buf, "%s %lu",
((sb.st_mode & S_IFMT) == S_IFCHR
@@ -5279,6 +4939,11 @@ RCS_checkin (rcs, workfile, message, rev, flags)
(unsigned long) sb.st_rdev);
np->data = xstrdup (buf);
addnode (delta->other_delta, np);
+#else
+ error (0, 0,
+"can't preserve %s: unable to save device files on this system",
+workfile);
+#endif
break;
default:
@@ -5323,8 +4988,9 @@ RCS_checkin (rcs, workfile, message, rev, flags)
delta->version = xstrdup (newrev);
nodep = getnode();
nodep->type = RCSVERS;
- nodep->key = xstrdup (newrev);
+ nodep->delproc = rcsvers_delproc;
nodep->data = (char *) delta;
+ nodep->key = delta->version;
(void) addnode (rcs->versions, nodep);
dtext->version = xstrdup (newrev);
@@ -5358,7 +5024,6 @@ RCS_checkin (rcs, workfile, message, rev, flags)
error (1, errno, "cannot ftell for %s", rcs->path);
putdeltatext (fout, dtext);
rcs_internal_unlockfile (fout, rcs->path);
- freedeltatext (dtext);
if ((flags & RCS_FLAGS_KEEPFILE) == 0)
{
@@ -5370,7 +5035,8 @@ RCS_checkin (rcs, workfile, message, rev, flags)
if (!checkin_quiet)
cvs_output ("done\n", 5);
- return 0;
+ status = 0;
+ goto checkin_done;
}
/* Derive a new revision number. From the `ci' man page:
@@ -5466,6 +5132,13 @@ RCS_checkin (rcs, workfile, message, rev, flags)
goto checkin_done;
}
delta->version = RCS_addbranch (rcs, branch);
+ if (!delta->version)
+ {
+ free (branch);
+ free (newrev);
+ status = 1;
+ goto checkin_done;
+ }
adding_branch = 1;
p = strrchr (branch, '.');
*p = '\0';
@@ -5690,8 +5363,9 @@ RCS_checkin (rcs, workfile, message, rev, flags)
rcs->versions = getlist();
nodep = getnode();
nodep->type = RCSVERS;
- nodep->key = xstrdup (delta->version);
+ nodep->delproc = rcsvers_delproc;
nodep->data = (char *) delta;
+ nodep->key = delta->version;
(void) addnode (rcs->versions, nodep);
/* Write the new RCS file, inserting the new delta at COMMITPT. */
@@ -5714,8 +5388,10 @@ RCS_checkin (rcs, workfile, message, rev, flags)
}
if (unlink_file (tmpfile) < 0)
error (0, errno, "cannot remove %s", tmpfile);
+ free (tmpfile);
if (unlink_file (changefile) < 0)
error (0, errno, "cannot remove %s", changefile);
+ free (changefile);
if (!checkin_quiet)
cvs_output ("done\n", 5);
@@ -5798,6 +5474,7 @@ RCS_cmp_file (rcs, rev, options, filename)
retcode = xcmp (tmp, filename);
if (CVS_UNLINK (tmp) < 0)
error (0, errno, "cannot remove %s", tmp);
+ free (tmp);
return retcode;
}
else
@@ -6158,17 +5835,14 @@ RCS_unlock (rcs, rev, unlock_quiet)
lock = NULL;
for (p = locks->list->next; p != locks->list; p = p->next)
{
- if (STREQ (p->data, user))
+ if (lock != NULL)
{
- if (lock != NULL)
- {
- if (!unlock_quiet)
- error (0, 0, "\
+ if (!unlock_quiet)
+ error (0, 0, "\
%s: multiple revisions locked by %s; please specify one", rcs->path, user);
- return 1;
- }
- lock = p;
+ return 1;
}
+ lock = p;
}
if (lock == NULL)
return 0; /* no lock found, ergo nothing to do */
@@ -6248,6 +5922,7 @@ RCS_addaccess (rcs, user)
return;
}
}
+ free (access);
rcs->access = (char *) xrealloc
(rcs->access, strlen (rcs->access) + strlen (user) + 2);
strcat (rcs->access, " ");
@@ -6271,13 +5946,19 @@ RCS_delaccess (rcs, user)
if (rcs->access == NULL)
return;
+ if (user == NULL)
+ {
+ free (rcs->access);
+ rcs->access = NULL;
+ return;
+ }
+
p = rcs->access;
ulen = strlen (user);
while (p != NULL)
{
- if (p[ulen] == '\0' || p[ulen] == ' ')
- if (strncmp (p, user, ulen) == 0)
- break;
+ if (strncmp (p, user, ulen) == 0 && (p[ulen] == '\0' || p[ulen] == ' '))
+ break;
p = strchr (p, ' ');
if (p != NULL)
++p;
@@ -7676,7 +7357,7 @@ getdelta (rcsbuf, rcsfile, keyp, valp)
char **valp;
{
RCSVers *vnode;
- char *key, *value, *keybuf, *valbuf, *cp;
+ char *key, *value, *cp;
Node *kv;
/* Get revision number if it wasn't passed in. This uses
@@ -7794,81 +7475,32 @@ unable to parse %s; `state' not in the expected place", rcsfile);
*/
while (1)
{
- int len;
- size_t valbuflen;
-
- key = NULL;
-
- if (! rcsbuf_getid (rcsbuf, &keybuf))
+ if (! rcsbuf_getkey (rcsbuf, &key, &value))
error (1, 0, "unexpected end of file reading %s", rcsfile);
- /* rcsbuf_getid did not terminate the key, so copy it to new space. */
- len = rcsbuf->ptr - keybuf;
- key = (char *) xmalloc (sizeof(char) * (len + 1));
- strncpy (key, keybuf, len);
- key[len] = '\0';
-
- /* The `desc' keyword has only a single string value, with no
- trailing semicolon, so it must be handled specially. */
- if (STREQ (key, RCSDESC))
- {
- (void) rcsbuf_getstring (rcsbuf, &valbuf);
- value = rcsbuf_valcopy (rcsbuf, valbuf, 1, &valbuflen);
+ /* The `desc' keyword is the end of the deltas. */
+ if (strcmp (key, RCSDESC) == 0)
break;
- }
#ifdef PRESERVE_PERMISSIONS_SUPPORT
+
/* The `hardlinks' value is a group of words, which must
be parsed separately and added as a list to vnode->hardlinks. */
- if (STREQ (key, "hardlinks"))
+ if (strcmp (key, "hardlinks") == 0)
{
- Node *n;
+ char *word;
vnode->hardlinks = getlist();
- while (1)
+ while ((word = rcsbuf_valword (rcsbuf, &value)) != NULL)
{
- if (! rcsbuf_getword (rcsbuf, &valbuf))
- error (1, 0, "unexpected end of file reading %s", rcsfile);
- if (valbuf == NULL)
- break;
- n = getnode();
- n->key = rcsbuf_valcopy (rcsbuf, valbuf, 1, NULL);
+ Node *n = getnode();
+ n->key = word;
addnode (vnode->hardlinks, n);
}
continue;
}
#endif
- /* Get the value. */
- value = NULL;
- while (1)
- {
- if (! rcsbuf_getword (rcsbuf, &valbuf))
- error (1, 0, "unexpected end of file reading %s", rcsfile);
- if (valbuf == NULL)
- break;
-
- /* Copy valbuf to new space so we can polish it, then
- append it to value. */
-
- if (value == NULL)
- {
- value = rcsbuf_valcopy (rcsbuf, valbuf, 1, &valbuflen);
- }
- else
- {
- char *temp_value;
-
- temp_value = rcsbuf_valcopy (rcsbuf, valbuf, 1, &valbuflen);
- len = strlen (value);
- value = (char *) xrealloc
- (value, sizeof(char) * (len + valbuflen + 2));
- value[len] = ' ';
- strcpy (value + len + 1, temp_value);
- free (temp_value);
- }
- }
-
/* Enable use of repositories created by certain obsolete
versions of CVS. This code should remain indefinately;
there is no procedure for converting old repositories, and
@@ -7897,9 +7529,10 @@ unable to parse %s; `state' not in the expected place", rcsfile);
if (vnode->other_delta == NULL)
vnode->other_delta = getlist ();
kv = getnode ();
- kv->type = RCSFIELD;
- kv->key = key;
- kv->data = value;
+ kv->type = rcsbuf_valcmp (rcsbuf) ? RCSCMPFLD : RCSFIELD;
+ kv->key = xstrdup (key);
+ kv->data = rcsbuf_valcopy (rcsbuf, value, kv->type == RCSFIELD,
+ (size_t *) NULL);
if (addnode (vnode->other_delta, kv) != 0)
{
/* Complaining about duplicate keys in newphrases seems
@@ -7984,9 +7617,10 @@ RCS_getdeltatext (rcs, fp, rcsbuf)
break;
p = getnode();
- p->type = RCSFIELD;
+ p->type = rcsbuf_valcmp (rcsbuf) ? RCSCMPFLD : RCSFIELD;
p->key = xstrdup (key);
- p->data = rcsbuf_valcopy (rcsbuf, value, 1, (size_t *) NULL);
+ p->data = rcsbuf_valcopy (rcsbuf, value, p->type == RCSFIELD,
+ (size_t *) NULL);
if (addnode (d->other, p) < 0)
{
error (0, 0, "warning: %s, delta %s: duplicate field `%s'",
@@ -8067,8 +7701,8 @@ putrcsfield_proc (node, vfp)
A case where we are wrong in a much more clear-cut way is that
we let through non-graphic characters such as whitespace and
control characters. */
- int n = strcspn (node->data, "$,.:;@");
- if (node->data[n] == 0)
+
+ if (node->type == RCSCMPFLD || strpbrk (node->data, "$,.:;@") == NULL)
fputs (node->data, fp);
else
{
@@ -8229,7 +7863,13 @@ RCS_putdtree (rcs, rev, fp)
/* Find the delta node for this revision. */
p = findnode (rcs->versions, rev);
- assert (p != NULL);
+ if (p == NULL)
+ {
+ error (1, 0,
+ "error parsing repository file %s, file may be corrupt.",
+ rcs->path);
+ }
+
versp = (RCSVers *) p->data;
/* Print the delta node and recurse on its `next' node. This prints
@@ -8350,6 +7990,7 @@ RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt)
/* If this revision has been outdated, just skip it. */
if (dadmin->outdated)
{
+ freedeltatext (dtext);
--actions;
continue;
}
@@ -8469,7 +8110,7 @@ count_delta_actions (np, ignore)
/*
* Clean up temporary files
*/
-static RETSIGTYPE
+RETSIGTYPE
rcs_cleanup ()
{
/* Note that the checks for existence_error are because we are
@@ -8483,11 +8124,18 @@ rcs_cleanup ()
of a just-created file) reentrancy won't be an issue. */
if (rcs_lockfile != NULL)
{
- if (unlink_file (rcs_lockfile) < 0
+ char *tmp = rcs_lockfile;
+ rcs_lockfile = NULL;
+ if (rcs_lockfd >= 0)
+ {
+ if (close (rcs_lockfd) != 0)
+ error (0, errno, "error closing lock file %s", tmp);
+ rcs_lockfd = -1;
+ }
+ if (unlink_file (tmp) < 0
&& !existence_error (errno))
- error (0, errno, "cannot remove %s", rcs_lockfile);
+ error (0, errno, "cannot remove %s", tmp);
}
- rcs_lockfile = NULL;
}
/* RCS_internal_lockfile and RCS_internal_unlockfile perform RCS-style
@@ -8521,7 +8169,6 @@ static FILE *
rcs_internal_lockfile (rcsfile)
char *rcsfile;
{
- int fd;
struct stat rstat;
FILE *fp;
static int first_call = 1;
@@ -8530,6 +8177,9 @@ rcs_internal_lockfile (rcsfile)
{
first_call = 0;
/* clean up if we get a signal */
+#ifdef SIGABRT
+ (void) SIG_register (SIGABRT, rcs_cleanup);
+#endif
#ifdef SIGHUP
(void) SIG_register (SIGHUP, rcs_cleanup);
#endif
@@ -8549,6 +8199,7 @@ rcs_internal_lockfile (rcsfile)
/* Get the lock file name: `,file,' for RCS file `file,v'. */
assert (rcs_lockfile == NULL);
+ assert (rcs_lockfd < 0);
rcs_lockfile = rcs_lockfilename (rcsfile);
/* Use the existing RCS file mode, or read-only if this is a new
@@ -8575,11 +8226,11 @@ rcs_internal_lockfile (rcsfile)
rely on O_EXCL these days. This might be true for unix (I
don't really know), but I am still pretty skeptical in the case
of the non-unix systems. */
- fd = open (rcs_lockfile,
- OPEN_BINARY | O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
- S_IRUSR | S_IRGRP | S_IROTH);
+ rcs_lockfd = open (rcs_lockfile,
+ OPEN_BINARY | O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
+ S_IRUSR | S_IRGRP | S_IROTH);
- if (fd < 0)
+ if (rcs_lockfd < 0)
{
error (1, errno, "could not open lock file `%s'", rcs_lockfile);
}
@@ -8588,10 +8239,10 @@ rcs_internal_lockfile (rcsfile)
/* Because we change the modes later, we don't worry about
this in the non-HAVE_FCHMOD case. */
#ifdef HAVE_FCHMOD
- if (fchmod (fd, rstat.st_mode) < 0)
+ if (fchmod (rcs_lockfd, rstat.st_mode) < 0)
error (1, errno, "cannot change mode for %s", rcs_lockfile);
#endif
- fp = fdopen (fd, FOPEN_BINARY_WRITE);
+ fp = fdopen (rcs_lockfd, FOPEN_BINARY_WRITE);
if (fp == NULL)
error (1, errno, "cannot fdopen %s", rcs_lockfile);
@@ -8604,6 +8255,7 @@ rcs_internal_unlockfile (fp, rcsfile)
char *rcsfile;
{
assert (rcs_lockfile != NULL);
+ assert (rcs_lockfd >= 0);
/* Abort if we could not write everything successfully to LOCKFILE.
This is not a great error-handling mechanism, but should prevent
@@ -8619,6 +8271,7 @@ rcs_internal_unlockfile (fp, rcsfile)
error (1, 0, "error writing to lock file %s", rcs_lockfile);
if (fclose (fp) == EOF)
error (1, errno, "error closing lock file %s", rcs_lockfile);
+ rcs_lockfd = -1;
rename_file (rcs_lockfile, rcsfile);
@@ -8712,6 +8365,22 @@ RCS_rewrite (rcs, newdtext, insertpt)
rcs_internal_unlockfile (fout, rcs->path);
}
+/* Abandon changes to an RCS file. */
+
+void
+RCS_abandon (rcs)
+ RCSNode *rcs;
+{
+ free_rcsnode_contents (rcs);
+ rcs->symbols_data = NULL;
+ rcs->expand = NULL;
+ rcs->access = NULL;
+ rcs->locks_data = NULL;
+ rcs->comment = NULL;
+ rcs->desc = NULL;
+ rcs->flags |= PARTIAL;
+}
+
/* Annotate command. In rcs.c for historical reasons (from back when
what is now RCS_deltas was part of annotate_fileproc). */
diff --git a/contrib/cvs/src/rcs.h b/contrib/cvs/src/rcs.h
index 0a28161..3466398 100644
--- a/contrib/cvs/src/rcs.h
+++ b/contrib/cvs/src/rcs.h
@@ -8,8 +8,10 @@
* RCS source control definitions needed by rcs.c and friends
*/
-/* String which indicates a conflict if it occurs at the start of a line. */
-#define RCS_MERGE_PAT ">>>>>>> "
+/* Strings which indicate a conflict if they occur at the start of a line. */
+#define RCS_MERGE_PAT_1 "<<<<<<< "
+#define RCS_MERGE_PAT_2 "=======\n"
+#define RCS_MERGE_PAT_3 ">>>>>>> "
#define RCSEXT ",v"
#define RCSPAT "*,v"
@@ -227,7 +229,9 @@ int RCS_delete_revs PROTO ((RCSNode *, char *, char *, int));
void RCS_addaccess PROTO ((RCSNode *, char *));
void RCS_delaccess PROTO ((RCSNode *, char *));
char *RCS_getaccess PROTO ((RCSNode *));
+RETSIGTYPE rcs_cleanup PROTO ((void));
void RCS_rewrite PROTO ((RCSNode *, Deltatext *, char *));
+void RCS_abandon PROTO ((RCSNode *));
int rcs_change_text PROTO ((const char *, char *, size_t, const char *,
size_t, char **, size_t *));
char *make_file_label PROTO ((char *, char *, RCSNode *));
diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c
index e93afbf..1cb2fbb 100644
--- a/contrib/cvs/src/recurse.c
+++ b/contrib/cvs/src/recurse.c
@@ -173,6 +173,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
seems to be handled somewhere (else) but why should
it be a separate case? Needs investigation... */
just_subdirs = 1;
+ free (root);
}
#endif
@@ -590,7 +591,7 @@ do_recursion (frame)
/* Add it to our list. */
Node *n = getnode ();
- n->type = UNKNOWN;
+ n->type = NT_UNKNOWN;
n->key = xstrdup (this_root);
if (addnode (root_directories, n))
@@ -1015,7 +1016,7 @@ but CVS uses %s for its own purposes; skipping %s directory",
/* Add it to our list. */
Node *n = getnode ();
- n->type = UNKNOWN;
+ n->type = NT_UNKNOWN;
n->key = xstrdup (this_root);
if (addnode (root_directories, n))
@@ -1132,6 +1133,7 @@ addfile (listp, dir, file)
char *file;
{
Node *n;
+ List *fl;
/* add this dir. */
addlist (listp, dir);
@@ -1144,7 +1146,9 @@ addfile (listp, dir, file)
}
n->type = DIRS;
- addlist ((List **) &n->data, file);
+ fl = (List *) n->data;
+ addlist (&fl, file);
+ n->data = (char *) fl;
return;
}
@@ -1204,6 +1208,7 @@ unroll_files_proc (p, closure)
}
dirlist = save_dirlist;
- filelist = NULL;
+ if (filelist)
+ dellist (&filelist);
return(err);
}
diff --git a/contrib/cvs/src/release.c b/contrib/cvs/src/release.c
index ca7945b..06d582f 100644
--- a/contrib/cvs/src/release.c
+++ b/contrib/cvs/src/release.c
@@ -190,7 +190,7 @@ release (argc, argv)
{
if (strchr ("MARCZ", *line))
c++;
- (void) printf (line);
+ (void) fputs (line, stdout);
}
if (line_length < 0 && !feof (fp))
error (0, errno, "cannot read from subprocess");
diff --git a/contrib/cvs/src/remove.c b/contrib/cvs/src/remove.c
index 2dacdf1..f0055d9 100644
--- a/contrib/cvs/src/remove.c
+++ b/contrib/cvs/src/remove.c
@@ -103,6 +103,7 @@ cvsremove (argc, argv)
/* FIXME: Can't we set SEND_NO_CONTENTS here? Needs investigation. */
send_files (argc, argv, local, 0, 0);
send_file_names (argc, argv, 0);
+ free_names (&argc, argv);
send_to_server ("remove\012", 0);
return get_responses_and_close ();
}
diff --git a/contrib/cvs/src/repos.c b/contrib/cvs/src/repos.c
index 2738665..bc2b4be 100644
--- a/contrib/cvs/src/repos.c
+++ b/contrib/cvs/src/repos.c
@@ -106,12 +106,6 @@ Name_Repository (dir, update_dir)
* one by tacking on the CVSROOT environment variable. If the CVSROOT
* environment variable is not set, die now.
*/
- if (strcmp (repos, "..") == 0 || strncmp (repos, "../", 3) == 0)
- {
- error (0, 0, "in directory %s:", xupdate_dir);
- error (0, 0, "`..'-relative repositories are not supported.");
- error (1, 0, "illegal source repository");
- }
if (! isabsolute(repos))
{
char *newrepos;
@@ -123,6 +117,12 @@ Name_Repository (dir, update_dir)
error (0, 0, "or specify the '-d' option to %s.", program_name);
error (1, 0, "illegal repository setting");
}
+ if (pathname_levels (repos) > 0)
+ {
+ error (0, 0, "in directory %s:", xupdate_dir);
+ error (0, 0, "`..'-relative repositories are not supported.");
+ error (1, 0, "illegal source repository");
+ }
newrepos = xmalloc (strlen (CVSroot_directory) + strlen (repos) + 10);
(void) sprintf (newrepos, "%s/%s", CVSroot_directory, repos);
free (repos);
diff --git a/contrib/cvs/src/root.c b/contrib/cvs/src/root.c
index d88c6f4..81859c8 100644
--- a/contrib/cvs/src/root.c
+++ b/contrib/cvs/src/root.c
@@ -174,9 +174,9 @@ Create_Root (dir, rootdir)
directories. Then we can check against them when a remote user
hands us a CVSROOT directory. */
-static unsigned int root_allow_count;
+static int root_allow_count;
static char **root_allow_vector;
-static unsigned int root_allow_size;
+static int root_allow_size;
void
root_allow_add (arg)
@@ -233,8 +233,7 @@ void
root_allow_free ()
{
if (root_allow_vector != NULL)
- free (root_allow_vector);
- root_allow_count = 0;
+ free_names (&root_allow_count, root_allow_vector);
root_allow_size = 0;
}
@@ -242,7 +241,7 @@ int
root_allow_ok (arg)
char *arg;
{
- unsigned int i;
+ int i;
if (root_allow_count == 0)
{
@@ -295,7 +294,7 @@ parse_cvsroot (CVSroot)
char *CVSroot;
{
static int cvsroot_parsed = 0;
- char *cvsroot_copy, *p;
+ char *cvsroot_copy, *cvsroot_save, *p;
int check_hostname;
/* Don't go through the trouble twice. */
@@ -305,10 +304,19 @@ parse_cvsroot (CVSroot)
return 0;
}
+ if (CVSroot_original != NULL)
+ free (CVSroot_original);
+ if (CVSroot_directory != NULL)
+ free (CVSroot_directory);
+ if (CVSroot_username != NULL)
+ free (CVSroot_username);
+ if (CVSroot_hostname != NULL)
+ free (CVSroot_hostname);
+
CVSroot_original = xstrdup (CVSroot);
- cvsroot_copy = xstrdup (CVSroot);
+ cvsroot_save = cvsroot_copy = xstrdup (CVSroot);
- if ((*cvsroot_copy == ':'))
+ if (*cvsroot_copy == ':')
{
char *method = ++cvsroot_copy;
@@ -324,6 +332,7 @@ parse_cvsroot (CVSroot)
if (! (p = strchr (method, ':')))
{
error (0, 0, "bad CVSroot: %s", CVSroot);
+ free (cvsroot_save);
return 1;
}
*p = '\0';
@@ -348,6 +357,7 @@ parse_cvsroot (CVSroot)
else
{
error (0, 0, "unknown method in CVSroot: %s", CVSroot);
+ free (cvsroot_save);
return 1;
}
}
@@ -378,19 +388,19 @@ parse_cvsroot (CVSroot)
{
/* Check to see if there is a username in the string. */
- if ((p = strchr (cvsroot_copy, '@')))
+ if ((p = strchr (cvsroot_copy, '@')) != NULL)
{
- CVSroot_username = cvsroot_copy;
*p = '\0';
+ CVSroot_username = xstrdup (cvsroot_copy);
cvsroot_copy = ++p;
if (*CVSroot_username == '\0')
CVSroot_username = NULL;
}
- if ((p = strchr (cvsroot_copy, ':')))
+ if ((p = strchr (cvsroot_copy, ':')) != NULL)
{
- CVSroot_hostname = cvsroot_copy;
*p = '\0';
+ CVSroot_hostname = xstrdup (cvsroot_copy);
cvsroot_copy = ++p;
if (*CVSroot_hostname == '\0')
@@ -398,7 +408,8 @@ parse_cvsroot (CVSroot)
}
}
- CVSroot_directory = cvsroot_copy;
+ CVSroot_directory = xstrdup(cvsroot_copy);
+ free (cvsroot_save);
#if ! defined (CLIENT_SUPPORT) && ! defined (DEBUG)
if (CVSroot_method != local_method)
@@ -422,12 +433,10 @@ parse_cvsroot (CVSroot)
switch (CVSroot_method)
{
case local_method:
- case fork_method:
if (CVSroot_username || CVSroot_hostname)
{
error (0, 0, "can't specify hostname and username in CVSROOT");
- error (0, 0, "when using %s access method",
- CVSroot_method == local_method ? "local" : "fork");
+ error (0, 0, "when using local access method");
error (0, 0, "(%s)", CVSroot);
return 1;
}
@@ -440,6 +449,18 @@ parse_cvsroot (CVSroot)
error (1, 0, "CVSROOT %s must be an absolute pathname",
CVSroot_directory);
break;
+ case fork_method:
+ /* We want :fork: to behave the same as other remote access
+ methods. Therefore, don't check to see that the repository
+ name is absolute -- let the server do it. */
+ if (CVSroot_username || CVSroot_hostname)
+ {
+ error (0, 0, "can't specify hostname and username in CVSROOT");
+ error (0, 0, "when using fork access method");
+ error (0, 0, "(%s)", CVSroot);
+ return 1;
+ }
+ break;
case kserver_method:
#ifndef HAVE_KERBEROS
error (0, 0, "Your CVSROOT is set for a kerberos access method");
@@ -488,18 +509,24 @@ parse_cvsroot (CVSroot)
/* Set up the global CVSroot* variables as if we're using the local
- repository DIR. DIR must point to storage which will last for the
- rest of the CVS invocation (for example, the caller might malloc it
- and never free it, or free it just before exiting CVS). */
+ repository DIR. */
void
set_local_cvsroot (dir)
char *dir;
{
- CVSroot_original = dir;
+ if (CVSroot_original != NULL)
+ free (CVSroot_original);
+ CVSroot_original = xstrdup(dir);
CVSroot_method = local_method;
- CVSroot_directory = CVSroot_original;
+ if (CVSroot_directory != NULL)
+ free (CVSroot_directory);
+ CVSroot_directory = xstrdup(dir);
+ if (CVSroot_username != NULL)
+ free (CVSroot_username);
CVSroot_username = NULL;
+ if (CVSroot_hostname != NULL)
+ free (CVSroot_hostname);
CVSroot_hostname = NULL;
client_active = 0;
}
diff --git a/contrib/cvs/src/rtag.c b/contrib/cvs/src/rtag.c
index 5fd825f..bc14d88 100644
--- a/contrib/cvs/src/rtag.c
+++ b/contrib/cvs/src/rtag.c
@@ -29,7 +29,7 @@ static int rtag_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static int rtag_filesdoneproc PROTO ((void *callerdat, int err,
char *repos, char *update_dir,
List *entries));
-static int rtag_proc PROTO((int *pargc, char **argv, char *xwhere,
+static int rtag_proc PROTO((int argc, char **argv, char *xwhere,
char *mwhere, char *mfile, int shorten,
int local_specified, char *mname, char *msg));
static int rtag_delete PROTO((RCSNode *rcsfile));
@@ -222,9 +222,9 @@ rtag (argc, argv)
*/
/* ARGSUSED */
static int
-rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
+rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
mname, msg)
- int *pargc;
+ int argc;
char **argv;
char *xwhere;
char *mwhere;
@@ -236,6 +236,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
{
/* Begin section which is identical to patch_proc--should this
be abstracted out somehow? */
+ char *myargv[2];
int err = 0;
int which;
char *repository;
@@ -277,13 +278,10 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
}
else
{
- int i;
-
- /* a file means muck argv */
- for (i = 1; i < *pargc; i++)
- free (argv[i]);
- argv[1] = xstrdup (mfile);
- (*pargc) = 2;
+ myargv[0] = argv[0];
+ myargv[1] = mfile;
+ argc = 2;
+ argv = myargv;
}
free (path);
}
@@ -305,7 +303,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
if (numtag != NULL && !numtag_validated)
{
- tag_check_valid (numtag, *pargc - 1, argv + 1, local, 0, NULL);
+ tag_check_valid (numtag, argc - 1, argv + 1, local, 0, NULL);
numtag_validated = 1;
}
@@ -315,7 +313,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
mtlist = getlist();
err = start_recursion (check_fileproc, check_filesdoneproc,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
- *pargc - 1, argv + 1, local, which, 0, 1,
+ argc - 1, argv + 1, local, which, 0, 1,
where, 1);
if (err)
@@ -326,7 +324,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
/* start the recursion processor */
err = start_recursion (rtag_fileproc, rtag_filesdoneproc, rtag_dirproc,
(DIRLEAVEPROC) NULL, NULL,
- *pargc - 1, argv + 1, local,
+ argc - 1, argv + 1, local,
which, 0, 0, where, 1);
free (where);
dellist(&mtlist);
diff --git a/contrib/cvs/src/run.c b/contrib/cvs/src/run.c
index 41f4457..d382cef 100644
--- a/contrib/cvs/src/run.c
+++ b/contrib/cvs/src/run.c
@@ -207,6 +207,18 @@ run_exec (stin, stout, sterr, flags)
(void) close (sherr);
}
+#ifdef SETXID_SUPPORT
+ /*
+ ** This prevents a user from creating a privileged shell
+ ** from the text editor when the SETXID_SUPPORT option is selected.
+ */
+ if (!strcmp (run_argv[0], Editor) && setegid (getgid ()))
+ {
+ error (0, errno, "cannot set egid to gid");
+ _exit (127);
+ }
+#endif
+
/* dup'ing is done. try to run it now */
(void) execvp (run_argv[0], run_argv);
error (0, errno, "cannot exec %s", run_argv[0]);
diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh
index 6130289..84e67cc 100755
--- a/contrib/cvs/src/sanity.sh
+++ b/contrib/cvs/src/sanity.sh
@@ -25,21 +25,6 @@
# See TODO list at end of file.
-# You can't run CVS as root; print a nice error message here instead
-# of somewhere later, after making a mess.
-# Commented out because:
-# (1) whoami is not portable. If memory serves the POSIX way is "id -un".
-# ("logname" or "who am i" are similar but different--they have more to
-# do with who logged in on your tty than your uid).
-# (2) This definition of "root" doesn't quite match CVS's (which is based
-# on uid 0, not username "root").
-#case "`whoami`" in
-# "root" )
-# echo "sanity.sh: test suite does not work correctly when run as root" >&2
-# exit 1
-# ;;
-#esac
-
# required to make this script work properly.
unset CVSREAD
@@ -68,7 +53,8 @@ export LC_ALL
# So this would be lost if everything was `pwd`-based. I suppose
# if we wanted to get baroque we could start making symlinks
# to ensure the two are different.
-TESTDIR=${TESTDIR:-/tmp/cvs-sanity}
+tmp=`(cd /tmp; /bin/pwd || pwd) 2>/dev/null`
+: ${TESTDIR=$tmp/cvs-sanity}
# "debugger"
#set -x
@@ -121,6 +107,7 @@ PROG=`basename ${testcvs}`
# should be here. a-zA-Z obviously. People complained when 0-9 were
# not allowed in usernames. Other than that I'm not sure.
username="[-a-zA-Z0-9][-a-zA-Z0-9]*"
+author="[-a-zA-Z0-9][-a-zA-Z0-9]*"
# Regexp to match the name of a temporary file (from cvs_temp_name).
# This appears in certain diff output.
@@ -154,34 +141,87 @@ if test -f check.log; then
mv check.log check.plog
fi
-GEXPRLOCS="`echo $PATH | sed 's/:/ /g'` /usr/local/bin /usr/contrib/bin /usr/gnu/bin /local/bin /local/gnu/bin /gun/bin"
+# clean any old remnants (we need the chmod because some tests make
+# directories read-only)
+if test -d ${TESTDIR}; then
+ chmod -R a+wx ${TESTDIR}
+ rm -rf ${TESTDIR}
+fi
+mkdir ${TESTDIR}
+cd ${TESTDIR}
-EXPR=expr
+# Make sure various tools work the way we expect, or try to find
+# versions that do.
+: ${AWK=awk}
+: ${EXPR=expr}
+: ${ID=id}
+: ${TR=tr}
-# Cause NextStep 3.3 users to lose in a more graceful fashion.
-if $EXPR 'abc
-def' : 'abc
-def' >/dev/null; then
- : good, it works
-else
- for path in $GEXPRLOCS ; do
- if test -x $path/gexpr ; then
- if test "X`$path/gexpr --version`" != "X--version" ; then
- EXPR=$path/gexpr
+find_tool ()
+{
+ GLOCS="`echo $PATH | sed 's/:/ /g'` /usr/local/bin /usr/contrib/bin /usr/gnu/bin /local/bin /local/gnu/bin /gun/bin"
+ TOOL=""
+ for path in $GLOCS ; do
+ if test -x $path/g$1 ; then
+ if test "X`$path/g$1 --version`" != "X--version" ; then
+ TOOL=$path/g$1
break
fi
fi
- if test -x $path/expr ; then
- if test "X`$path/expr --version`" != "X--version" ; then
- EXPR=$path/expr
+ if test -x $path/$1 ; then
+ if test "X`$path/$1 --version`" != "X--version" ; then
+ TOOL=$path/$1
break
fi
fi
done
+ if test -z "$TOOL"; then
+ :
+ else
+ echo "Notice: The default version of $1 is defective, using" >&2
+ echo "$TOOL instead." >&2
+ fi
+ echo "$TOOL"
+}
+
+# You can't run CVS as root; print a nice error message here instead
+# of somewhere later, after making a mess.
+case "`$ID -u`" in
+ "0")
+ echo "Test suite does not work correctly when run as root" >&2
+ exit 1
+ ;;
+
+ "")
+ ID=`find_tool id`
+ if test -z "$ID" ; then
+ echo 'Running these tests requires an "id" program that understands the' >&2
+ echo '-u and -n flags. Make sure that such an id (GNU, or many but not' >&2
+ echo 'all vendor-supplied versions) is in your path.' >&2
+ exit 1
+ fi
+ ;;
+esac
+username=`$ID -un`
+if $EXPR "${username}" : "${username}" >/dev/null; then
+ : good, it works
+else
+ echo "Test suite does not work correctly when run by a username" >&2
+ echo "containing regular expression meta-characters." >&2
+ exit 1
+fi
+
+# Cause NextStep 3.3 users to lose in a more graceful fashion.
+if $EXPR 'abc
+def' : 'abc
+def' >/dev/null; then
+ : good, it works
+else
+ EXPR=`find_tool expr`
if test -z "$EXPR" ; then
- echo 'Running these tests requires an "expr" program that can handle'
- echo 'multi-line patterns. Make sure that such an expr (GNU, or many but'
- echo 'not all vendor-supplied versions) is in your path.'
+ echo 'Running these tests requires an "expr" program that can handle' >&2
+ echo 'multi-line patterns. Make sure that such an expr (GNU, or many but' >&2
+ echo 'not all vendor-supplied versions) is in your path.' >&2
exit 1
fi
fi
@@ -191,20 +231,7 @@ fi
if $EXPR 'a
b' : 'a
c' >/dev/null; then
- for path in $GEXPRLOCS ; do
- if test -x $path/gexpr ; then
- if test "X`$path/gexpr --version`" != "X--version" ; then
- EXPR=$path/gexpr
- break
- fi
- fi
- if test -x $path/expr ; then
- if test "X`$path/expr --version`" != "X--version" ; then
- EXPR=$path/expr
- break
- fi
- fi
- done
+ EXPR=`find_tool expr`
if test -z "$EXPR" ; then
echo 'Warning: you are using a version of expr which does not correctly'
echo 'match multi-line patterns. Some tests may spuriously pass.'
@@ -215,6 +242,35 @@ else
: good, it works
fi
+# More SunOS lossage...
+echo 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >${TESTDIR}/foo
+cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar
+cat ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar >${TESTDIR}/foo
+cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar
+if $EXPR "`cat ${TESTDIR}/bar`" : "`cat ${TESTDIR}/bar`" >/dev/null; then
+ : good, it works
+else
+ EXPR=`find_tool expr`
+ if test -z "$EXPR" ; then
+ echo 'Warning: you are using a version of expr which does not correctly'
+ echo 'match large patterns. Some tests may spuriously fail.'
+ echo 'You may wish to make sure GNU expr is in your path.'
+ EXPR=expr
+ fi
+fi
+if $EXPR "`cat ${TESTDIR}/bar`x" : "`cat ${TESTDIR}/bar`y" >/dev/null; then
+ EXPR=`find_tool expr`
+ if test -z "$EXPR" ; then
+ echo 'Warning: you are using a version of expr which does not correctly'
+ echo 'match large patterns. Some tests may spuriously pass.'
+ echo 'You may wish to make sure GNU expr is in your path.'
+ EXPR=expr
+ fi
+else
+ : good, it works
+fi
+rm -f ${TESTDIR}/foo ${TESTDIR}/bar
+
# That we should have to do this is total bogosity, but GNU expr
# version 1.9.4-1.12 uses the emacs definition of "$" instead of the unix
# (e.g. SunOS 4.1.3 expr) one. Rumor has it this will be fixed in the
@@ -265,6 +321,19 @@ else
QUESTION='\?'
fi
+# now make sure that tr works on NULs
+if $EXPR `echo "123" | ${TR} '2' '\0'` : "123" >/dev/null; then
+ TR=`find_tool tr`
+ if test -z "$TR" ; then
+ echo 'Warning: you are using a version of tr which does not correctly'
+ echo 'handle NUL bytes. Some tests may spuriously pass or fail.'
+ echo 'You may wish to make sure GNU tr is in your path.'
+ TR=tr
+ fi
+else
+ : good, it works
+fi
+
pass ()
{
echo "PASS: $1" >>${LOGFILE}
@@ -359,15 +428,15 @@ dotest_all_in_one ()
dotest_line_by_line ()
{
line=1
- while [ $line -le `wc -l ${TESTDIR}/dotest.tmp` ] ; do
- echo "$line matched \c" >>$LOGFILE
+ while [ $line -le `wc -l <${TESTDIR}/dotest.tmp` ] ; do
if $EXPR "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" : \
"`sed -n ${line}p ${TESTDIR}/dotest.exp`" >/dev/null; then
:
else
- echo "**** expected line: " >>${LOGFILE}
+ echo "Line $line:" >> ${LOGFILE}
+ echo "**** expected: " >>${LOGFILE}
sed -n ${line}p ${TESTDIR}/dotest.exp >>${LOGFILE}
- echo "**** got line: " >>${LOGFILE}
+ echo "**** got: " >>${LOGFILE}
sed -n ${line}p ${TESTDIR}/dotest.tmp >>${LOGFILE}
unset line
return 1
@@ -443,7 +512,7 @@ dotest_internal_debug ()
dotest ()
{
rm -f ${TESTDIR}/dotest.ex? 2>&1
- if $2 >${TESTDIR}/dotest.tmp 2>&1; then
+ if eval "$2" >${TESTDIR}/dotest.tmp 2>&1; then
: so far so good
else
status=$?
@@ -458,7 +527,7 @@ dotest ()
dotest_lit ()
{
rm -f ${TESTDIR}/dotest.ex? 2>&1
- if $2 >${TESTDIR}/dotest.tmp 2>&1; then
+ if eval "$2" >${TESTDIR}/dotest.tmp 2>&1; then
: so far so good
else
status=$?
@@ -482,7 +551,7 @@ dotest_lit ()
dotest_fail ()
{
rm -f ${TESTDIR}/dotest.ex? 2>&1
- if $2 >${TESTDIR}/dotest.tmp 2>&1; then
+ if eval "$2" >${TESTDIR}/dotest.tmp 2>&1; then
status=$?
cat ${TESTDIR}/dotest.tmp >>${LOGFILE}
echo "exit status was $status" >>${LOGFILE}
@@ -497,7 +566,7 @@ dotest_fail ()
# Like dotest except second argument is the required exitstatus.
dotest_status ()
{
- $3 >${TESTDIR}/dotest.tmp 2>&1
+ eval "$3" >${TESTDIR}/dotest.tmp 2>&1
status=$?
if test "$status" = "$2"; then
: so far so good
@@ -513,7 +582,7 @@ dotest_status ()
dotest_sort ()
{
rm -f ${TESTDIR}/dotest.ex? 2>&1
- if $2 >${TESTDIR}/dotest.tmp1 2>&1; then
+ if eval "$2" >${TESTDIR}/dotest.tmp1 2>&1; then
: so far so good
else
status=$?
@@ -521,18 +590,10 @@ dotest_sort ()
echo "exit status was $status" >>${LOGFILE}
fail "$1"
fi
- sort < ${TESTDIR}/dotest.tmp1 > ${TESTDIR}/dotest.tmp
+ ${TR} ' ' ' ' < ${TESTDIR}/dotest.tmp1 | sort > ${TESTDIR}/dotest.tmp
dotest_internal "$@"
}
-# clean any old remnants (we need the chmod because some tests make
-# directories read-only)
-if test -d ${TESTDIR}; then
- chmod -R a+wx ${TESTDIR}
- rm -rf ${TESTDIR}
-fi
-mkdir ${TESTDIR}
-cd ${TESTDIR}
# This will show up in cvs history output where it prints the working
# directory. It should *not* appear in any cvs output referring to the
# repository; cvs should use the name of the repository as specified.
@@ -573,10 +634,11 @@ if test x"$*" = x; then
tests="${tests} branches branches2 tagc tagf"
tests="${tests} rcslib multibranch import importb importc"
tests="${tests} import-after-initial"
- tests="${tests} join join2 join3 join-readonly-conflict"
+ tests="${tests} join join2 join3 join-readonly-conflict join-admin"
tests="${tests} new newb conflicts conflicts2 conflicts3"
+ tests="${tests} clean"
# Checking out various places (modules, checkout -d, &c)
- tests="${tests} modules modules2 modules3 modules4"
+ tests="${tests} modules modules2 modules3 modules4 modules5"
tests="${tests} mkmodules-temp-file-removal"
tests="${tests} cvsadm emptydir abspath toplevel toplevel2"
# Log messages, error messages.
@@ -587,7 +649,7 @@ if test x"$*" = x; then
tests="${tests} ignore binfiles binfiles2 binfiles3"
tests="${tests} mcopy binwrap binwrap2"
tests="${tests} binwrap3 mwrap info taginfo config"
- tests="${tests} serverpatch log log2 ann ann-id"
+ tests="${tests} serverpatch log log2 logopt ann ann-id"
# Repository Storage (RCS file format, CVS lock files, creating
# a repository without "cvs init", &c).
tests="${tests} crerepos rcs rcs2 rcs3 lockfiles backuprecover"
@@ -595,7 +657,7 @@ if test x"$*" = x; then
tests="${tests} history"
tests="${tests} big modes modes2 modes3 stamps"
# PreservePermissions stuff: permissions, symlinks et al.
- tests="${tests} perms symlinks symlinks2 hardlinks"
+ # tests="${tests} perms symlinks symlinks2 hardlinks"
# More tag and branch tests, keywords.
tests="${tests} sticky keyword keyword2 keywordlog"
tests="${tests} head tagdate multibranch2 tag8k"
@@ -667,6 +729,7 @@ if test "x$remote" = xyes; then
fi
dotest 1 "${testcvs} init" ''
+dotest 1a "${testcvs} init" ''
### The big loop
for what in $tests; do
@@ -805,6 +868,21 @@ done"
${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile
new revision: 3\.1; previous revision: 2\.0
done"
+
+ # Test using -r to create a branch
+ dotest_fail basica-8a3 "${testcvs} -q ci -m bogus -r 3.0.0" \
+"Checking in ssfile;
+${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile
+${PROG} [a-z]*: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v: can't find branch point 3\.0
+${PROG} [a-z]*: could not check in ssfile"
+ dotest basica-8a4 "${testcvs} -q ci -m valid -r 3.1.2" \
+"Checking in ssfile;
+${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v <-- ssfile
+new revision: 3\.1\.2\.1; previous revision: 3\.1
+done"
+ # now get rid of the sticky tag and go back to the trunk
+ dotest basica-8a5 "${testcvs} -q up -A" "[UP] ssfile"
+
cd ../..
dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" \
"Index: sdir/ssdir/ssfile
@@ -814,6 +892,15 @@ retrieving revision 1\.2
retrieving revision 1\.3
diff -r1\.2 -r1\.3"
+ dotest_fail basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd" \
+"Index: sdir/ssdir/ssfile
+===================================================================
+RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v
+retrieving revision 1\.2
+retrieving revision 1\.3
+diff -C3isacrowd -r1\.2 -r1\.3
+${PROG} [a-z]*: invalid context length argument"
+
# The .* here will normally be "No such file or directory",
# but if memory serves some systems (AIX?) have a different message.
: dotest_fail basica-9 \
@@ -864,6 +951,10 @@ done"
deleting revision 2\.0
deleting revision 1\.3
done"
+ dotest basica-o6a "${testcvs} admin -o 3.1.2: ssfile" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v
+deleting revision 3\.1\.2\.1
+done"
dotest basica-o7 "${testcvs} log -N ssfile" "
RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/ssdir/ssfile,v
Working file: ssfile
@@ -1193,7 +1284,7 @@ ${PROG} [a-z]*: Updating second-dir"
# For CVS to make a syntactic check for "." wouldn't suffice.
# On Linux 2.2 systems, the cwd may be gone, so we recreate it
# to allow basicc-11 to actually happen
- if ! test -d ../first-dir; then
+ if test ! -d ../first-dir; then
cd ..
mkdir ./first-dir
cd ./first-dir
@@ -2067,44 +2158,50 @@ ${PROG} [a-z]*: Importing ${TESTDIR}/cvsroot/second-dir/dir1/dir2"
# which don't exist in the remote output? would seem to be
# a CVS bug.
dotest basic2-64 "${testcvs} his -x TOFWUCGMAR -a" \
-"O [0-9/]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= ${TMPPWD}/\*
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == ${TMPPWD}
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == ${TMPPWD}
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == ${TMPPWD}
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == ${TMPPWD}
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == ${TMPPWD}
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == ${TMPPWD}
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == ${TMPPWD}
-M [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TMPPWD}
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == ${TMPPWD}
-M [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == ${TMPPWD}
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == ${TMPPWD}
-M [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == ${TMPPWD}
-F [0-9/]* [0-9:]* ${PLUS}0000 ${username} =first-dir= ${TMPPWD}/\*
-T [0-9/]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\]
-T [0-9/]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\]
-T [0-9/]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\]
-O [0-9/]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= ${TMPPWD}/\*
-U [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TMPPWD}/first-dir
-U [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == ${TMPPWD}/first-dir" \
-"O [0-9/]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= <remote>/\*
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == <remote>
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == <remote>
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == <remote>
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == <remote>
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == <remote>
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == <remote>
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == <remote>
-M [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == <remote>
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == <remote>
-M [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == <remote>
-A [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == <remote>
-M [0-9/]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == <remote>
-F [0-9/]* [0-9:]* ${PLUS}0000 ${username} =first-dir= <remote>/\*
-T [0-9/]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\]
-T [0-9/]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\]
-T [0-9/]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\]
-O [0-9/]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= <remote>/\*"
+"O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= ${TMPPWD}/\*
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == ${TMPPWD}
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == ${TMPPWD}
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == ${TMPPWD}
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == ${TMPPWD}
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == ${TMPPWD}
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == ${TMPPWD}
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == ${TMPPWD}
+M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TMPPWD}
+R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == ${TMPPWD}
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == ${TMPPWD}
+M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == ${TMPPWD}
+R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1 == ${TMPPWD}
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == ${TMPPWD}
+M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == ${TMPPWD}
+R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1/dir2 == ${TMPPWD}
+F [0-9-]* [0-9:]* ${PLUS}0000 ${username} =first-dir= ${TMPPWD}/\*
+T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\]
+T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\]
+T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\]
+O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= ${TMPPWD}/\*
+U [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TMPPWD}/first-dir
+U [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == ${TMPPWD}/first-dir" \
+"O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= <remote>/\*
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == <remote>
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == <remote>
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == <remote>
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == <remote>
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == <remote>
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == <remote>
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == <remote>
+M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == <remote>
+R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == <remote>
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == <remote>
+M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == <remote>
+R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1 == <remote>
+A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == <remote>
+M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == <remote>
+R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1/dir2 == <remote>
+F [0-9-]* [0-9:]* ${PLUS}0000 ${username} =first-dir= <remote>/\*
+T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\]
+T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\]
+T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\]
+O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= <remote>/\*"
rm -rf ${CVSROOT_DIRNAME}/first-dir
rm -rf ${CVSROOT_DIRNAME}/second-dir
@@ -2246,10 +2343,9 @@ done"
spacefiles)
# More filename tests, in particular spaces in file names.
- # If we start using eval in dotest, this test should become
- # easier to write (in fact, it may be possible to just
- # change a few of the names in basica or some other test,
- # always good to keep the testsuite concise).
+ # (it might be better to just change a few of the names in
+ # basica or some other test instead, always good to keep the
+ # testsuite concise).
# I wrote this test to worry about problems in do_module;
# but then I found that the CVS server has its own problems
@@ -2283,24 +2379,16 @@ ${TESTDIR}/cvsroot/top,v <-- top
initial revision: 1\.1
done"
mkdir 'first dir'
- if ${testcvs} add 'first dir' >${TESTDIR}/output.tmp 2>&1; then
- dotest spacefiles-4 "cat ${TESTDIR}/output.tmp" \
+ dotest spacefiles-4 "${testcvs} add 'first dir'" \
"Directory ${TESTDIR}/cvsroot/first dir added to the repository"
- else
- fail spacefiles-4
- fi
mkdir ./${dashb}
dotest spacefiles-5 "${testcvs} add -- ${dashb}" \
"Directory ${TESTDIR}/cvsroot/${dashb} added to the repository"
cd 'first dir'
touch 'a file'
- if ${testcvs} add 'a file' >${TESTDIR}/output.tmp 2>&1; then
- dotest spacefiles-6 "cat ${TESTDIR}/output.tmp" \
+ dotest spacefiles-6 "${testcvs} add 'a file'" \
"${PROG} [a-z]*: scheduling file .a file. for addition
${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
- else
- fail spacefiles-6
- fi
dotest spacefiles-7 "${testcvs} -q ci -m add" \
"RCS file: ${TESTDIR}/cvsroot/first dir/a file,v
done
@@ -2322,22 +2410,13 @@ done"
dotest spacefiles-11 "${testcvs} -q co -- ${dashc}" "U \./${dashc}"
rm ./${dashc}
dotest spacefiles-12 "${testcvs} -q co -- /${dashc}" "U \./${dashc}"
- if ${testcvs} -q co 'first dir' >${TESTDIR}/output.tmp 2>&1; then
- dotest spacefiles-13 "cat ${TESTDIR}/output.tmp" \
+ dotest spacefiles-13 "${testcvs} -q co 'first dir'" \
"U first dir/a file"
- else
- fail spacefiles-13
- fi
cd ..
mkdir 3; cd 3
- if ${testcvs} -q co 'first dir/a file' >${TESTDIR}/output.tmp 2>&1
- then
- dotest spacefiles-14 "cat ${TESTDIR}/output.tmp" \
+ dotest spacefiles-14 "${testcvs} -q co 'first dir/a file'" \
"U first dir/a file"
- else
- fail spacefiles-14
- fi
cd ..
rm -r 1 2 3
@@ -3573,15 +3652,9 @@ ${PROG} [a-z]*: skipping directory dir1/sdir"
# If we say "yes", then CVS gives errors about not being able to
# create lock files.
- if echo no | ${testcvs} release -d dir1/sdir \
- >${TESTDIR}/output.tmp 2>&1; then
- pass dirs-4
- else
- fail dirs-4
- fi
# The fact that it says "skipping directory " rather than
# "skipping directory dir1/sdir" is some kind of bug.
- dotest dirs-4a "cat ${TESTDIR}/output.tmp" \
+ echo no | dotest dirs-4 "${testcvs} release -d dir1/sdir" \
"${PROG} [a-z]*: cannot open directory ${TESTDIR}/cvsroot/dir1/sdir: No such file or directory
${PROG} [a-z]*: skipping directory
You have \[0\] altered files in this repository\.
@@ -3603,7 +3676,6 @@ D/sdir////"
cd ..
rm -r imp-dir 1
- rm ${TESTDIR}/output.tmp
# clean up our repositories
rm -rf ${CVSROOT_DIRNAME}/dir1
@@ -3952,7 +4024,7 @@ Merging differences between 1\.1\.2\.1 and 1\.1\.2\.1\.2\.1 into file1
rcsmerge: warning: conflicts during merge"
dotest branches-16 "cat file1" '<<<<<<< file1
1:ancest
-=======
+[=]======
1:brbr
[>]>>>>>> 1\.1\.2\.1\.2\.1'
@@ -4514,7 +4586,7 @@ mumble;
}
EOF
# Use dotest_fail because exit status from `cvs diff' must be 1.
- dotest_fail rcslib-diffrgx-3 "${testcvs} diff -c -F.*( rgx.c" \
+ dotest_fail rcslib-diffrgx-3 "${testcvs} diff -c -F'.*(' rgx.c" \
"Index: rgx\.c
===================================================================
RCS file: ${TESTDIR}/cvsroot/first-dir/rgx\.c,v
@@ -4904,7 +4976,7 @@ done"
"
- ${PROG} checkout -jvendor-branch:yesterday -jvendor-branch first-dir
+ ${PROG} checkout -jvendor-branch:yesterday -jvendor-branch first-dir
2 conflicts created by this import.
C first-dir/imported-f1
C first-dir/imported-f2
@@ -4950,7 +5022,7 @@ Use the following command to help the merge:"
dotest import-113 \
"${testcvs} -q co -jjunk-1_0 -jjunk-2_0 first-dir" \
-"${PROG} [a-z]*: file first-dir/imported-f1 is present in revision junk-2_0
+"${PROG} [a-z]*: file first-dir/imported-f1 does not exist, but is present in revision junk-2_0
RCS file: ${TESTDIR}/cvsroot/first-dir/imported-f2,v
retrieving revision 1\.1\.1\.1
retrieving revision 1\.1\.1\.2
@@ -5014,7 +5086,7 @@ No conflicts created by this import"
"
- ${PROG} -d ${CVSROOT} checkout -jfreemunger:yesterday -jfreemunger first-dir
+ ${PROG} -d ${CVSROOT} checkout -jfreemunger:yesterday -jfreemunger first-dir
2 conflicts created by this import.
C first-dir/file1
C first-dir/file2
@@ -5147,14 +5219,14 @@ ${PROG} [a-z]*: Updating bdir/subdir"
"${PROG} [a-z]*: in directory adir/sub1/ssdir:
${PROG} \[[a-z]* aborted\]: there is no version here; do .${PROG} checkout. first"
# The workaround is to leave off the "-r wip_test".
- dotest importc-8 "${testcvs} -q ci -m modify" \
+ dotest importc-7a "${testcvs} -q ci -m modify" \
"Checking in cdir/cfile;
${TESTDIR}/cvsroot/first-dir/cdir/cfile,v <-- cfile
new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1
done"
else
# Remote doesn't have the bug in the first place.
- dotest importc-7 "${testcvs} -q ci -m modify -r wip_test" \
+ dotest importc-7r "${testcvs} -q ci -m modify -r wip_test" \
"Checking in cdir/cfile;
${TESTDIR}/cvsroot/first-dir/cdir/cfile,v <-- cfile
new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1
@@ -5688,6 +5760,63 @@ M file2
R file3
A file8"
+ # Checkout the mainline again to try merging from the trunk
+ # to a branch.
+ cd ..
+ rm -r first-dir
+ dotest join-30 "${testcvs} -q co first-dir" \
+'U first-dir/file2
+U first-dir/file3
+U first-dir/file4
+U first-dir/file7'
+ cd first-dir
+
+ # Tag the current revisions on the trunk.
+ dotest join-31 "${testcvs} -q tag T3 ." \
+'T file2
+T file3
+T file4
+T file7'
+
+ # Modify file7.
+ echo 'second revision of file7' > file7
+ dotest join-32 "${testcvs} -q ci -mx ." \
+"Checking in file7;
+${TESTDIR}/cvsroot/first-dir/file7,v <-- file7
+new revision: 1\.2; previous revision: 1\.1
+done"
+
+ # And Tag again.
+ dotest join-33 "${testcvs} -q tag T4 ." \
+'T file2
+T file3
+T file4
+T file7'
+
+ # Now update branch to T3.
+ cd ../../2/first-dir
+ dotest join-34 "${testcvs} -q up -jT3" \
+"${PROG} [a-z]*: file file4 does not exist, but is present in revision T3
+U file7"
+
+ # Verify that the right changes have been scheduled.
+ dotest join-35 "${testcvs} -q update" \
+'A file7'
+
+ # Now update to T4.
+ # This is probably a bug, although in this particular case it just
+ # happens to do the right thing; see above join-20.
+ dotest join-36 "${testcvs} -q up -j T3 -j T4" \
+"A file7
+RCS file: ${TESTDIR}/cvsroot/first-dir/file7,v
+retrieving revision 1\.1
+retrieving revision 1\.2
+Merging differences between 1\.1 and 1\.2 into file7"
+
+ # Verify that the right changes have been scheduled.
+ dotest join-37 "${testcvs} -q update" \
+'A file7'
+
cd ../..
rm -r 1 2 3
@@ -5975,6 +6104,49 @@ C m"
rm -rf ${CVSROOT_DIRNAME}/$module
;;
+ join-admin)
+ mkdir 1; cd 1
+ dotest join-admin-1 "$testcvs -q co -l ." ''
+ module=x
+ mkdir $module
+ $testcvs -q add $module >>$LOGFILE 2>&1
+ cd $module
+
+ # Create a file so applying the first tag works.
+ echo foo > a
+ $testcvs -Q add a > /dev/null 2>&1
+ $testcvs -Q ci -m. a > /dev/null 2>&1
+
+ $testcvs -Q tag -b B
+ $testcvs -Q tag -b M1
+ echo '$''Id$' > b
+ $testcvs -Q add b > /dev/null 2>&1
+ $testcvs -Q ci -m. b > /dev/null 2>&1
+ $testcvs -Q tag -b M2
+
+ $testcvs -Q update -r B
+ $testcvs -Q update -kk -jM1 -jM2
+ $testcvs -Q ci -m. b >/dev/null 2>&1
+
+ $testcvs -Q update -A
+
+ # Verify that the -kk flag from the update did not
+ # propagate to the repository.
+ dotest join-admin-1 "$testcvs status b" \
+"===================================================================
+File: b Status: Up-to-date
+
+ Working revision: 1\.1.*
+ Repository revision: 1\.1 ${TESTDIR}/cvsroot/x/b,v
+ Sticky Tag: (none)
+ Sticky Date: (none)
+ Sticky Options: (none)"
+
+ cd ../..
+ rm -rf 1
+ rm -rf ${CVSROOT_DIRNAME}/$module
+ ;;
+
new) # look for stray "no longer pertinent" messages.
mkdir ${CVSROOT_DIRNAME}/first-dir
@@ -6262,9 +6434,24 @@ File: a Status: File had conflicts on merge
"${PROG} [a-z]*: file .a. had a conflict and has not been modified
${PROG} \[[a-z]* aborted\]: correct above errors first!"
- echo lame attempt at resolving it >>a
# Try to check in the file with the conflict markers in it.
- dotest conflicts-status-2 "${testcvs} status a" \
+ # Make sure we detect any one of the three conflict markers
+ mv a aa
+ grep '^<<<<<<<' aa >a
+ dotest conflicts-status-2 "${testcvs} -nq ci -m try a" \
+"${PROG} [a-z]*: warning: file .a. seems to still contain conflict indicators"
+
+ grep '^=======' aa >a
+ dotest conflicts-status-3 "${testcvs} -nq ci -m try a" \
+"${PROG} [a-z]*: warning: file .a. seems to still contain conflict indicators"
+
+ grep '^>>>>>>>' aa >a
+ dotest conflicts-status-4 "${testcvs} -qn ci -m try a" \
+"${PROG} [a-z]*: warning: file .a. seems to still contain conflict indicators"
+
+ mv aa a
+ echo lame attempt at resolving it >>a
+ dotest conflicts-status-5 "${testcvs} status a" \
"===================================================================
File: a Status: File had conflicts on merge
@@ -6283,7 +6470,7 @@ done"
# OK, the user saw the warning (good user), and now
# resolves it for real.
echo resolve conflict >a
- dotest conflicts-status-3 "${testcvs} status a" \
+ dotest conflicts-status-6 "${testcvs} status a" \
"===================================================================
File: a Status: Locally Modified
@@ -6297,7 +6484,7 @@ File: a Status: Locally Modified
${TESTDIR}/cvsroot/first-dir/a,v <-- a
new revision: 1\.4; previous revision: 1\.3
done"
- dotest conflicts-status-4 "${testcvs} status a" \
+ dotest conflicts-status-7 "${testcvs} status a" \
"===================================================================
File: a Status: Up-to-date
@@ -6790,6 +6977,62 @@ ${PROG} update: cannot open CVS/Entries for reading: No such file or directory"
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ clean)
+ # Test update -C (overwrite local mods w/ repository copies)
+ mkdir 1; cd 1
+ dotest clean-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest clean-2 "${testcvs} add first-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
+ cd first-dir
+ echo "The usual boring test text." > cleanme.txt
+ dotest clean-3 "${testcvs} add cleanme.txt" \
+"${PROG} [a-z]*: scheduling file .cleanme\.txt. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ dotest clean-4 "${testcvs} -q ci -m clean-3" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/cleanme\.txt,v
+done
+Checking in cleanme\.txt;
+${TESTDIR}/cvsroot/first-dir/cleanme\.txt,v <-- cleanme\.txt
+initial revision: 1\.1
+done"
+ # Okay, preparation is done, now test.
+ # Check that updating an unmodified copy works.
+ dotest clean-5 "${testcvs} -q update" ''
+ # Check that updating -C an unmodified copy works.
+ dotest clean-6 "${testcvs} -q update -C" ''
+ # Check that updating a modified copy works.
+ echo "fish" >> cleanme.txt
+ dotest clean-7 "${testcvs} -q update" 'M cleanme\.txt'
+ # Check that updating -C a modified copy works.
+ dotest clean-8 "${testcvs} -q update -C" \
+"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1)
+U cleanme\.txt"
+ # And check that the backup copy really was made.
+ dotest clean-9 "cat .#cleanme.txt.1.1" \
+"The usual boring test text\.
+fish"
+
+ # Do it all again, this time naming the file explicitly.
+ rm .#cleanme.txt.1.1
+ dotest clean-10 "${testcvs} -q update cleanme.txt" ''
+ dotest clean-11 "${testcvs} -q update -C cleanme.txt" ''
+ echo "bluegill" >> cleanme.txt
+ dotest clean-12 "${testcvs} -q update cleanme.txt" 'M cleanme\.txt'
+ dotest clean-13 "${testcvs} -q update -C cleanme.txt" \
+"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1)
+U cleanme\.txt"
+ # And check that the backup copy really was made.
+ dotest clean-14 "cat .#cleanme.txt.1.1" \
+"The usual boring test text\.
+bluegill"
+
+ # Done. Clean up.
+ cd ../..
+ rm -rf 1
+ rm -rf ${TESTDIR}/cvsroot/first-dir
+ ;;
+
modules)
# Tests of various ways to define and use modules.
# Roadmap to various modules tests:
@@ -6802,6 +7045,7 @@ ${PROG} update: cannot open CVS/Entries for reading: No such file or directory"
# ampersand modules: modules2
# -s: modules.
# -d: modules, modules3, cvsadm
+ # -i, -o, -u, -e, -t: modules5
# slashes in module names: modules3
############################################################
@@ -6893,76 +7137,88 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
mkdir 1
cd 1
- if ${testcvs} -q co first-dir; then
- pass 143
- else
- fail 143
- fi
+ dotest modules-143 "${testcvs} -q co first-dir" ""
cd first-dir
mkdir subdir
- ${testcvs} add subdir >>${LOGFILE}
- cd subdir
+ dotest modules-143a "${testcvs} add subdir" \
+"Directory ${TESTDIR}/cvsroot/first-dir/subdir added to the repository"
+ cd subdir
mkdir ssdir
- ${testcvs} add ssdir >>${LOGFILE}
+ dotest modules-143b "${testcvs} add ssdir" \
+"Directory ${TESTDIR}/cvsroot/first-dir/subdir/ssdir added to the repository"
touch a b
- if ${testcvs} add a b 2>>${LOGFILE} ; then
- pass 144
- else
- fail 144
- fi
+ dotest modules-144 "${testcvs} add a b" \
+"${PROG} [a-z]*: scheduling file .a. for addition
+${PROG} [a-z]*: scheduling file .b. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
- if ${testcvs} ci -m added >>${LOGFILE} 2>&1; then
- pass 145
- else
- fail 145
- fi
+ dotest modules-145 "${testcvs} ci -m added" \
+"${PROG} [a-z]*: Examining .
+${PROG} [a-z]*: Examining ssdir
+RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/a,v
+done
+Checking in a;
+${TESTDIR}/cvsroot/first-dir/subdir/a,v <-- a
+initial revision: 1\.1
+done
+RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/b,v
+done
+Checking in b;
+${TESTDIR}/cvsroot/first-dir/subdir/b,v <-- b
+initial revision: 1\.1
+done"
cd ..
- if ${testcvs} -q co CVSROOT >>${LOGFILE}; then
- pass 146
- else
- fail 146
- fi
+ dotest modules-146 "${testcvs} -q co CVSROOT" \
+"U CVSROOT/checkoutlist
+U CVSROOT/commitinfo
+U CVSROOT/config
+U CVSROOT/cvswrappers
+U CVSROOT/editinfo
+U CVSROOT/loginfo
+U CVSROOT/modules
+U CVSROOT/notify
+U CVSROOT/rcsinfo
+U CVSROOT/taginfo
+U CVSROOT/verifymsg"
# Here we test that CVS can deal with CVSROOT (whose repository
# is at top level) in the same directory as subdir (whose repository
# is a subdirectory of first-dir). TODO: Might want to check that
# files can actually get updated in this state.
- if ${testcvs} -q update; then
- pass 147
- else
- fail 147
- fi
+ dotest modules-147 "${testcvs} -q update" ""
+
+ cat >CVSROOT/modules <<EOF
+realmodule first-dir/subdir a
+dirmodule first-dir/subdir
+namedmodule -d nameddir first-dir/subdir
+aliasmodule -a first-dir/subdir/a
+aliasnested -a first-dir/subdir/ssdir
+topfiles -a first-dir/file1 first-dir/file2
+world -a .
+statusmod -s Mungeable
+# Options must come before arguments. It is possible this should
+# be relaxed at some point (though the result would be bizarre for
+# -a); for now test the current behavior.
+bogusalias first-dir/subdir/a -a
+EOF
+ dotest modules-148 "${testcvs} ci -m 'add modules' CVSROOT/modules" \
+"Checking in CVSROOT/modules;
+${TESTDIR}/cvsroot/CVSROOT/modules,v <-- modules
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
- echo realmodule first-dir/subdir a >CVSROOT/modules
- echo dirmodule first-dir/subdir >>CVSROOT/modules
- echo namedmodule -d nameddir first-dir/subdir >>CVSROOT/modules
- echo aliasmodule -a first-dir/subdir/a >>CVSROOT/modules
- echo aliasnested -a first-dir/subdir/ssdir >>CVSROOT/modules
- echo topfiles -a first-dir/file1 first-dir/file2 >>CVSROOT/modules
- echo world -a . >>CVSROOT/modules
- echo statusmod -s Mungeable >>CVSROOT/modules
-
- # Options must come before arguments. It is possible this should
- # be relaxed at some point (though the result would be bizarre for
- # -a); for now test the current behavior.
- echo bogusalias first-dir/subdir/a -a >>CVSROOT/modules
- if ${testcvs} ci -m 'add modules' CVSROOT/modules \
- >>${LOGFILE} 2>&1; then
- pass 148
- else
- fail 148
- fi
cd ..
# The "statusmod" module contains an error; trying to use it
# will produce "modules file missing directory" I think.
# However, that shouldn't affect the ability of "cvs co -c" or
# "cvs co -s" to do something reasonable with it.
- dotest 148a0 "${testcvs} co -c" 'aliasmodule -a first-dir/subdir/a
+ dotest modules-148a0 "${testcvs} co -c" 'aliasmodule -a first-dir/subdir/a
aliasnested -a first-dir/subdir/ssdir
bogusalias first-dir/subdir/a -a
dirmodule first-dir/subdir
@@ -6974,7 +7230,7 @@ world -a \.'
# There is code in modules.c:save_d which explicitly skips
# modules defined with -a, which is why aliasmodule is not
# listed.
- dotest 148a1 "${testcvs} co -s" \
+ dotest modules-148a1 "${testcvs} co -s" \
'statusmod Mungeable
bogusalias NONE first-dir/subdir/a -a
dirmodule NONE first-dir/subdir
@@ -6982,123 +7238,60 @@ namedmodule NONE first-dir/subdir
realmodule NONE first-dir/subdir a'
# Test that real modules check out to realmodule/a, not subdir/a.
- if ${testcvs} co realmodule >>${LOGFILE}; then
- pass 149a1
- else
- fail 149a1
- fi
- if test -d realmodule && test -f realmodule/a; then
- pass 149a2
- else
- fail 149a2
- fi
- if test -f realmodule/b; then
- fail 149a3
- else
- pass 149a3
- fi
- if ${testcvs} -q co realmodule; then
- pass 149a4
- else
- fail 149a4
- fi
- if echo "yes" | ${testcvs} release -d realmodule >>${LOGFILE} ; then
- pass 149a5
- else
- fail 149a5
- fi
-
- dotest_fail 149b1 "${testcvs} co realmodule/a" \
+ dotest modules-149a1 "${testcvs} co realmodule" "U realmodule/a"
+ dotest modules-149a2 "test -d realmodule && test -f realmodule/a" ""
+ dotest_fail modules-149a3 "test -f realmodule/b" ""
+ dotest modules-149a4 "${testcvs} -q co realmodule" ""
+ dotest modules-149a5 "echo yes | ${testcvs} release -d realmodule" \
+"You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .realmodule.: "
+
+ dotest_fail modules-149b1 "${testcvs} co realmodule/a" \
"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \
"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory
'"${PROG}"' \[[a-z]* aborted\]: cannot expand modules'
# Now test the ability to check out a single file from a directory
- if ${testcvs} co dirmodule/a >>${LOGFILE}; then
- pass 150c
- else
- fail 150c
- fi
- if test -d dirmodule && test -f dirmodule/a; then
- pass 150d
- else
- fail 150d
- fi
- if test -f dirmodule/b; then
- fail 150e
- else
- pass 150e
- fi
- if echo "yes" | ${testcvs} release -d dirmodule >>${LOGFILE} ; then
- pass 150f
- else
- fail 150f
- fi
+ dotest modules-150c "${testcvs} co dirmodule/a" "U dirmodule/a"
+ dotest modules-150d "test -d dirmodule && test -f dirmodule/a" ""
+ dotest_fail modules-150e "test -f dirmodule/b" ""
+ dotest modules-150f "echo yes | ${testcvs} release -d dirmodule" \
+"You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .dirmodule.: "
# Now test the ability to correctly reject a non-existent filename.
# For maximum studliness we would check that an error message is
# being output.
- if ${testcvs} co dirmodule/nonexist >>${LOGFILE} 2>&1; then
- # We accept a zero exit status because it is what CVS does
- # (Dec 95). Probably the exit status should be nonzero,
- # however.
- pass 150g1
- else
- pass 150g1
- fi
+ # We accept a zero exit status because it is what CVS does
+ # (Dec 95). Probably the exit status should be nonzero,
+ # however.
+ dotest modules-150g1 "${testcvs} co dirmodule/nonexist" \
+"${PROG} [a-z]*: warning: new-born dirmodule/nonexist has disappeared"
# We tolerate the creation of the dirmodule directory, since that
# is what CVS does, not because we view that as preferable to not
# creating it.
- if test -f dirmodule/a || test -f dirmodule/b; then
- fail 150g2
- else
- pass 150g2
- fi
+ dotest_fail modules-150g2 "test -f dirmodule/a || test -f dirmodule/b" ""
rm -r dirmodule
# Now test that a module using -d checks out to the specified
# directory.
- dotest 150h1 "${testcvs} -q co namedmodule" 'U nameddir/a
+ dotest modules-150h1 "${testcvs} -q co namedmodule" \
+'U nameddir/a
U nameddir/b'
- if test -f nameddir/a && test -f nameddir/b; then
- pass 150h2
- else
- fail 150h2
- fi
+ dotest modules-150h2 "test -f nameddir/a && test -f nameddir/b" ""
echo add line >>nameddir/a
- dotest 150h3 "${testcvs} -q co namedmodule" 'M nameddir/a'
+ dotest modules-150h3 "${testcvs} -q co namedmodule" 'M nameddir/a'
rm nameddir/a
- dotest 150h4 "${testcvs} -q co namedmodule" 'U nameddir/a'
- if echo "yes" | ${testcvs} release -d nameddir >>${LOGFILE} ; then
- pass 150h99
- else
- fail 150h99
- fi
+ dotest modules-150h4 "${testcvs} -q co namedmodule" 'U nameddir/a'
+ dotest modules-150h99 "echo yes | ${testcvs} release -d nameddir" \
+"You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .nameddir.: "
# Now test that alias modules check out to subdir/a, not
# aliasmodule/a.
- if ${testcvs} co aliasmodule >>${LOGFILE}; then
- pass 151
- else
- fail 151
- fi
- if test -d aliasmodule; then
- fail 152
- else
- pass 152
- fi
+ dotest modules-151 "${testcvs} co aliasmodule" ""
+ dotest_fail modules-152 "test -d aliasmodule" ""
echo abc >>first-dir/subdir/a
- if (${testcvs} -q co aliasmodule | tee test153.tmp) \
- >>${LOGFILE}; then
- pass 153
- else
- fail 153
- fi
- echo 'M first-dir/subdir/a' >ans153.tmp
- if cmp test153.tmp ans153.tmp; then
- pass 154
- else
- fail 154
- fi
+ dotest modules-153 "${testcvs} -q co aliasmodule" "M first-dir/subdir/a"
cd ..
rm -r 1
@@ -7218,6 +7411,8 @@ done"
cd CVSROOT
echo 'ampermodule &first-dir &second-dir' > modules
echo 'combmodule third-dir file3 &first-dir' >> modules
+ echo 'ampdirmod -d newdir &first-dir &second-dir' >> modules
+ echo 'badmod -d newdir' >> modules
# Depending on whether the user also ran the modules test
# we will be checking in revision 1.2 or 1.3.
dotest modules2-2 "${testcvs} -q ci -m add-modules" \
@@ -7294,11 +7489,11 @@ initial revision: 1\.1
done"
cd ..
fi
+ cd ..
+ rm -r 1
# Now test the "combmodule" module (combining regular modules
# and ampersand modules in the same module definition).
- cd ..
- rm -r 1
mkdir 1; cd 1
dotest modules2-14 "${testcvs} co combmodule" \
"U combmodule/file3
@@ -7325,6 +7520,22 @@ U first-dir/amper1"
cd ..
rm -r 1
+ # Now test the "ampdirmod" and "badmod" modules to be sure that
+ # options work with ampersand modules but don't prevent the
+ # "missing directory" error message.
+ mkdir 1; cd 1
+ dotest modules2-20 "${testcvs} co ampdirmod" \
+"${PROG} [a-z]*: Updating first-dir
+U first-dir/amper1
+${PROG} [a-z]*: Updating second-dir"
+ dotest modules2-21 "test -f newdir/first-dir/amper1" ""
+ dotest_fail modules2-22 "${testcvs} co badmod" \
+"${PROG} [a-z]*: modules file missing directory for module badmod" \
+"${PROG} [a-z]*: modules file missing directory for module badmod
+${PROG} \[[a-z]* aborted\]: cannot expand modules"
+ cd ..
+ rm -r 1
+
# Test that CVS gives an error if one combines -a with
# other options.
# Probably would be better to break this out into a separate
@@ -7646,6 +7857,226 @@ add-it
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
+ modules5)
+ # Test module programs
+
+ mkdir ${CVSROOT_DIRNAME}/first-dir
+ mkdir 1
+ cd 1
+ dotest modules5-1 "${testcvs} -q co first-dir" ""
+ cd first-dir
+ mkdir subdir
+ dotest modules5-2 "${testcvs} add subdir" \
+"Directory ${TESTDIR}/cvsroot/first-dir/subdir added to the repository"
+ cd subdir
+ mkdir ssdir
+ dotest modules5-3 "${testcvs} add ssdir" \
+"Directory ${TESTDIR}/cvsroot/first-dir/subdir/ssdir added to the repository"
+ touch a b
+ dotest modules5-4 "${testcvs} add a b" \
+"${PROG} [a-z]*: scheduling file .a. for addition
+${PROG} [a-z]*: scheduling file .b. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
+
+ dotest modules5-5 "${testcvs} ci -m added" \
+"${PROG} [a-z]*: Examining .
+${PROG} [a-z]*: Examining ssdir
+RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/a,v
+done
+Checking in a;
+${TESTDIR}/cvsroot/first-dir/subdir/a,v <-- a
+initial revision: 1\.1
+done
+RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/b,v
+done
+Checking in b;
+${TESTDIR}/cvsroot/first-dir/subdir/b,v <-- b
+initial revision: 1\.1
+done"
+
+ cd ..
+ dotest modules5-6 "${testcvs} -q co CVSROOT" \
+"U CVSROOT/checkoutlist
+U CVSROOT/commitinfo
+U CVSROOT/config
+U CVSROOT/cvswrappers
+U CVSROOT/editinfo
+U CVSROOT/loginfo
+U CVSROOT/modules
+U CVSROOT/notify
+U CVSROOT/rcsinfo
+U CVSROOT/taginfo
+U CVSROOT/verifymsg"
+
+ for i in checkin checkout update export tag; do
+ cat >> ${CVSROOT_DIRNAME}/$i.sh <<EOF
+#! /bin/sh
+echo "$i script invoked in \`pwd\`"
+echo "args: \$@"
+EOF
+ chmod +x ${CVSROOT_DIRNAME}/$i.sh
+ done
+
+ OPTS="-i ${CVSROOT_DIRNAME}/checkin.sh -o${CVSROOT_DIRNAME}/checkout.sh -u ${CVSROOT_DIRNAME}/update.sh -e ${CVSROOT_DIRNAME}/export.sh -t${CVSROOT_DIRNAME}/tag.sh"
+ cat >CVSROOT/modules <<EOF
+realmodule ${OPTS} first-dir/subdir a
+dirmodule ${OPTS} first-dir/subdir
+namedmodule -d nameddir ${OPTS} first-dir/subdir
+EOF
+
+ dotest modules5-7 "${testcvs} ci -m 'add modules' CVSROOT/modules" \
+"" \
+"Checking in CVSROOT/modules;
+${TESTDIR}/cvsroot/CVSROOT/modules,v <-- modules
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+
+ cd ..
+ rm -rf first-dir
+ # Test that real modules check out to realmodule/a, not subdir/a.
+ if test "$remote" = "yes"; then
+ dotest modules5-8 "${testcvs} co realmodule" \
+"U realmodule/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule..
+checkout script invoked in .*
+args: realmodule"
+ else
+ dotest modules5-8 "${testcvs} co realmodule" \
+"U realmodule/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .realmodule..
+checkout script invoked in ${TESTDIR}/1
+args: realmodule"
+ fi
+ dotest modules5-9 "test -d realmodule && test -f realmodule/a" ""
+ dotest_fail modules5-10 "test -f realmodule/b" ""
+ if test "$remote" = "yes"; then
+ dotest modules5-11 "${testcvs} -q co realmodule" \
+"checkout script invoked in .*
+args: realmodule"
+ dotest modules5-12 "${testcvs} -q update" \
+"${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in /.*/realmodule
+args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ echo "change" >>realmodule/a
+ dotest modules5-13 "${testcvs} -q ci -m." \
+"Checking in realmodule/a;
+${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a
+new revision: 1\.2; previous revision: 1\.1
+done
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkin\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+checkin script invoked in /.*/realmodule
+args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ else
+ dotest modules5-11 "${testcvs} -q co realmodule" \
+"checkout script invoked in ${TESTDIR}/1
+args: realmodule"
+ dotest modules5-12 "${testcvs} -q update" \
+"${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${TESTDIR}/1/realmodule
+args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ echo "change" >>realmodule/a
+ dotest modules5-13 "${testcvs} -q ci -m." \
+"Checking in realmodule/a;
+${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a
+new revision: 1\.2; previous revision: 1\.1
+done
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkin\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+checkin script invoked in ${TESTDIR}/1/realmodule
+args: ${CVSROOT_DIRNAME}/first-dir/subdir"
+ fi
+ dotest modules5-14 "echo yes | ${testcvs} release -d realmodule" \
+"You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .realmodule.: "
+ dotest modules5-15 "${testcvs} -q rtag -Dnow MYTAG realmodule" \
+"tag script invoked in ${TESTDIR}/1
+args: realmodule MYTAG"
+ if test "$remote" = "yes"; then
+ dotest modules5-16 "${testcvs} -q export -r MYTAG realmodule" \
+"U realmodule/a
+export script invoked in .*
+args: realmodule"
+ else
+ dotest modules5-16 "${testcvs} -q export -r MYTAG realmodule" \
+"U realmodule/a
+export script invoked in ${TESTDIR}/1
+args: realmodule"
+ fi
+
+ dotest_fail modules5-17 "${testcvs} co realmodule/a" \
+"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \
+"${PROG}"' [a-z]*: module `realmodule/a'\'' is a request for a file in a module which is not a directory
+'"${PROG}"' \[[a-z]* aborted\]: cannot expand modules'
+
+ # FIXCVS: The client gets confused in these cases and tries to
+ # store the scripts in the wrong places.
+ if test "$remote" != "yes"; then
+ # Now test the ability to check out a single file from a directory
+ dotest modules5-18 "${testcvs} co dirmodule/a" \
+"U dirmodule/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
+checkout script invoked in ${TESTDIR}/1
+args: dirmodule"
+ dotest modules5-19 "test -d dirmodule && test -f dirmodule/a" ""
+ dotest_fail modules5-20 "test -f dirmodule/b" ""
+ dotest modules5-21 "echo yes | ${testcvs} release -d dirmodule" \
+"You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .dirmodule.: "
+
+ # Now test the ability to correctly reject a non-existent filename.
+ # For maximum studliness we would check that an error message is
+ # being output.
+ # We accept a zero exit status because it is what CVS does
+ # (Dec 95). Probably the exit status should be nonzero,
+ # however.
+ dotest modules5-22 "${testcvs} co dirmodule/nonexist" \
+"${PROG} [a-z]*: warning: new-born dirmodule/nonexist has disappeared
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule..
+checkout script invoked in ${TESTDIR}/1
+args: dirmodule"
+
+ # We tolerate the creation of the dirmodule directory, since that
+ # is what CVS does, not because we view that as preferable to not
+ # creating it.
+ dotest_fail modules5-23 "test -f dirmodule/a || test -f dirmodule/b" ""
+ rm -r dirmodule
+
+ # Now test that a module using -d checks out to the specified
+ # directory.
+ dotest modules5-24 "${testcvs} -q co namedmodule" \
+"U nameddir/a
+U nameddir/b
+checkout script invoked in ${TESTDIR}/1
+args: nameddir"
+ dotest modules5-25 "test -f nameddir/a && test -f nameddir/b" ""
+ echo add line >>nameddir/a
+ # This seems suspicious: when we checkout an existing directory,
+ # the checkout script gets executed in addition to the update
+ # script. Is that by design or accident?
+ dotest modules5-26 "${testcvs} -q co namedmodule" \
+"M nameddir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${TESTDIR}/1/nameddir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir
+checkout script invoked in ${TESTDIR}/1
+args: nameddir"
+ rm nameddir/a
+ dotest modules5-27 "${testcvs} -q co namedmodule" \
+"U nameddir/a
+${PROG} [a-z]*: Executing ..${CVSROOT_DIRNAME}/update\.sh. .${CVSROOT_DIRNAME}/first-dir/subdir..
+update script invoked in ${TESTDIR}/1/nameddir
+args: ${CVSROOT_DIRNAME}/first-dir/subdir
+checkout script invoked in ${TESTDIR}/1
+args: nameddir"
+ dotest modules5-28 "echo yes | ${testcvs} release -d nameddir" \
+"You have \[0\] altered files in this repository\.
+Are you sure you want to release (and delete) directory .nameddir.: "
+ fi
+
+ cd ..
+ rm -rf 1 ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/*.sh
+ ;;
+
mkmodules-temp-file-removal)
# When a file listed in checkoutlist doesn't exist, cvs-1.10.4
# would fail to remove the CVSROOT/.#[0-9]* temporary file it
@@ -7777,7 +8208,9 @@ Checking in CVSROOT/modules;
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} [a-z]*: Rebuilding administrative file database" \
+"${PROG} [a-z]*: Examining .
+${PROG} [a-z]*: Examining CVSROOT"
rm -rf CVS CVSROOT;
# Create the various modules
@@ -9115,6 +9548,8 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
"U CVSROOT/modules"
echo "# Module defs for emptydir tests" > CVSROOT/modules
echo "2d1mod -d dir2d1/sub2d1 mod1" >> CVSROOT/modules
+ echo "2d1moda -d dir2d1/suba moda/modasub" >> CVSROOT/modules
+ echo "comb -a 2d1mod 2d1moda" >> CVSROOT/modules
dotest emptydir-2 "${testcvs} ci -m add-modules" \
"${PROG} [a-z]*: Examining CVSROOT
@@ -9122,27 +9557,39 @@ Checking in CVSROOT/modules;
${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
-${PROG} [a-z]*: Rebuilding administrative file database"
+${PROG} [a-z]*: Rebuilding administrative file database" \
+"${PROG} [a-z]*: Examining CVSROOT"
rm -rf CVS CVSROOT
- mkdir ${CVSROOT_DIRNAME}/mod1
+ mkdir ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/moda
# Populate. Not sure we really need to do this.
- dotest emptydir-3 "${testcvs} co mod1" \
-"${PROG} [a-z]*: Updating mod1"
+ dotest emptydir-3 "${testcvs} -q co -l ." ""
+ dotest emptydir-3a "${testcvs} co mod1 moda" \
+"${PROG} [a-z]*: Updating mod1
+${PROG} [a-z]*: Updating moda"
echo "file1" > mod1/file1
- cd mod1
- dotest emptydir-4 "${testcvs} add file1" \
-"${PROG} [a-z]*: scheduling file .file1. for addition
-${PROG} [a-z]*: use '${PROG} commit' to add this file permanently"
- cd ..
- dotest emptydir-5 "${testcvs} -q ci -m yup mod1" \
+ mkdir moda/modasub
+ dotest emptydir-3b "${testcvs} add moda/modasub" \
+"Directory ${TESTDIR}/cvsroot/moda/modasub added to the repository"
+ echo "filea" > moda/modasub/filea
+ dotest emptydir-4 "${testcvs} add mod1/file1 moda/modasub/filea" \
+"${PROG} [a-z]*: scheduling file .mod1/file1. for addition
+${PROG} [a-z]*: scheduling file .moda/modasub/filea. for addition
+${PROG} [a-z]*: use '${PROG} commit' to add these files permanently"
+ dotest emptydir-5 "${testcvs} -q ci -m yup" \
"RCS file: ${CVSROOT_DIRNAME}/mod1/file1,v
done
Checking in mod1/file1;
${CVSROOT_DIRNAME}/mod1/file1,v <-- file1
initial revision: 1\.1
+done
+RCS file: ${CVSROOT_DIRNAME}/moda/modasub/filea,v
+done
+Checking in moda/modasub/filea;
+${CVSROOT_DIRNAME}/moda/modasub/filea,v <-- filea
+initial revision: 1\.1
done"
- rm -rf mod1 CVS
+ rm -rf mod1 moda CVS
# End Populate.
dotest emptydir-6 "${testcvs} co 2d1mod" \
@@ -9154,11 +9601,11 @@ U dir2d1/sub2d1/file1"
# else) in Emptydir; Emptydir is a placeholder indicating that
# the working directory doesn't correspond to anything in
# the repository.
- dotest emptydir-7 "${testcvs} add emptyfile" \
-"${PROG} [a-z]*: scheduling file .emptyfile. for addition
-${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
- dotest_fail emptydir-8 "${testcvs} -q ci -m add" \
-"${PROG} \[[a-z]* aborted\]: cannot check in to ${TESTDIR}/cvsroot/CVSROOT/Emptydir"
+ dotest_fail emptydir-7 "${testcvs} add emptyfile" \
+"${PROG} \[[a-z]* aborted\]: cannot add to ${TESTDIR}/cvsroot/CVSROOT/Emptydir"
+ mkdir emptydir
+ dotest_fail emptydir-8 "${testcvs} add emptydir" \
+"${PROG} \[[a-z]* aborted\]: cannot add to ${TESTDIR}/cvsroot/CVSROOT/Emptydir"
cd ..
rm -rf CVS dir2d1
@@ -9173,11 +9620,25 @@ ${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
dotest emptydir-11 "${testcvs} -q -n update -d -P" ''
cd ../..
rm -r edir
+ cd ..
+ # Now start playing with moda.
+ mkdir 2; cd 2
+ dotest emptydir-12 "${testcvs} -q co 2d1moda" \
+"U dir2d1/suba/filea"
+ # OK, this is the crux of the matter. Some people think
+ # it would be more logical if this showed "moda". But why
+ # "moda" (from module 2d1moda) and not "." (from module 2d1mod)?
+ dotest emptydir-13 "cat dir2d1/CVS/Repository" "CVSROOT/Emptydir"
+ dotest emptydir-14 "${testcvs} co comb" \
+"${PROG} [a-z]*: Updating dir2d1/sub2d1
+U dir2d1/sub2d1/file1
+${PROG} [a-z]*: Updating dir2d1/suba"
+ dotest emptydir-15 "cat dir2d1/CVS/Repository" "CVSROOT/Emptydir"
cd ..
- rm -r 1
- rm -rf ${CVSROOT_DIRNAME}/mod1
+ rm -r 1 2
+ rm -rf ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/moda
# I guess for the moment the convention is going to be
# that we don't need to remove ${CVSROOT_DIRNAME}/CVSROOT/Emptydir
;;
@@ -10002,6 +10463,14 @@ done"
cd ..
dotest errmsg2-8 "${testcvs} add first-dir/sdir" \
"Directory ${TESTDIR}/cvsroot/first-dir/sdir added to the repository"
+ # while we're here... check commit with no CVS directory
+ dotest_fail errmsg2-8a "${testcvs} -q ci first-dir nonexistant" \
+"${PROG} [a-z]*: nothing known about .nonexistant'
+${PROG} \[[a-z]* aborted\]: correct above errors first!"
+ dotest_fail errmsg2-8b "${testcvs} -q ci nonexistant first-dir" \
+"${PROG} [a-z]*: nothing known about .nonexistant'
+${PROG} \[[a-z]* aborted\]: correct above errors first!"
+ dotest errmsg2-8c "${testcvs} -q ci first-dir" ""
cd first-dir
@@ -10075,6 +10544,16 @@ done"
dotest_fail errmsg2-19 "${testcvs} annotate -rtest -Dyesterday" \
"${PROG} \[[a-z]* aborted\]: rcsbuf_open: internal error"
+ # trying to import the repository
+
+ if test "$remote" = "no"; then
+ cd ${CVSROOT_DIRNAME}
+ dotest_fail errmsg2-20 "${testcvs} import -mtest . A B" \
+"${PROG} \[[a-z]* aborted\]: attempt to import the repository"
+ dotest_fail errmsg2-21 "${testcvs} import -mtest first-dir A B" \
+"${PROG} \[[a-z]* aborted\]: attempt to import the repository"
+ fi
+
cd ..
rm -r 1
rm -rf ${TESTDIR}/cvsroot/first-dir
@@ -10366,7 +10845,25 @@ Fnw1 _watched=
D _watched="
cd ..
- cd ..
+ # Do a little error testing
+ dotest devcom2-18 "${testcvs} -q co -d first+dir first-dir" \
+"U first${PLUS}dir/nw1
+U first${PLUS}dir/w1
+U first${PLUS}dir/w2
+U first${PLUS}dir/w3"
+ cd first+dir
+ dotest_fail devcom2-19 "${testcvs} edit" \
+"${PROG} \[[a-z]* aborted\]: current directory (${TESTDIR}/2/first${PLUS}dir) contains an invalid character (${PLUS},>;=\\\\t\\\\n)"
+
+ # Make sure there are no droppings lying around
+ dotest devcom2-20 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \
+"Fw1 _watched=
+Fw2 _watched=
+Fw3 _watched=
+Fnw1 _watched=
+D _watched="
+
+ cd ../..
# Use -f because of the readonly files.
rm -rf 1 2
@@ -10639,14 +11136,9 @@ done"
rm -f CVS/Baserev
# This will fail on most systems.
- if echo "yes" | ${testcvs} -Q unedit $file \
- >${TESTDIR}/test.tmp 2>&1 ; then
- dotest unedit-without-baserev-4 "cat ${TESTDIR}/test.tmp" \
+ echo "yes" | dotest unedit-without-baserev-4 "${testcvs} -Q unedit $file" \
"m has been modified; revert changes${QUESTION} ${PROG} unedit: m not mentioned in CVS/Baserev
${PROG} unedit: run update to complete the unedit"
- else
- fail unedit-without-baserev-4
- fi
# SunOS4.1.4 systems make it this far, but with a corrupted
# CVS/Entries file. Demonstrate the corruption!
@@ -10694,13 +11186,9 @@ rcsmerge: warning: conflicts during merge
${PROG} [a-z]*: conflicts found in m
C m"
rm CVS/Baserev
- if (echo yes | ${testcvs} unedit m) >${TESTDIR}/test.tmp 2>&1; then
- dotest unedit-without-baserev-14 "cat ${TESTDIR}/test.tmp" \
+ echo yes | dotest unedit-without-baserev-14 "${testcvs} unedit m" \
"m has been modified; revert changes${QUESTION} ${PROG} unedit: m not mentioned in CVS/Baserev
${PROG} unedit: run update to complete the unedit"
- else
- fail unedit-without-baserev-14
- fi
if test "$remote" = yes; then
dotest unedit-without-baserev-15 "${testcvs} -q update" "U m"
else
@@ -10844,26 +11332,14 @@ ${QUESTION} first-dir/rootig.c
${QUESTION} second-dir/.cvsignore
${QUESTION} second-dir/notig.c"
- if echo yes | ${testcvs} release -d first-dir \
- >${TESTDIR}/ignore.tmp; then
- pass ignore-192
- else
- fail ignore-192
- fi
- dotest ignore-193 "cat ${TESTDIR}/ignore.tmp" \
+ echo yes | dotest ignore-192 "${testcvs} release -d first-dir" \
"${QUESTION} \.cvsignore
You have \[0\] altered files in this repository.
Are you sure you want to release (and delete) directory .first-dir': "
echo add a line >>second-dir/foobar.c
rm second-dir/notig.c second-dir/.cvsignore
- if echo yes | ${testcvs} release -d second-dir \
- >${TESTDIR}/ignore.tmp; then
- pass ignore-194
- else
- fail ignore-194
- fi
- dotest ignore-195 "cat ${TESTDIR}/ignore.tmp" \
+ echo yes | dotest ignore-194 "${testcvs} release -d second-dir" \
"M foobar.c
You have \[1\] altered files in this repository.
Are you sure you want to release (and delete) directory .second-dir': "
@@ -10871,7 +11347,6 @@ Are you sure you want to release (and delete) directory .second-dir': "
rm -r 1
cd ..
rm -r wnt
- rm ${TESTDIR}/ignore.tmp
rm -rf ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/second-dir
;;
@@ -10887,8 +11362,8 @@ Are you sure you want to release (and delete) directory .second-dir': "
mkdir ${CVSROOT_DIRNAME}/first-dir
mkdir 1; cd 1
dotest binfiles-1 "${testcvs} -q co first-dir" ''
- awk 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
- </dev/null | tr '@' '\000' >binfile.dat
+ ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
+ </dev/null | ${TR} '@' '\000' >binfile.dat
cat binfile.dat binfile.dat >binfile2.dat
cd first-dir
cp ../binfile.dat binfile
@@ -11159,8 +11634,8 @@ total revisions: 1
# each be distinct from each other. We also make sure to include
# a few likely end-of-line patterns to make sure nothing is
# being munged as if in text mode.
- awk 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
- </dev/null | tr '@' '\000' >../binfile
+ ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
+ </dev/null | ${TR} '@' '\000' >../binfile
cat ../binfile ../binfile >../binfile2
cat ../binfile2 ../binfile >../binfile3
@@ -11321,8 +11796,8 @@ checkin
mkdir ${CVSROOT_DIRNAME}/first-dir
mkdir 1; cd 1
dotest binfiles3-1 "${testcvs} -q co first-dir" ''
- awk 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
- </dev/null | tr '@' '\000' >binfile.dat
+ ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
+ </dev/null | ${TR} '@' '\000' >binfile.dat
cd first-dir
echo hello >file1
dotest binfiles3-2 "${testcvs} add file1" \
@@ -11377,9 +11852,9 @@ total revisions: 3
# OK, now test admin -o on a binary file. See "admin"
# test for a more complete list of admin -o tests.
cp ${TESTDIR}/1/binfile.dat ${TESTDIR}/1/binfile4.dat
- echo '%%$$##@@!!jjiiuull' | tr j '\000' >>${TESTDIR}/1/binfile4.dat
+ echo '%%$$##@@!!jjiiuull' | ${TR} j '\000' >>${TESTDIR}/1/binfile4.dat
cp ${TESTDIR}/1/binfile4.dat ${TESTDIR}/1/binfile5.dat
- echo 'aawwee%$$##@@!!jjil' | tr w '\000' >>${TESTDIR}/1/binfile5.dat
+ echo 'aawwee%$$##@@!!jjil' | ${TR} w '\000' >>${TESTDIR}/1/binfile5.dat
cp ../binfile4.dat file1
dotest binfiles3-9 "${testcvs} -q ci -m change" \
@@ -12011,6 +12486,7 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
dotest info-1 "${testcvs} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}"
cd CVSROOT
+ rm -f $TESTDIR/testlog $TESTDIR/testlog2
echo "ALL sh -c \"echo x\${=MYENV}\${=OTHER}y\${=ZEE}=\$USER=\$CVSROOT= >>$TESTDIR/testlog; cat >/dev/null\"" > loginfo
# The following cases test the format string substitution
echo "ALL echo %{sVv} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
@@ -12051,11 +12527,18 @@ ${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
initial revision: 1\.1
done
${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}"
+ echo line0 >>file1
+ dotest info-6b "${testcvs} -q -sOTHER=foo ci -m mod-it" \
+"Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+new revision: 1\.2; previous revision: 1\.1
+done
+${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}"
echo line1 >>file1
dotest info-7 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \
"Checking in file1;
${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
-new revision: 1\.2; previous revision: 1\.1
+new revision: 1\.3; previous revision: 1\.2
done"
cd ..
dotest info-9 "cat $TESTDIR/testlog" "xenv-valueyz=${username}=${TESTDIR}/cvsroot="
@@ -12068,6 +12551,11 @@ first-dir file1,1.1,1.2
first-dir 1.2
first-dir file1
first-dir 1.1AX
+first-dir file1ux
+first-dir file1,1.2,1.3
+first-dir 1.3
+first-dir file1
+first-dir 1.2AX
first-dir file1ux'
cd CVSROOT
@@ -12075,7 +12563,7 @@ first-dir file1ux'
dotest info-11 "${testcvs} -q -s ZEE=garbage ci -m nuke-loginfo" \
"Checking in loginfo;
${TESTDIR}/cvsroot/CVSROOT/loginfo,v <-- loginfo
-new revision: 1\.[0-9]; previous revision: 1\.[0-9]
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
${PROG} [a-z]*: Rebuilding administrative file database"
@@ -12086,6 +12574,7 @@ if head -1 < \$1 | grep '^BugId:[ ]*[0-9][0-9]*$' > /dev/null; then
exit 0
else
echo "No BugId found."
+ sleep 1
exit 1
fi
EOF
@@ -12094,7 +12583,7 @@ EOF
dotest info-v1 "${testcvs} -q ci -m add-verification" \
"Checking in verifymsg;
${TESTDIR}/cvsroot/CVSROOT/verifymsg,v <-- verifymsg
-new revision: 1\.2; previous revision: 1\.1
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
${PROG} [a-z]*: Rebuilding administrative file database"
@@ -12111,7 +12600,7 @@ EOF
dotest info-v3 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \
"Checking in file1;
${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
-new revision: 1\.3; previous revision: 1\.2
+new revision: 1\.4; previous revision: 1\.3
done"
cd ..
mkdir another-dir
@@ -12130,7 +12619,7 @@ ${PROG} \[[a-z]* aborted\]: Message verification failed"
dotest info-cleanup-verifymsg "${testcvs} -q ci -m nuke-verifymsg" \
"Checking in verifymsg;
${TESTDIR}/cvsroot/CVSROOT/verifymsg,v <-- verifymsg
-new revision: 1\.[0-9]; previous revision: 1\.[0-9]
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
${PROG} [a-z]*: Rebuilding administrative file database"
cd ..
@@ -12392,8 +12881,10 @@ U file1'
# -h: admin-19a-log
# -N: log, log2, admin-19a-log
# -b, -r: log
- # -d: rcs
- # -s, -R: rcs3
+ # -d: logopt, rcs
+ # -s: logopt, rcs3
+ # -R: logopt, rcs3
+ # -w, -t: not tested yet (TODO)
# Check in a file with a few revisions and branches.
mkdir ${CVSROOT_DIRNAME}/first-dir
@@ -12560,6 +13051,33 @@ description:
${log_rev3}
${log_trailer}"
+# Check that unusual syntax works correctly.
+
+ dotest log-14c "${testcvs} log -r: file1" \
+"${log_header}
+${log_tags}
+${log_header2}
+total revisions: 5; selected revisions: 1
+description:
+${log_rev3}
+${log_trailer}"
+ dotest log-14d "${testcvs} log -r, file1" \
+"${log_header}
+${log_tags}
+${log_header2}
+total revisions: 5; selected revisions: 1
+description:
+${log_rev3}
+${log_trailer}"
+ dotest log-14e "${testcvs} log -r. file1" \
+"${log_header}
+${log_tags}
+${log_header2}
+total revisions: 5; selected revisions: 1
+description:
+${log_rev3}
+${log_trailer}"
+
dotest log-15 "${testcvs} log -r1.2 file1" \
"${log_header}
${log_tags}
@@ -12600,6 +13118,18 @@ description:
${log_rev2b}
${log_trailer}"
+ # Multiple -r options are undocumented; see comments in
+ # cvs.texinfo about whether they should be deprecated.
+ dotest log-18a "${testcvs} log -r1.2.2.2 -r1.3:1.3 file1" \
+"${log_header}
+${log_tags}
+${log_header2}
+total revisions: 5; selected revisions: 2
+description:
+${log_rev3}
+${log_rev2b}
+${log_trailer}"
+
# This test would fail with the old invocation of rlog, but it
# works with the builtin log support.
dotest log-19 "${testcvs} log -rbranch. file1" \
@@ -12730,18 +13260,13 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
1
============================================================================="
- # I believe that in Real Life (TM), this is broken for remote.
- # That is, the filename in question must be the filename of a
- # file on the server. It only happens to work here because the
- # client machine and the server machine are one and the same.
echo 'longer description' >${TESTDIR}/descrip
echo 'with two lines' >>${TESTDIR}/descrip
dotest log2-7 "${testcvs} admin -t${TESTDIR}/descrip file1" \
"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
done"
dotest_fail log2-7a "${testcvs} admin -t${TESTDIR}/nonexist file1" \
-"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
-${PROG} \[[a-z]* aborted\]: can't stat ${TESTDIR}/nonexist: No such file or directory"
+"${PROG} \[[a-z]* aborted\]: can't stat ${TESTDIR}/nonexist: No such file or directory"
dotest log2-8 "${testcvs} log -N file1" "
RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
Working file: file1
@@ -12760,22 +13285,13 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
1
============================================================================="
- # Reading the description from stdin is broken for remote.
- # See comments in cvs.texinfo for a few more notes on this.
- if test "x$remote" = xno; then
+ # TODO: `cvs admin -t "my message" file1' is a request to
+ # read the message from stdin and to operate on two files.
+ # Should test that there is an error because "my message"
+ # doesn't exist.
- # TODO: `cvs admin -t "my message" file1' is a request to
- # read the message from stdin and to operate on two files.
- # Should test that there is an error because "my message"
- # doesn't exist.
-
- if echo change from stdin | ${testcvs} admin -t -q file1
- then
- pass log2-9
- else
- fail log2-9
- fi
- dotest log2-10 "${testcvs} log -N file1" "
+ dotest log2-9 "echo change from stdin | ${testcvs} admin -t -q file1" ""
+ dotest log2-10 "${testcvs} log -N file1" "
RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
Working file: file1
head: 1\.1
@@ -12792,8 +13308,6 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
1
============================================================================="
- fi # end of tests skipped for remote
-
cd ..
rm ${TESTDIR}/descrip
rm -r first-dir
@@ -12801,6 +13315,49 @@ date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;
;;
+ logopt)
+ # Some tests of log.c's option parsing and such things.
+ mkdir 1; cd 1
+ dotest logopt-1 "${testcvs} -q co -l ." ''
+ mkdir first-dir
+ dotest logopt-2 "${testcvs} add first-dir" \
+"Directory ${TESTDIR}/cvsroot/first-dir added to the repository"
+ cd first-dir
+ echo hi >file1
+ dotest logopt-3 "${testcvs} add file1" \
+"${PROG} [a-z]*: scheduling file .file1. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+ dotest logopt-4 "${testcvs} -q ci -m add file1" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+done
+Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v <-- file1
+initial revision: 1\.1
+done"
+ cd ..
+
+ dotest logopt-5 "${testcvs} log -R -d 2038-01-01" \
+"${PROG} [a-z]*: Logging \.
+${PROG} [a-z]*: Logging first-dir
+${TESTDIR}/cvsroot/first-dir/file1,v"
+ dotest logopt-6 "${testcvs} log -d 2038-01-01 -R" \
+"${PROG} [a-z]*: Logging \.
+${PROG} [a-z]*: Logging first-dir
+${TESTDIR}/cvsroot/first-dir/file1,v"
+ dotest logopt-6a "${testcvs} log -Rd 2038-01-01" \
+"${PROG} [a-z]*: Logging \.
+${PROG} [a-z]*: Logging first-dir
+${TESTDIR}/cvsroot/first-dir/file1,v"
+ dotest logopt-7 "${testcvs} log -s Exp -R" \
+"${PROG} [a-z]*: Logging \.
+${PROG} [a-z]*: Logging first-dir
+${TESTDIR}/cvsroot/first-dir/file1,v"
+
+ cd ..
+ rm -r 1
+ rm -rf ${CVSROOT_DIRNAME}/first-dir
+ ;;
+
ann)
# Tests of "cvs annotate". See also:
# basica-10 A simple annotate test
@@ -13296,7 +13853,7 @@ add file1
# ISO8601 format. There are many, many, other variations
# specified by ISO8601 which we should be testing too.
- dotest rcs-3 "${testcvs} -q log -d 1996-12-11<" "
+ dotest rcs-3 "${testcvs} -q log -d '1996-12-11<'" "
RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
Working file: file1
head: 1\.3
@@ -13315,9 +13872,8 @@ delete second line; modify twelfth line
============================================================================="
# RFC822 format (as amended by RFC1123).
- if ${testcvs} -q log -d '<3 Apr 2000 00:00' >${TESTDIR}/rcs4.tmp
- then
- dotest rcs-4 "cat ${TESTDIR}/rcs4.tmp" "
+ dotest rcs-4 "${testcvs} -q log -d '<3 Apr 2000 00:00'" \
+"
RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
Working file: file1
head: 1\.3
@@ -13338,9 +13894,6 @@ revision 1\.1
date: 1996/11/24 15:56:05; author: kingdon; state: Exp;
add file1
============================================================================="
- else
- fail rcs-4
- fi
# Intended behavior for "cvs annotate" is that it displays the
# last two digits of the year. Make sure it does that rather
@@ -13545,47 +14098,22 @@ a1 1
next branch revision
@"
- if ${testcvs} -q update -p -D '1970-12-31 11:30 UT' file2 \
- >${TESTDIR}/rcs4.tmp
- then
- dotest rcs-9 "cat ${TESTDIR}/rcs4.tmp" "start revision"
- else
- fail rcs-9
- fi
+ dotest rcs-9 "${testcvs} -q update -p -D '1970-12-31 11:30 UT' file2" \
+"start revision"
- if ${testcvs} -q update -p -D '1970-12-31 12:30 UT' file2 \
- >${TESTDIR}/rcs4.tmp
- then
- dotest rcs-10 "cat ${TESTDIR}/rcs4.tmp" "mid revision"
- else
- fail rcs-10
- fi
+ dotest rcs-10 "${testcvs} -q update -p -D '1970-12-31 12:30 UT' file2" \
+"mid revision"
- if ${testcvs} -q update -p -D '1971-01-01 00:30 UT' file2 \
- >${TESTDIR}/rcs4.tmp
- then
- dotest rcs-11 "cat ${TESTDIR}/rcs4.tmp" "new year revision"
- else
- fail rcs-11
- fi
+ dotest rcs-11 "${testcvs} -q update -p -D '1971-01-01 00:30 UT' file2" \
+"new year revision"
# Same test as rcs-10, but with am/pm.
- if ${testcvs} -q update -p -D 'December 31, 1970 12:30pm UT' file2 \
- >${TESTDIR}/rcs4.tmp
- then
- dotest rcs-12 "cat ${TESTDIR}/rcs4.tmp" "mid revision"
- else
- fail rcs-12
- fi
+ dotest rcs-12 "${testcvs} -q update -p -D 'December 31, 1970 12:30pm UT' file2" \
+"mid revision"
# Same test as rcs-11, but with am/pm.
- if ${testcvs} -q update -p -D 'January 1, 1971 12:30am UT' file2 \
- >${TESTDIR}/rcs4.tmp
- then
- dotest rcs-13 "cat ${TESTDIR}/rcs4.tmp" "new year revision"
- else
- fail rcs-13
- fi
+ dotest rcs-13 "${testcvs} -q update -p -D 'January 1, 1971 12:30am UT' file2" \
+"new year revision"
# OK, now make sure cvs log doesn't have any trouble with the
# newphrases and such.
@@ -13631,9 +14159,49 @@ revision 1\.2\.6\.1
date: 1971/01/01 08:00:05; author: joe; state: Exp; lines: ${PLUS}1 -1
\*\*\* empty log message \*\*\*
============================================================================="
+ # Now test each date format for "cvs log -d".
+ # Earlier than 1971-01-01
+ dotest rcs-15 "${testcvs} -q log -d '<1971-01-01 00:00 GMT' file2 \
+ | grep revision" \
+"total revisions: 7; selected revisions: 3
+revision 1\.3
+revision 1\.2
+revision 1\.1"
+ # Later than 1971-01-01
+ dotest rcs-16 "${testcvs} -q log -d '1971-01-01 00:00 GMT<' file2 \
+ | grep revision" \
+"total revisions: 7; selected revisions: 4
+revision 1\.5
+revision 1\.4
+revision 1\.2\.6\.2
+revision 1\.2\.6\.1"
+ # Alternate syntaxes for later and earlier; multiple -d options
+ dotest rcs-17 "${testcvs} -q log -d '>1971-01-01 00:00 GMT' \
+ -d '1970-12-31 12:15 GMT>' file2 | grep revision" \
+"total revisions: 7; selected revisions: 5
+revision 1\.5
+revision 1\.4
+revision 1\.1
+revision 1\.2\.6\.2
+revision 1\.2\.6\.1"
+ # Range, and single date
+ dotest rcs-18 "${testcvs} -q log -d '1970-12-31 11:30 GMT' \
+ -d '1971-01-01 00:00:05 GMT<1971-01-01 01:00:01 GMT' \
+ file2 | grep revision" \
+"total revisions: 7; selected revisions: 2
+revision 1\.5
+revision 1\.1"
+ # Alternate range syntax; equality
+ dotest rcs-19 "${testcvs} -q log \
+ -d '1971-01-01 01:00:01 GMT>=1971-01-01 00:00:05 GMT' \
+ file2 | grep revision" \
+"total revisions: 7; selected revisions: 2
+revision 1\.5
+revision 1\.4"
+
cd ..
- rm -r first-dir ${TESTDIR}/rcs4.tmp
+ rm -r first-dir
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
@@ -13684,41 +14252,17 @@ EOF
cd first-dir
# 9 Sep 1999
- if ${testcvs} -q update -p -D '1999-09-09 11:30 UT' file1 \
- >${TESTDIR}/rcs4.tmp
- then
- dotest rcs2-2 "cat ${TESTDIR}/rcs4.tmp" \
+ dotest rcs2-2 "${testcvs} -q update -p -D '1999-09-09 11:30 UT' file1" \
"Tonight we're going to party like it's a certain year"
- else
- fail rcs2-2
- fi
# 1 Jan 2001.
- if ${testcvs} -q update -p -D '2001-01-01 11:30 UT' file1 \
- >${TESTDIR}/rcs4.tmp
- then
- dotest rcs2-3 "cat ${TESTDIR}/rcs4.tmp" \
+ dotest rcs2-3 "${testcvs} -q update -p -D '2001-01-01 11:30 UT' file1" \
"two year hiatus"
- else
- fail rcs2-3
- fi
# 29 Feb 2000
- if ${testcvs} -q update -p -D '2000-02-29 11:30 UT' file1 \
- >${TESTDIR}/rcs4.tmp
- then
- dotest rcs2-4 "cat ${TESTDIR}/rcs4.tmp" \
+ dotest rcs2-4 "${testcvs} -q update -p -D '2000-02-29 11:30 UT' file1" \
"2000 is also a good year for leaping"
- else
- fail rcs2-4
- fi
# 29 Feb 2003 is invalid
- if ${testcvs} -q update -p -D '2003-02-29 11:30 UT' file1 \
- >${TESTDIR}/rcs4.tmp 2>&1
- then
- fail rcs2-5
- else
- dotest rcs2-5 "cat ${TESTDIR}/rcs4.tmp" \
+ dotest_fail rcs2-5 "${testcvs} -q update -p -D '2003-02-29 11:30 UT' file1" \
"${PROG} \[[a-z]* aborted\]: Can't parse date/time: 2003-02-29 11:30 UT"
- fi
dotest rcs2-6 "${testcvs} -q update -p -D 2007-01-07 file1" \
"head revision"
@@ -13736,22 +14280,10 @@ EOF
# 31 May 1999), it seems to fail.
#
# Sigh.
- if ${testcvs} -q update -p -D '100 months' file1 \
- >${TESTDIR}/rcs4.tmp 2>&1
- then
- dotest rcs2-7 "cat ${TESTDIR}/rcs4.tmp" "head revision"
- else
- fail rcs2-7
- fi
- if ${testcvs} -q update -p -D '8 years' file1 \
- >${TESTDIR}/rcs4.tmp 2>&1
- then
- dotest rcs2-8 "cat ${TESTDIR}/rcs4.tmp" "head revision"
- else
- fail rcs2-8
- fi
-
- rm ${TESTDIR}/rcs4.tmp
+ dotest rcs2-7 "${testcvs} -q update -p -D '100 months' file1" \
+"head revision"
+ dotest rcs2-8 "${testcvs} -q update -p -D '8 years' file1" \
+"head revision"
cd ..
rm -r first-dir
@@ -13772,7 +14304,7 @@ EOF
# question one way or the other (it has a grammar but almost
# nothing about lexical analysis).
dotest_fail rcs3-1 "${testcvs} -q co first-dir" \
-"${PROG} \[[a-z]* aborted\]: unexpected end of file reading ${TESTDIR}/cvsroot/first-dir/file1,v"
+"${PROG} \[[a-z]* aborted\]: EOF while looking for value in RCS file ${TESTDIR}/cvsroot/first-dir/file1,v"
cat <<EOF >${CVSROOT_DIRNAME}/first-dir/file1,v
head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02
; author jeremiah ;state ; branches; next;desc @@1.1log@@text@head@
@@ -13793,25 +14325,15 @@ head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02
; author jeremiah ;state ; branches; next;desc @@1.1 log @@text @head@
EOF
dotest rcs3-4 "${testcvs} -q co first-dir" 'U first-dir/file1'
- if test "$remote" = no; then
- # Ouch, didn't expect this one. FIXCVS. Or maybe just remove
- # the feature, if this is a -s problem?
- dotest_fail rcs3-5 "${testcvs} log -s nostate first-dir/file1" \
-".*[Aa]ssertion.*failed${DOTSTAR}" ".*failed assertion${DOTSTAR}"
- else # remote
- # Is this a reaction to the lack of TopLevelAdmin or something?
- # Seems pretty strange to me. Seems vaguely similar to the
- # "no repository" message in errmsg2-16 although I'm leaving
- # it here in case there is a difference between "cvs add" and a
- # normal start_recursion command like "cvs log".
- dotest_fail rcs3-5 "${testcvs} log -s nostate first-dir/file1" \
-"${PROG} log: cannot open CVS/Entries for reading: No such file or directory
-${PROG} \[log aborted\]: no repository"
- cd first-dir
- dotest_fail rcs3-5a "${testcvs} log -s nostate file1" \
+
+ # Ouch, didn't expect this one. FIXCVS. Or maybe just remove
+ # the feature, if this is a -s problem?
+ dotest_fail rcs3-5 "${testcvs} log -s nostate first-dir/file1" \
"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}"
- cd ..
- fi # remote
+ cd first-dir
+ dotest_fail rcs3-5a "${testcvs} log -s nostate file1" \
+"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}"
+ cd ..
# See remote code above for rationale for cd.
cd first-dir
@@ -13819,7 +14341,7 @@ ${PROG} \[log aborted\]: no repository"
"${TESTDIR}/cvsroot/first-dir/file1,v"
# OK, now put an extraneous '\0' at the end.
- awk </dev/null 'BEGIN { printf "@%c", 10 }' | tr '@' '\000' \
+ ${AWK} </dev/null 'BEGIN { printf "@%c", 10 }' | ${TR} '@' '\000' \
>>${CVSROOT_DIRNAME}/first-dir/file1,v
dotest_fail rcs3-7 "${testcvs} log -s nostate file1" \
"${PROG} \[[a-z]* aborted\]: unexpected '.x0' reading revision number in RCS file ${TESTDIR}/cvsroot/first-dir/file1,v"
@@ -13882,6 +14404,7 @@ ${PROG} \[[a-z]* aborted\]: cannot stat ${TESTDIR}/locks: No such file or direct
cd ../../..
dotest lockfiles-8 "${testcvs} -q update" ""
+ dotest lockfiles-9 "${testcvs} -q co -l ." ""
cd CVSROOT
echo "# nobody here but us comments" >config
@@ -14099,9 +14622,9 @@ ${PROG} \[[a-z]* aborted\]: could not find desired version 1\.6 in ${TESTDIR}/cv
# database dirs in a workspace with later revisions than those in the
# recovered repository
cd repos-first-dir
-DATADIRS=\`find . -name CVS\`
+DATADIRS=\`find . -name CVS -print\`
cd ../first-dir
-find . -name CVS |xargs rm -rf
+find . -name CVS -print | xargs rm -rf
for file in \${DATADIRS}; do
cp -r ../repos-first-dir/\${file} \${file}
done" >fixit
@@ -14204,42 +14727,79 @@ done"
# slowly and carefully.
cat >${CVSROOT_DIRNAME}/CVSROOT/history <<EOF
O3395c677|anonymous|<remote>/*0|ccvs||ccvs
+O3396c677|anonymous|<remote>/src|ccvs||src
+O3397c677|kingdon|<remote>/*0|ccvs||ccvs
M339cafae|nk|<remote>|ccvs/src|1.229|sanity.sh
+M339cafff|anonymous|<remote>|ccvs/src|1.23|Makefile
M339dc339|kingdon|~/work/*0|ccvs/src|1.231|sanity.sh
W33a6eada|anonymous|<remote>*4|ccvs/emx||Makefile.in
C3b235f50|kingdon|<remote>|ccvs/emx|1.3|README
M3b23af50|kingdon|~/work/*0|ccvs/doc|1.281|cvs.texinfo
EOF
dotest history-1 "${testcvs} history -e -a" \
-"O 06/04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= <remote>/\*
-W 06/17 19:51 ${PLUS}0000 anonymous Makefile\.in ccvs/emx == <remote>/emx
-M 06/10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src
-C 06/10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote>
-M 06/10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc
-M 06/10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>"
- if ${testcvs} history -e -a -D '10 Jun 1997 13:00 UT' \
- >${TESTDIR}/output.tmp
- then
- dotest history-2 "cat ${TESTDIR}/output.tmp" \
-"W 06/17 19:51 ${PLUS}0000 anonymous Makefile\.in ccvs/emx == <remote>/emx
-M 06/10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src
-C 06/10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote>
-M 06/10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc"
- else
- fail history-2
- fi
- if ${testcvs} history -e -a -D '10 Jun 2001 13:00 UT' \
- >${TESTDIR}/output.tmp
- then
- # For reasons that are completely unclear to me, the number
- # of spaces betwen "kingdon" and "1.281" is different than
- # for the other tests.
- dotest history-3 "cat ${TESTDIR}/output.tmp" \
-"M 06/10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc"
- else
- fail history-3
- fi
- rm ${TESTDIR}/output.tmp
+"O 1997-06-04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= <remote>/\*
+O 1997-06-05 14:00 ${PLUS}0000 anonymous ccvs =src= <remote>/\*
+M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == <remote>
+W 1997-06-17 19:51 ${PLUS}0000 anonymous Makefile\.in ccvs/emx == <remote>/emx
+O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= <remote>/\*
+M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src
+C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote>
+M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc
+M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>"
+
+ dotest history-2 "${testcvs} history -e -a -D '10 Jun 1997 13:00 UT'" \
+"W 1997-06-17 19:51 ${PLUS}0000 anonymous Makefile\.in ccvs/emx == <remote>/emx
+M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src
+C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote>
+M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc"
+
+ dotest history-3 "${testcvs} history -e -a -D '10 Jun 2001 13:00 UT'" \
+"M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc"
+
+ dotest history-4 "${testcvs} history -ac sanity.sh" \
+"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src
+M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>"
+
+ dotest history-5 "${testcvs} history -a -xCGUWAMR README sanity.sh" \
+"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src
+C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote>
+M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>"
+
+ dotest history-6 "${testcvs} history -xCGUWAMR -a -f README -f sanity.sh" \
+"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src
+C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote>
+M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>"
+
+ dotest history-7 "${testcvs} history -xCGUWAMR -a -f sanity.sh README" \
+"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src
+C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == <remote>
+M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == <remote>"
+
+ dotest history-8 "${testcvs} history -ca -D '1970-01-01 00:00 UT'" \
+"M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity.sh ccvs/src == <remote>
+M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == <remote>
+M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity.sh ccvs/src == ~/work/ccvs/src
+M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs.texinfo ccvs/doc == ~/work/ccvs/doc"
+
+ dotest history-9 "${testcvs} history -acl" \
+"M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs.texinfo ccvs/doc == ~/work/ccvs/doc
+M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == <remote>
+M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity.sh ccvs/src == ~/work/ccvs/src"
+
+ dotest history-10 "${testcvs} history -lca -D '1970-01-01 00:00 UT'" \
+"M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs.texinfo ccvs/doc == ~/work/ccvs/doc
+M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == <remote>
+M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity.sh ccvs/src == ~/work/ccvs/src"
+
+ dotest history-11 "${testcvs} history -aw" \
+"O 1997-06-04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= <remote>/\*
+O 1997-06-05 14:00 ${PLUS}0000 anonymous ccvs =src= <remote>/\*
+O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= <remote>/\*"
+
+ dotest history-12 "${testcvs} history -aw -D'1970-01-01 00:00 UT'" \
+"O 1997-06-04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= <remote>/\*
+O 1997-06-05 14:00 ${PLUS}0000 anonymous ccvs =src= <remote>/\*
+O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= <remote>/\*"
;;
big)
@@ -14481,17 +15041,17 @@ done"
# the attic (may that one can remain a fatal error, seems less
# useful for access control).
mkdir 1; cd 1
- dotest modes-1 "${testcvs} -q co -l ." ''
+ dotest modes3-1 "${testcvs} -q co -l ." ''
mkdir first-dir second-dir
- dotest modes-2 "${testcvs} add first-dir second-dir" \
+ dotest modes3-2 "${testcvs} add first-dir second-dir" \
"Directory ${TESTDIR}/cvsroot/first-dir added to the repository
Directory ${TESTDIR}/cvsroot/second-dir added to the repository"
touch first-dir/aa second-dir/ab
- dotest modes-3 "${testcvs} add first-dir/aa second-dir/ab" \
+ dotest modes3-3 "${testcvs} add first-dir/aa second-dir/ab" \
"${PROG} [a-z]*: scheduling file .first-dir/aa. for addition
${PROG} [a-z]*: scheduling file .second-dir/ab. for addition
${PROG} [a-z]*: use .${PROG} commit. to add these files permanently"
- dotest modes-4 "${testcvs} -q ci -m add" \
+ dotest modes3-4 "${testcvs} -q ci -m add" \
"RCS file: ${TESTDIR}/cvsroot/first-dir/aa,v
done
Checking in first-dir/aa;
@@ -14505,7 +15065,7 @@ ${TESTDIR}/cvsroot/second-dir/ab,v <-- ab
initial revision: 1\.1
done"
chmod a= ${TESTDIR}/cvsroot/first-dir
- dotest modes-5 "${testcvs} update" \
+ dotest modes3-5 "${testcvs} update" \
"${PROG} [a-z]*: Updating \.
${PROG} [a-z]*: Updating first-dir
${PROG} [a-z]*: cannot open directory ${TESTDIR}/cvsroot/first-dir: Permission denied
@@ -14517,7 +15077,7 @@ ${PROG} [a-z]*: Updating second-dir"
# won't have it in their working directory. But the next
# one is more of a problem if it is fatal.
rm -r first-dir
- dotest modes-6 "${testcvs} update -dP" \
+ dotest modes3-6 "${testcvs} update -dP" \
"${PROG} [a-z]*: Updating .
${PROG} [a-z]*: Updating CVSROOT
U ${DOTSTAR}
@@ -15470,9 +16030,9 @@ xx"
"${PROG} [a-z]*: scheduling file .file1. for addition
${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
- awk 'BEGIN { printf "%c%c%c%sRevision: 1.1 $@%c%c", \
+ ${AWK} 'BEGIN { printf "%c%c%c%sRevision: 1.1 $@%c%c", \
2, 10, 137, "$", 13, 10 }' \
- </dev/null | tr '@' '\000' >../binfile.dat
+ </dev/null | ${TR} '@' '\000' >../binfile.dat
cp ../binfile.dat .
dotest keyword2-5 "${testcvs} add -kb binfile.dat" \
"${PROG} [a-z]*: scheduling file .binfile\.dat. for addition
@@ -15577,8 +16137,8 @@ done"
T file1"
dotest keyword2-18 "${testcvs} -q update -r branch2" ''
- awk 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
- </dev/null | tr '@' '\000' >>binfile.dat
+ ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \
+ </dev/null | ${TR} '@' '\000' >>binfile.dat
dotest keyword2-19 "${testcvs} -q ci -m badbadbad" \
"Checking in binfile\.dat;
${TESTDIR}/cvsroot/first-dir/binfile\.dat,v <-- binfile\.dat
@@ -15851,51 +16411,16 @@ new revision: 1\.1\.4\.2; previous revision: 1\.1\.4\.1
done"
cd ../..
mkdir 2; cd
- if ${testcvs} -q export -r br2 -D'1 minute ago' first-dir \
- >${TESTDIR}/tagdate.tmp 2>&1; then
- if ${EXPR} "`cat ${TESTDIR}/tagdate.tmp`" : \
-"[UP] first-dir/file1" >/dev/null; then
- pass tagdate-14
- else
- echo "** expected: " >>${LOGFILE}
- echo "[UP] first-dir/file1" >>${LOGFILE}
- echo "** got: " >>${LOGFILE}
- cat ${TESTDIR}/tagdate.tmp >>${LOGFILE}
- fail tagdate-14
- fi
- else
- echo "Bad exit status" >>${LOGFILE}
- fail tagdate-14
- fi
-
- if ${EXPR} "`cat first-dir/file1`" : "br2-1" >/dev/null; then
- pass tagdate-15
- else
- fail tagdate-15
- fi
+ dotest tagdate-14 "${testcvs} -q export -r br2 -D'1 minute ago' first-dir" \
+"[UP] first-dir/file1"
+ dotest tagdate-15 "cat first-dir/file1" "br2-1"
# Now for annotate
cd ../1/first-dir
- if ${testcvs} annotate -rbr2 -D'1 minute ago' \
- >${TESTDIR}/tagdate.tmp 2>&1; then
- if ${EXPR} "`cat ${TESTDIR}/tagdate.tmp`" : \
+ dotest tagdate-16 "${testcvs} annotate -rbr2 -D'1 minute ago'" \
"Annotations for file1
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1\.4\.1 (${username} *[0-9a-zA-Z-]*): br2-1" >/dev/null; then
- pass tagdate-16
- else
- echo "** expected: " >>${LOGFILE}
- echo "Annotations for file1
-\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-1\.1\.4\.1 (${username} *[0-9a-zA-Z-]*): br2-1" >>${LOGFILE}
- echo "** got: " >>${LOGFILE}
- cat ${TESTDIR}/tagdate.tmp >>${LOGFILE}
- fail tagdate-16
- fi
- else
- echo "Bad exit status" >>${LOGFILE}
- fail tagdate-16
- fi
+1\.1\.4\.1 (${username} *[0-9a-zA-Z-]*): br2-1"
dotest tagdate-17 "${testcvs} annotate -rbr2 -Dnow" \
"Annotations for file1
@@ -15908,7 +16433,6 @@ done"
fi
cd ../..
- rm ${TESTDIR}/tagdate.tmp
rm -r 1 2
rm -rf ${CVSROOT_DIRNAME}/first-dir
;;
@@ -16452,16 +16976,27 @@ access list:
keyword substitution: kv
total revisions: 2
============================================================================="
- # Put the access list back, to avoid special cases later.
- dotest admin-19a-fix "${testcvs} -q admin -eauth3 file1" \
+ fi # end of tests skipped for remote
+
+ # Now test that plain -e works right.
+ dotest admin-19a-2 "${testcvs} -q admin -e file1" \
"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
done"
- fi # end of tests skipped for remote
+ dotest admin-19a-3 "${testcvs} -q log -h -N file1" "
+RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+Working file: file1
+head: 1\.1
+branch:
+locks: strict
+access list:
+keyword substitution: kv
+total revisions: 2
+============================================================================="
- # Now test that plain -e is at least parsed right. CVS 1.10
- # would wrongly treat "-e file1" as "-efile1".
- dotest_fail admin-19a-2 "${testcvs} -q admin -e file1" \
-"${PROG} \[[a-z]* aborted\]: removing entire access list not yet implemented"
+ # Put the access list back, to avoid special cases later.
+ dotest admin-19a-4 "${testcvs} -q admin -afoo,auth2 file1" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
+done"
# Add another revision to file2, so we can delete one.
echo 'add a line' >> file2
@@ -17020,13 +17555,13 @@ add
cat >${TESTDIR}/lockme <<EOF
#!${TESTSHELL}
-line=\`grep <\$1/\$2,v 'locks ${username}:1\.[0-9];'\`
+line=\`grep <\$1/\$2,v 'locks ${author}:1\.[0-9];'\`
if test -z "\$line"; then
# It isn't locked
exit 0
else
- user=\`echo \$line | sed -e 's/locks \\(${username}\\):[0-9.]*;.*/\\1/'\`
- version=\`echo \$line | sed -e 's/locks ${username}:\\([0-9.]*\\);.*/\\1/'\`
+ user=\`echo \$line | sed -e 's/locks \\(${author}\\):[0-9.]*;.*/\\1/'\`
+ version=\`echo \$line | sed -e 's/locks ${author}:\\([0-9.]*\\);.*/\\1/'\`
echo "\$user has file a-lock locked for version \$version"
exit 1
fi
@@ -19479,7 +20014,7 @@ done"
# something which doesn't make sense.
dotest_fail multiroot3-10 \
"${testcvs} -q -d ${CVSROOT1} diff dir1/file1 dir2/file2" \
-"${PROG} [a-z]*: failed to create lock directory in repository .${TESTDIR}/root1/dir2': No such file or directory
+"${PROG} [a-z]*: failed to create lock directory for .${TESTDIR}/root1/dir2' (${TESTDIR}/root1/dir2/#cvs.lock): No such file or directory
${PROG} [a-z]*: failed to obtain dir lock in repository .${TESTDIR}/root1/dir2'
${PROG} \[[a-z]* aborted\]: read lock failed - giving up"
else
@@ -19500,7 +20035,37 @@ ${PROG} \[[a-z]* aborted\]: read lock failed - giving up"
# This one is supposed to work.
dotest multiroot3-11 "${testcvs} -q diff dir1/file1 dir2/file2" ""
- cd ..
+ # make sure we can't access across repositories
+ # FIXCVS: we probably shouldn't even create the local directories
+ # in this case, but we do, so deal with it.
+ mkdir 1a
+ cd 1a
+ dotest_fail multiroot3-12 \
+"${testcvs} -d ${CVSROOT1} -q co ../root2/dir2" \
+"${PROG} [a-z]*: in directory \.\./root2/dir2:
+${PROG} [a-z]*: .\.\..-relative repositories are not supported.
+${PROG} \[[a-z]* aborted\]: illegal source repository"
+ rm -rf ../root2
+ dotest_fail multiroot3-13 \
+"${testcvs} -d ${CVSROOT2} -q co ../root1/dir1" \
+"${PROG} [a-z]*: in directory \.\./root1/dir1:
+${PROG} [a-z]*: .\.\..-relative repositories are not supported.
+${PROG} \[[a-z]* aborted\]: illegal source repository"
+ rm -rf ../root1
+ dotest_fail multiroot3-14 \
+"${testcvs} -d ${CVSROOT1} -q co ./../root2/dir2" \
+"${PROG} [a-z]*: in directory \./\.\./root2/dir2:
+${PROG} [a-z]*: .\.\..-relative repositories are not supported.
+${PROG} \[[a-z]* aborted\]: illegal source repository"
+ rm -rf ../root2
+ dotest_fail multiroot3-15 \
+"${testcvs} -d ${CVSROOT2} -q co ./../root1/dir1" \
+"${PROG} [a-z]*: in directory \./\.\./root1/dir1:
+${PROG} [a-z]*: .\.\..-relative repositories are not supported.
+${PROG} \[[a-z]* aborted\]: illegal source repository"
+ rm -rf ../root1
+
+ cd ../..
if test "$keep" = yes; then
echo Keeping ${TESTDIR} and exiting due to --keep
@@ -19733,7 +20298,7 @@ No such file or directory"
pserver)
# Test basic pserver functionality.
if test "$remote" = yes; then
- # First set SystemAuth=no. Not really necessary, I don't
+ # First set SystemAuth=no. Not really necessary, I don't
# think, but somehow it seems like the clean thing for
# the testsuite.
mkdir 1; cd 1
@@ -19746,22 +20311,27 @@ ${TESTDIR}/cvsroot/CVSROOT/config,v <-- config
new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
done
${PROG} [a-z]*: Rebuilding administrative file database"
- echo "testme:q6WV9d2t848B2:`id -un`" \
- >${CVSROOT_DIRNAME}/CVSROOT/passwd
- ${testcvs} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+ cat >${CVSROOT_DIRNAME}/CVSROOT/passwd <<EOF
+testme:q6WV9d2t848B2:$username
+anonymous::$username
+$username:
+willfail: :whocares
+EOF
+ dotest_fail pserver-3 "${testcvs} pserver" \
+"error 0 Server configuration missing --allow-root in inetd.conf" <<EOF
BEGIN AUTH REQUEST
${CVSROOT_DIRNAME}
testme
Ay::'d
END AUTH REQUEST
EOF
- dotest pserver-3 "cat ${TESTDIR}/pserver.tmp" \
-"error 0 Server configuration missing --allow-root in inetd.conf"
# Sending the Root and noop before waiting for the
# "I LOVE YOU" is bogus, but hopefully we can get
# away with it.
- ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+ dotest pserver-4 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU
+ok" <<EOF
BEGIN AUTH REQUEST
${CVSROOT_DIRNAME}
testme
@@ -19770,11 +20340,11 @@ END AUTH REQUEST
Root ${CVSROOT_DIRNAME}
noop
EOF
- dotest pserver-4 "cat ${TESTDIR}/pserver.tmp" \
-"${DOTSTAR} LOVE YOU
-ok"
- ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+ dotest pserver-5 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU
+E Protocol error: Root says \"${TESTDIR}/1\" but pserver says \"${CVSROOT_DIRNAME}\"
+error " <<EOF
BEGIN AUTH REQUEST
${CVSROOT_DIRNAME}
testme
@@ -19783,40 +20353,85 @@ END AUTH REQUEST
Root ${TESTDIR}/1
noop
EOF
- dotest pserver-5 "cat ${TESTDIR}/pserver.tmp" \
-"${DOTSTAR} LOVE YOU
-E Protocol error: Root says \"${TESTDIR}/1\" but pserver says \"${CVSROOT_DIRNAME}\"
-error "
- ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+ dotest_fail pserver-6 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"I HATE YOU" <<EOF
BEGIN AUTH REQUEST
${CVSROOT_DIRNAME}
testme
Ay::'d^b?hd
END AUTH REQUEST
EOF
- dotest pserver-6 "cat ${TESTDIR}/pserver.tmp" \
-"I HATE YOU"
- ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+ dotest_fail pserver-7 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"I HATE YOU" <<EOF
BEGIN VERIFICATION REQUEST
${CVSROOT_DIRNAME}
testme
Ay::'d^b?hd
END VERIFICATION REQUEST
EOF
- dotest pserver-7 "cat ${TESTDIR}/pserver.tmp" \
-"I HATE YOU"
- ${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver >${TESTDIR}/pserver.tmp 2>&1 <<EOF
+ dotest pserver-8 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU" <<EOF
BEGIN VERIFICATION REQUEST
${CVSROOT_DIRNAME}
testme
Ay::'d
END VERIFICATION REQUEST
EOF
- dotest pserver-8 "cat ${TESTDIR}/pserver.tmp" \
-"${DOTSTAR} LOVE YOU"
+
+# Tests pserver-9 through pserver-13 are about empty passwords
+
+ # Test empty password (both sides) for aliased user
+ dotest pserver-9 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+anonymous
+A
+END AUTH REQUEST
+EOF
+
+ # Test empty password (server side only) for aliased user
+ dotest pserver-10 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+anonymous
+Aanythingwouldworkhereittrulydoesnotmatter
+END AUTH REQUEST
+EOF
+
+ # Test empty (both sides) password for non-aliased user
+ dotest pserver-11 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+${username}
+A
+END AUTH REQUEST
+EOF
+
+ # Test empty (server side only) password for non-aliased user
+ dotest pserver-12 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} LOVE YOU" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+${username}
+Anypasswordwouldworkwhynotthisonethen
+END AUTH REQUEST
+EOF
+
+ # Test failure of whitespace password
+ dotest_fail pserver-13 "${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \
+"${DOTSTAR} HATE YOU" <<EOF
+BEGIN AUTH REQUEST
+${CVSROOT_DIRNAME}
+willfail
+Amquiteunabletocomeupwithinterestingpasswordsanymore
+END AUTH REQUEST
+EOF
# Clean up.
echo "# comments only" >config
@@ -19835,38 +20450,28 @@ ${PROG} [a-z]*: Rebuilding administrative file database"
server)
# Some tests of the server (independent of the client).
if test "$remote" = yes; then
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-1 "${testcvs} server" \
+"E Protocol error: Root request missing
+error " <<EOF
Directory bogus
mumble/bar
update
EOF
- dotest server-1 "cat ${TESTDIR}/server.tmp" \
-"E Protocol error: Root request missing
-error "
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-1
- fi
# Could also test for relative pathnames here (so that crerepos-6a
# and crerepos-6b can use :fork:).
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-2 "${testcvs} server" "ok" <<EOF
Set OTHER=variable
Set MYENV=env-value
init ${TESTDIR}/crerepos
EOF
- dotest server-2 "cat ${TESTDIR}/server.tmp" "ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-2
- fi
dotest server-3 "test -d ${TESTDIR}/crerepos/CVSROOT" ""
# Now some tests of gzip-file-contents (used by jCVS).
- awk 'BEGIN { \
+ ${AWK} 'BEGIN { \
printf "%c%c%c%c%c%c.6%c%c+I-.%c%c%c%c5%c;%c%c%c%c", \
31, 139, 8, 64, 5, 7, 64, 3, 225, 2, 64, 198, 185, 5, 64, 64, 64}' \
- </dev/null | tr '\100' '\000' >gzipped.dat
+ </dev/null | ${TR} '\100' '\000' >gzipped.dat
# Note that the CVS client sends "-b 1.1.1", and this
# test doesn't. But the server also defaults to that.
cat <<EOF >session.dat
@@ -19887,21 +20492,20 @@ z25
EOF
cat gzipped.dat >>session.dat
echo import >>session.dat
- if ${testcvs} server >${TESTDIR}/server.tmp <session.dat; then
- dotest server-4 "cat ${TESTDIR}/server.tmp" "M N dir1/file1
+ dotest server-4 "${testcvs} server" \
+"M N dir1/file1
M
M No conflicts created by this import
M
-ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-4
- fi
+ok" <session.dat
dotest server-5 \
"${testcvs} -q -d ${TESTDIR}/crerepos co -p dir1/file1" "test"
# OK, here are some notify tests.
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-6 "${testcvs} server" \
+"Notified \./
+${TESTDIR}/crerepos/dir1/file1
+ok" <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
@@ -19909,18 +20513,16 @@ Notify file1
E Fri May 7 13:21:09 1999 GMT myhost some-work-dir EUC
noop
EOF
- dotest server-6 "cat ${TESTDIR}/server.tmp" \
-"Notified \./
-${TESTDIR}/crerepos/dir1/file1
-ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-6
- fi
# Sending the second "noop" before waiting for the output
# from the first is bogus but hopefully we can get away
# with it.
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-7 "${testcvs} server" \
+"Notified \./
+${TESTDIR}/crerepos/dir1/file1
+ok
+Notified \./
+${TESTDIR}/crerepos/dir1/file1
+ok" <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
@@ -19931,20 +20533,14 @@ Notify file1
E The 57th day of Discord in the YOLD 3165 myhost some-work-dir EUC
noop
EOF
- dotest server-7 "cat ${TESTDIR}/server.tmp" \
-"Notified \./
-${TESTDIR}/crerepos/dir1/file1
-ok
-Notified \./
-${TESTDIR}/crerepos/dir1/file1
-ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-7
- fi
# OK, now test a few error conditions.
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ # FIXCVS: should give "error" and no "Notified", like server-9
+ dotest server-8 "${testcvs} server" \
+"E ${PROG} server: invalid character in editor value
+Notified \./
+${TESTDIR}/crerepos/dir1/file1
+ok" <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
@@ -19952,18 +20548,10 @@ Notify file1
E Setting Orange, the 52th day of Discord in the YOLD 3165 myhost some-work-dir EUC
noop
EOF
- # FIXCVS: should give "error" and no "Notified", like server-9
- dotest server-8 "cat ${TESTDIR}/server.tmp" \
-"E ${PROG} server: invalid character in editor value
-Notified \./
-${TESTDIR}/crerepos/dir1/file1
-ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-8
- fi
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-9 "${testcvs} server" \
+"E Protocol error; misformed Notify request
+error " <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
@@ -19971,64 +20559,43 @@ Notify file1
E Setting Orange+57th day of Discord myhost some-work-dir EUC
noop
EOF
- dotest server-9 "cat ${TESTDIR}/server.tmp" \
-"E Protocol error; misformed Notify request
-error "
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-9
- fi
# First demonstrate an interesting quirk in the protocol.
# The "watchers" request selects the files to operate based
# on files which exist in the working directory. So if we
# don't send "Entry" or the like, it won't do anything.
# Wants to be documented in cvsclient.texi...
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-10 "${testcvs} server" "ok" <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
watchers
EOF
- dotest server-10 "cat ${TESTDIR}/server.tmp" \
-"ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-10
- fi
-
# See if "watchers" and "editors" display the right thing.
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-11 "${testcvs} server" \
+"M file1 ${username} tedit tunedit tcommit
+ok" <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
Entry /file1/1.1////
watchers
EOF
- dotest server-11 "cat ${TESTDIR}/server.tmp" \
-"M file1 ${username} tedit tunedit tcommit
-ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-11
- fi
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-12 "${testcvs} server" \
+"M file1 ${username} The 57th day of Discord in the YOLD 3165 myhost some-work-dir
+ok" <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
Entry /file1/1.1////
editors
EOF
- dotest server-12 "cat ${TESTDIR}/server.tmp" \
-"M file1 ${username} The 57th day of Discord in the YOLD 3165 myhost some-work-dir
-ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-12
- fi
# Now do an unedit.
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-13 "${testcvs} server" \
+"Notified \./
+${TESTDIR}/crerepos/dir1/file1
+ok" <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
@@ -20036,40 +20603,20 @@ Notify file1
U 7 May 1999 15:00 GMT myhost some-work-dir EUC
noop
EOF
- dotest server-13 "cat ${TESTDIR}/server.tmp" \
-"Notified \./
-${TESTDIR}/crerepos/dir1/file1
-ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-13
- fi
# Now try "watchers" and "editors" again.
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-14 "${testcvs} server" "ok" <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
watchers
EOF
- dotest server-14 "cat ${TESTDIR}/server.tmp" \
-"ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-14
- fi
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server-15 "${testcvs} server" "ok" <<EOF
Root ${TESTDIR}/crerepos
Directory .
${TESTDIR}/crerepos/dir1
editors
EOF
- dotest server-15 "cat ${TESTDIR}/server.tmp" \
-"ok"
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server-15
- fi
if test "$keep" = yes; then
echo Keeping ${TESTDIR} and exiting due to --keep
@@ -20078,7 +20625,6 @@ EOF
rm -rf ${TESTDIR}/crerepos
rm gzipped.dat session.dat
- rm ${TESTDIR}/server.tmp
fi # skip the whole thing for local
;;
@@ -20086,66 +20632,46 @@ EOF
# More server tests, in particular testing that various
# possible security holes are plugged.
if test "$remote" = yes; then
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server2-1 "${testcvs} server" \
+"E protocol error: directory '${TESTDIR}/cvsroot/\.\./dir1' not within root '${TESTDIR}/cvsroot'
+error " <<EOF
Root ${TESTDIR}/cvsroot
Directory .
${TESTDIR}/cvsroot/../dir1
noop
EOF
- dotest server2-1 "cat ${TESTDIR}/server.tmp" \
-"E protocol error: directory '${TESTDIR}/cvsroot/\.\./dir1' not within root '${TESTDIR}/cvsroot'
-error "
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server2-1
- fi
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server2-2 "${testcvs} server" \
+"E protocol error: directory '${TESTDIR}/cvsrootdir1' not within root '${TESTDIR}/cvsroot'
+error " <<EOF
Root ${TESTDIR}/cvsroot
Directory .
${TESTDIR}/cvsrootdir1
noop
EOF
- dotest server2-2 "cat ${TESTDIR}/server.tmp" \
-"E protocol error: directory '${TESTDIR}/cvsrootdir1' not within root '${TESTDIR}/cvsroot'
-error "
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server2-2
- fi
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest 2-3 "${testcvs} server" \
+"E protocol error: directory '${TESTDIR}' not within root '${TESTDIR}/cvsroot'
+error " <<EOF
Root ${TESTDIR}/cvsroot
Directory .
${TESTDIR}
noop
EOF
- dotest server2-3 "cat ${TESTDIR}/server.tmp" \
-"E protocol error: directory '${TESTDIR}' not within root '${TESTDIR}/cvsroot'
-error "
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server2-3
- fi
# OK, now a few tests for the rule that one cannot pass a
# filename containing a slash to Modified, Is-modified,
# Notify, Questionable, or Unchanged. For completeness
# we'd try them all. For lazyness/conciseness we don't.
- if ${testcvs} server >${TESTDIR}/server.tmp <<EOF; then
+ dotest server2-4 "${testcvs} server" \
+"E protocol error: directory 'foo/bar' not within current directory
+error " <<EOF
Root ${TESTDIR}/cvsroot
Directory .
${TESTDIR}/cvsroot
Unchanged foo/bar
noop
EOF
- dotest server2-4 "cat ${TESTDIR}/server.tmp" \
-"E protocol error: directory 'foo/bar' not within current directory
-error "
- else
- echo "exit status was $?" >>${LOGFILE}
- fail server2-4
- fi
fi
;;
@@ -20175,7 +20701,7 @@ EOF
CVS_SERVER=${TESTDIR}/serveme; export CVS_SERVER
mkdir 1; cd 1
dotest_fail client-1 "${testcvs} -q co first-dir" \
-"${PROG} \[checkout aborted\]: This server does not support the global -q option\."
+"${PROG} \[checkout aborted\]: This server does not support the global -q option${DOTSTAR}"
dotest client-2 "${testcvs} co first-dir" "special message"
cat >${TESTDIR}/serveme <<EOF
@@ -20197,8 +20723,10 @@ cat >/dev/null
EOF
cd first-dir
mkdir ${TESTDIR}/bogus
+ # The ${DOTSTAR} is to match a potential "broken pipe" if the
+ # client exits before the server script sends everything
dotest_fail client-3 "${testcvs} update" "merge-it
-${PROG} \[update aborted\]: protocol error: Copy-file tried to specify directory"
+${PROG} \[update aborted\]: protocol error: Copy-file tried to specify director${DOTSTAR}"
cat >${TESTDIR}/serveme <<EOF
#!${TESTSHELL}
echo "Valid-requests Root Valid-responses valid-requests Directory Entry Modified Unchanged Argument Argumentx ci co update"
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c
index 669cad7..e1af5e4 100644
--- a/contrib/cvs/src/server.c
+++ b/contrib/cvs/src/server.c
@@ -183,6 +183,7 @@ static int fd_buffer_input PROTO((void *, char *, int, int, int *));
static int fd_buffer_output PROTO((void *, const char *, int, int *));
static int fd_buffer_flush PROTO((void *));
static int fd_buffer_block PROTO((void *, int));
+static int fd_buffer_shutdown PROTO((void *));
/* Initialize a buffer built on a file descriptor. FD is the file
descriptor. INPUT is nonzero if this is for input, zero if this is
@@ -204,7 +205,7 @@ fd_buffer_initialize (fd, input, memory)
input ? NULL : fd_buffer_output,
input ? NULL : fd_buffer_flush,
fd_buffer_block,
- (int (*) PROTO((void *))) NULL,
+ fd_buffer_shutdown,
memory,
n);
}
@@ -341,6 +342,16 @@ fd_buffer_block (closure, block)
return 0;
}
+/* The buffer shutdown function for a buffer built on a file descriptor. */
+
+static int
+fd_buffer_shutdown (closure)
+ void *closure;
+{
+ free (closure);
+ return 0;
+}
+
/* Populate all of the directories between BASE_DIR and its relative
subdirectory DIR with CVSADM directories. Return 0 for success or
errno value. */
@@ -738,8 +749,6 @@ serve_root (arg)
{
char *env;
char *path;
- int save_errno;
- char *arg_dup;
if (error_pending()) return;
@@ -781,14 +790,7 @@ E Protocol error: Root says \"%s\" but pserver says \"%s\"",
}
}
#endif
- arg_dup = malloc (strlen (arg) + 1);
- if (arg_dup == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcpy (arg_dup, arg);
- set_local_cvsroot (arg_dup);
+ set_local_cvsroot (arg);
/* For pserver, this will already have happened, and the call will do
nothing. But for rsh, we need to do it now. */
@@ -796,7 +798,6 @@ E Protocol error: Root says \"%s\" but pserver says \"%s\"",
path = malloc (strlen (CVSroot_directory)
+ sizeof (CVSROOTADM)
- + sizeof (CVSROOTADM_HISTORY)
+ 10);
if (path == NULL)
{
@@ -806,23 +807,11 @@ E Protocol error: Root says \"%s\" but pserver says \"%s\"",
(void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
if (!isaccessible (path, R_OK | X_OK))
{
- save_errno = errno;
- pending_error_text = malloc (80 + strlen (path));
- if (pending_error_text != NULL)
+ int save_errno = errno;
+ if (alloc_pending (80 + strlen (path)))
sprintf (pending_error_text, "E Cannot access %s", path);
pending_error = save_errno;
}
- (void) strcat (path, "/");
- (void) strcat (path, CVSROOTADM_HISTORY);
- if (isfile (path) && !isaccessible (path, R_OK | W_OK))
- {
- save_errno = errno;
- pending_error_text = malloc (80 + strlen (path));
- if (pending_error_text != NULL)
- sprintf (pending_error_text, "E \
-Sorry, you don't have read/write access to the history file %s", path);
- pending_error = save_errno;
- }
free (path);
#ifdef HAVE_PUTENV
@@ -1036,9 +1025,9 @@ dirswitch (dir, repos)
if (status != 0
&& status != EEXIST)
{
- pending_error = status;
if (alloc_pending (80 + strlen (dir_name)))
sprintf (pending_error_text, "E cannot mkdir %s", dir_name);
+ pending_error = status;
return;
}
@@ -1051,17 +1040,18 @@ dirswitch (dir, repos)
status = create_adm_p (server_temp_dir, dir);
if (status != 0)
{
- pending_error = status;
if (alloc_pending (80 + strlen (dir_name)))
sprintf (pending_error_text, "E cannot create_adm_p %s", dir_name);
+ pending_error = status;
return;
}
if ( CVS_CHDIR (dir_name) < 0)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (dir_name)))
sprintf (pending_error_text, "E cannot change to %s", dir_name);
+ pending_error = save_errno;
return;
}
/*
@@ -1070,10 +1060,14 @@ dirswitch (dir, repos)
*/
if ((CVS_MKDIR (CVSADM, 0777) < 0) && (errno != EEXIST))
{
- pending_error = errno;
+ int save_errno = errno;
+ if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM)))
+ sprintf (pending_error_text,
+ "E cannot mkdir %s/%s", dir_name, CVSADM);
+ pending_error = save_errno;
return;
}
-
+
/* The following will overwrite the contents of CVSADM_REP. This
is the correct behavior -- mkdir_p may have written a
placeholder value to this file and we need to insert the
@@ -1082,12 +1076,20 @@ dirswitch (dir, repos)
f = CVS_FOPEN (CVSADM_REP, "w");
if (f == NULL)
{
- pending_error = errno;
+ int save_errno = errno;
+ if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
+ sprintf (pending_error_text,
+ "E cannot open %s/%s", dir_name, CVSADM_REP);
+ pending_error = save_errno;
return;
}
if (fprintf (f, "%s", repos) < 0)
{
- pending_error = errno;
+ int save_errno = errno;
+ if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
+ sprintf (pending_error_text,
+ "E error writing %s/%s", dir_name, CVSADM_REP);
+ pending_error = save_errno;
fclose (f);
return;
}
@@ -1100,20 +1102,32 @@ dirswitch (dir, repos)
{
if (fprintf (f, "/.") < 0)
{
- pending_error = errno;
+ int save_errno = errno;
+ if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
+ sprintf (pending_error_text,
+ "E error writing %s/%s", dir_name, CVSADM_REP);
+ pending_error = save_errno;
fclose (f);
return;
}
}
if (fprintf (f, "\n") < 0)
{
- pending_error = errno;
+ int save_errno = errno;
+ if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
+ sprintf (pending_error_text,
+ "E error writing %s/%s", dir_name, CVSADM_REP);
+ pending_error = save_errno;
fclose (f);
return;
}
if (fclose (f) == EOF)
{
- pending_error = errno;
+ int save_errno = errno;
+ if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
+ sprintf (pending_error_text,
+ "E error closing %s/%s", dir_name, CVSADM_REP);
+ pending_error = save_errno;
return;
}
/* We open in append mode because we don't want to clobber an
@@ -1121,16 +1135,18 @@ dirswitch (dir, repos)
f = CVS_FOPEN (CVSADM_ENT, "a");
if (f == NULL)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_ENT)))
sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
+ pending_error = save_errno;
return;
}
if (fclose (f) == EOF)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_ENT)))
sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
+ pending_error = save_errno;
return;
}
}
@@ -1139,10 +1155,7 @@ static void
serve_repository (arg)
char *arg;
{
- pending_error_text = malloc (80);
- if (pending_error_text == NULL)
- pending_error = ENOMEM;
- else
+ if (alloc_pending (80))
strcpy (pending_error_text,
"E Repository request is obsolete; aborted");
return;
@@ -1158,9 +1171,8 @@ serve_directory (arg)
status = buf_read_line (buf_from_net, &repos, (int *) NULL);
if (status == 0)
{
- if (outside_root (repos))
- return;
- dirswitch (arg, repos);
+ if (!outside_root (repos))
+ dirswitch (arg, repos);
free (repos);
}
else if (status == -2)
@@ -1199,16 +1211,18 @@ serve_static_directory (arg)
f = CVS_FOPEN (CVSADM_ENTSTAT, "w+");
if (f == NULL)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
sprintf (pending_error_text, "E cannot open %s", CVSADM_ENTSTAT);
+ pending_error = save_errno;
return;
}
if (fclose (f) == EOF)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
sprintf (pending_error_text, "E cannot close %s", CVSADM_ENTSTAT);
+ pending_error = save_errno;
return;
}
}
@@ -1224,23 +1238,26 @@ serve_sticky (arg)
f = CVS_FOPEN (CVSADM_TAG, "w+");
if (f == NULL)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_TAG)))
sprintf (pending_error_text, "E cannot open %s", CVSADM_TAG);
+ pending_error = save_errno;
return;
}
if (fprintf (f, "%s\n", arg) < 0)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_TAG)))
sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG);
+ pending_error = save_errno;
return;
}
if (fclose (f) == EOF)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_TAG)))
sprintf (pending_error_text, "E cannot close %s", CVSADM_TAG);
+ pending_error = save_errno;
return;
}
}
@@ -1299,10 +1316,10 @@ receive_partial_file (size, file)
nwrote = write (file, data, nread);
if (nwrote < 0)
{
- pending_error_text = malloc (40);
- if (pending_error_text != NULL)
- sprintf (pending_error_text, "E unable to write");
- pending_error = errno;
+ int save_errno = errno;
+ if (alloc_pending (40))
+ strcpy (pending_error_text, "E unable to write");
+ pending_error = save_errno;
/* Read and discard the file data. */
while (size > 0)
@@ -1338,10 +1355,10 @@ receive_file (size, file, gzipped)
fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd < 0)
{
- pending_error_text = malloc (40 + strlen (arg));
- if (pending_error_text)
+ int save_errno = errno;
+ if (alloc_pending (40 + strlen (arg)))
sprintf (pending_error_text, "E cannot open %s", arg);
- pending_error = errno;
+ pending_error = save_errno;
return;
}
@@ -1407,7 +1424,7 @@ receive_file (size, file, gzipped)
goto out;
}
- if (gunzip_and_write (fd, file, filebuf, size))
+ if (gunzip_and_write (fd, file, (unsigned char *) filebuf, size))
{
if (alloc_pending (80))
sprintf (pending_error_text,
@@ -1433,10 +1450,10 @@ receive_file (size, file, gzipped)
out:
if (close (fd) < 0 && !error_pending ())
{
- pending_error_text = malloc (40 + strlen (arg));
- if (pending_error_text)
+ int save_errno = errno;
+ if (alloc_pending (40 + strlen (arg)))
sprintf (pending_error_text, "E cannot close %s", arg);
- pending_error = errno;
+ pending_error = save_errno;
return;
}
}
@@ -1515,10 +1532,11 @@ serve_modified (arg)
{
sprintf (pending_error_text,
"E error reading size for %s", arg);
- pending_error = errno;
+ pending_error = status;
}
}
}
+ free (mode_text);
return;
}
if (size_text[0] == 'z')
@@ -1543,16 +1561,24 @@ serve_modified (arg)
return;
size -= nread;
}
+ free (mode_text);
return;
}
if (outside_dir (arg))
+ {
+ free (mode_text);
return;
+ }
if (size >= 0)
{
receive_file (size, arg, gzipped);
- if (error_pending ()) return;
+ if (error_pending ())
+ {
+ free (mode_text);
+ return;
+ }
}
if (checkin_time_valid)
@@ -1563,9 +1589,11 @@ serve_modified (arg)
t.modtime = t.actime = checkin_time;
if (utime (arg, &t) < 0)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (arg)))
sprintf (pending_error_text, "E cannot utime %s", arg);
+ pending_error = save_errno;
+ free (mode_text);
return;
}
checkin_time_valid = 0;
@@ -1576,8 +1604,7 @@ serve_modified (arg)
free (mode_text);
if (status)
{
- pending_error_text = malloc (40 + strlen (arg));
- if (pending_error_text)
+ if (alloc_pending (40 + strlen (arg)))
sprintf (pending_error_text,
"E cannot change mode for %s", arg);
pending_error = status;
@@ -1852,9 +1879,10 @@ server_write_entries ()
f = CVS_FOPEN (CVSADM_ENT, "a");
if (f == NULL)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_ENT)))
sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
+ pending_error = save_errno;
}
}
for (p = entries; p != NULL;)
@@ -1863,10 +1891,11 @@ server_write_entries ()
{
if (fprintf (f, "%s\n", p->entry) < 0)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen(CVSADM_ENT)))
sprintf (pending_error_text,
"E cannot write to %s", CVSADM_ENT);
+ pending_error = save_errno;
}
}
free (p->entry);
@@ -1877,9 +1906,10 @@ server_write_entries ()
entries = NULL;
if (f != NULL && fclose (f) == EOF && !error_pending ())
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_ENT)))
sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
+ pending_error = save_errno;
}
}
@@ -1911,8 +1941,8 @@ static void
serve_notify (arg)
char *arg;
{
- struct notify_note *new;
- char *data;
+ struct notify_note *new = NULL;
+ char *data = NULL;
int status;
if (error_pending ()) return;
@@ -1920,27 +1950,26 @@ serve_notify (arg)
if (outside_dir (arg))
return;
+ if (dir_name == NULL)
+ goto error;
+
new = (struct notify_note *) malloc (sizeof (struct notify_note));
if (new == NULL)
{
pending_error = ENOMEM;
return;
}
- if (dir_name == NULL)
- goto error;
new->dir = malloc (strlen (dir_name) + 1);
- if (new->dir == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcpy (new->dir, dir_name);
new->filename = malloc (strlen (arg) + 1);
- if (new->filename == NULL)
+ if (new->dir == NULL || new->filename == NULL)
{
pending_error = ENOMEM;
+ if (new->dir != NULL)
+ free (new->dir);
+ free (new);
return;
}
+ strcpy (new->dir, dir_name);
strcpy (new->filename, arg);
status = buf_read_line (buf_from_net, &data, (int *) NULL);
@@ -1966,6 +1995,9 @@ serve_notify (arg)
}
}
}
+ free (new->filename);
+ free (new->dir);
+ free (new);
}
else
{
@@ -2013,11 +2045,18 @@ serve_notify (arg)
}
return;
error:
- pending_error_text = malloc (80);
- if (pending_error_text)
+ pending_error = 0;
+ if (alloc_pending (80))
strcpy (pending_error_text,
"E Protocol error; misformed Notify request");
- pending_error = 0;
+ if (data != NULL)
+ free (data);
+ if (new != NULL)
+ {
+ free (new->filename);
+ free (new->dir);
+ free (new);
+ }
return;
}
@@ -2060,6 +2099,7 @@ server_notify ()
buf_append_char (buf_to_net, '/');
buf_output0 (buf_to_net, notify_list->filename);
buf_append_char (buf_to_net, '\n');
+ free (repos);
p = notify_list->next;
free (notify_list->filename);
@@ -2647,22 +2687,26 @@ error \n");
if (pipe (stdout_pipe) < 0)
{
+ buf_output0 (buf_to_net, "E pipe failed\n");
print_error (errno);
goto error_exit;
}
if (pipe (stderr_pipe) < 0)
{
+ buf_output0 (buf_to_net, "E pipe failed\n");
print_error (errno);
goto error_exit;
}
if (pipe (protocol_pipe) < 0)
{
+ buf_output0 (buf_to_net, "E pipe failed\n");
print_error (errno);
goto error_exit;
}
#ifdef SERVER_FLOWCONTROL
if (pipe (flowcontrol_pipe) < 0)
{
+ buf_output0 (buf_to_net, "E pipe failed\n");
print_error (errno);
goto error_exit;
}
@@ -2673,6 +2717,7 @@ error \n");
dev_null_fd = CVS_OPEN (DEVNULL, O_RDONLY);
if (dev_null_fd < 0)
{
+ buf_output0 (buf_to_net, "E open /dev/null failed\n");
print_error (errno);
goto error_exit;
}
@@ -2700,6 +2745,7 @@ error \n");
command_pid = fork ();
if (command_pid < 0)
{
+ buf_output0 (buf_to_net, "E fork failed\n");
print_error (errno);
goto error_exit;
}
@@ -2733,8 +2779,11 @@ error \n");
error (1, errno, "can't set up pipes");
if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0)
error (1, errno, "can't set up pipes");
+ close (dev_null_fd);
close (stdout_pipe[0]);
+ close (stdout_pipe[1]);
close (stderr_pipe[0]);
+ close (stderr_pipe[1]);
close (protocol_pipe[0]);
#ifdef SERVER_FLOWCONTROL
close (flowcontrol_pipe[1]);
@@ -2769,6 +2818,7 @@ error \n");
* When we exit, that will close the pipes, giving an EOF to
* the parent.
*/
+ buf_free (protocol);
exit (exitstatus);
}
@@ -2825,6 +2875,7 @@ error \n");
if (close (stdout_pipe[1]) < 0)
{
+ buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
}
@@ -2832,6 +2883,7 @@ error \n");
if (close (stderr_pipe[1]) < 0)
{
+ buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
}
@@ -2839,6 +2891,7 @@ error \n");
if (close (protocol_pipe[1]) < 0)
{
+ buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
}
@@ -2847,6 +2900,7 @@ error \n");
#ifdef SERVER_FLOWCONTROL
if (close (flowcontrol_pipe[0]) < 0)
{
+ buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
}
@@ -2855,6 +2909,7 @@ error \n");
if (close (dev_null_fd) < 0)
{
+ buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
}
@@ -2922,6 +2977,7 @@ error \n");
if (numfds < 0
&& errno != EINTR)
{
+ buf_output0 (buf_to_net, "E select failed\n");
print_error (errno);
goto error_exit;
}
@@ -2933,48 +2989,6 @@ error \n");
buf_send_output (buf_to_net);
}
- if (stdout_pipe[0] >= 0
- && (FD_ISSET (stdout_pipe[0], &readfds)))
- {
- int status;
-
- status = buf_input_data (stdoutbuf, (int *) NULL);
-
- buf_copy_lines (buf_to_net, stdoutbuf, 'M');
-
- if (status == -1)
- stdout_pipe[0] = -1;
- else if (status > 0)
- {
- print_error (status);
- goto error_exit;
- }
-
- /* What should we do with errors? syslog() them? */
- buf_send_output (buf_to_net);
- }
-
- if (stderr_pipe[0] >= 0
- && (FD_ISSET (stderr_pipe[0], &readfds)))
- {
- int status;
-
- status = buf_input_data (stderrbuf, (int *) NULL);
-
- buf_copy_lines (buf_to_net, stderrbuf, 'E');
-
- if (status == -1)
- stderr_pipe[0] = -1;
- else if (status > 0)
- {
- print_error (status);
- goto error_exit;
- }
-
- /* What should we do with errors? syslog() them? */
- buf_send_output (buf_to_net);
- }
-
if (protocol_pipe[0] >= 0
&& (FD_ISSET (protocol_pipe[0], &readfds)))
{
@@ -2985,9 +2999,13 @@ error \n");
status = buf_input_data (protocol_inbuf, &count_read);
if (status == -1)
+ {
+ close (protocol_pipe[0]);
protocol_pipe[0] = -1;
+ }
else if (status > 0)
{
+ buf_output0 (buf_to_net, "E buf_input_data failed\n");
print_error (status);
goto error_exit;
}
@@ -3024,6 +3042,56 @@ error \n");
}
}
}
+
+ if (stdout_pipe[0] >= 0
+ && (FD_ISSET (stdout_pipe[0], &readfds)))
+ {
+ int status;
+
+ status = buf_input_data (stdoutbuf, (int *) NULL);
+
+ buf_copy_lines (buf_to_net, stdoutbuf, 'M');
+
+ if (status == -1)
+ {
+ close (stdout_pipe[0]);
+ stdout_pipe[0] = -1;
+ }
+ else if (status > 0)
+ {
+ buf_output0 (buf_to_net, "E buf_input_data failed\n");
+ print_error (status);
+ goto error_exit;
+ }
+
+ /* What should we do with errors? syslog() them? */
+ buf_send_output (buf_to_net);
+ }
+
+ if (stderr_pipe[0] >= 0
+ && (FD_ISSET (stderr_pipe[0], &readfds)))
+ {
+ int status;
+
+ status = buf_input_data (stderrbuf, (int *) NULL);
+
+ buf_copy_lines (buf_to_net, stderrbuf, 'E');
+
+ if (status == -1)
+ {
+ close (stderr_pipe[0]);
+ stderr_pipe[0] = -1;
+ }
+ else if (status > 0)
+ {
+ buf_output0 (buf_to_net, "E buf_input_data failed\n");
+ print_error (status);
+ goto error_exit;
+ }
+
+ /* What should we do with errors? syslog() them? */
+ buf_send_output (buf_to_net);
+ }
}
/*
@@ -3045,6 +3113,11 @@ error \n");
buf_output0 (buf_to_net,
"E Protocol error: uncounted data discarded\n");
+#ifdef SERVER_FLOWCONTROL
+ close (flowcontrol_pipe[1]);
+ flowcontrol_pipe[1] = -1;
+#endif /* SERVER_FLOWCONTROL */
+
errs = 0;
while (command_pid > 0)
@@ -3099,6 +3172,12 @@ E CVS locks may need cleaning up.\n");
*/
set_block (buf_to_net);
buf_flush (buf_to_net, 1);
+ buf_shutdown (protocol_inbuf);
+ buf_free (protocol_inbuf);
+ buf_shutdown (stderrbuf);
+ buf_free (stderrbuf);
+ buf_shutdown (stdoutbuf);
+ buf_free (stdoutbuf);
}
if (errs)
@@ -3129,6 +3208,10 @@ E CVS locks may need cleaning up.\n");
close (stderr_pipe[1]);
close (stdout_pipe[0]);
close (stdout_pipe[1]);
+#ifdef SERVER_FLOWCONTROL
+ close (flowcontrol_pipe[0]);
+ close (flowcontrol_pipe[1]);
+#endif /* SERVER_FLOWCONTROL */
free_args_and_return:
/* Now free the arguments. */
@@ -3184,6 +3267,7 @@ server_pause_check()
if (numfds < 0
&& errno != EINTR)
{
+ buf_output0 (buf_to_net, "E select failed\n");
print_error (errno);
return;
}
@@ -3624,23 +3708,29 @@ serve_editors (arg)
do_cvs_command ("editors", editors);
}
-static int noop PROTO ((int, char **));
+static void serve_noop PROTO ((char *));
-static int
-noop (argc, argv)
- int argc;
- char **argv;
+static void
+serve_noop (arg)
+ char *arg;
{
- return 0;
+
+ server_write_entries ();
+ if (!print_pending_error ())
+ {
+ (void) server_notify ();
+ buf_output0 (buf_to_net, "ok\n");
+ }
+ buf_flush (buf_to_net, 1);
}
-static void serve_noop PROTO ((char *));
+static void serve_version PROTO ((char *));
static void
-serve_noop (arg)
+serve_version (arg)
char *arg;
{
- do_cvs_command ("noop", noop);
+ do_cvs_command ("version", version);
}
static void serve_init PROTO ((char *));
@@ -4017,7 +4107,7 @@ CVS server internal error: unhandled case in server_updated");
if (file != NULL)
{
- buf_output (protocol, file, file_used);
+ buf_output (protocol, (char *) file, file_used);
free (file);
file = NULL;
}
@@ -4314,9 +4404,9 @@ serve_ignore (arg)
}
static int
-expand_proc (pargc, argv, where, mwhere, mfile, shorten,
+expand_proc (argc, argv, where, mwhere, mfile, shorten,
local_specified, omodule, msg)
- int *pargc;
+ int argc;
char **argv;
char *where;
char *mwhere;
@@ -4355,7 +4445,7 @@ expand_proc (pargc, argv, where, mwhere, mfile, shorten,
{
/* We may not need to do this anymore -- check the definition
of aliases before removing */
- if (*pargc == 1)
+ if (argc == 1)
{
buf_output0 (buf_to_net, "Module-expansion ");
if (server_dir != NULL)
@@ -4368,7 +4458,7 @@ expand_proc (pargc, argv, where, mwhere, mfile, shorten,
}
else
{
- for (i = 1; i < *pargc; ++i)
+ for (i = 1; i < argc; ++i)
{
buf_output0 (buf_to_net, "Module-expansion ");
if (server_dir != NULL)
@@ -4460,24 +4550,27 @@ serve_checkin_prog (arg)
f = CVS_FOPEN (CVSADM_CIPROG, "w+");
if (f == NULL)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_CIPROG)))
sprintf (pending_error_text, "E cannot open %s", CVSADM_CIPROG);
+ pending_error = save_errno;
return;
}
if (fprintf (f, "%s\n", arg) < 0)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_CIPROG)))
sprintf (pending_error_text,
"E cannot write to %s", CVSADM_CIPROG);
+ pending_error = save_errno;
return;
}
if (fclose (f) == EOF)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_CIPROG)))
sprintf (pending_error_text, "E cannot close %s", CVSADM_CIPROG);
+ pending_error = save_errno;
return;
}
}
@@ -4503,23 +4596,26 @@ E Flag -u in modules not allowed in readonly mode");
f = CVS_FOPEN (CVSADM_UPROG, "w+");
if (f == NULL)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_UPROG)))
sprintf (pending_error_text, "E cannot open %s", CVSADM_UPROG);
+ pending_error = save_errno;
return;
}
if (fprintf (f, "%s\n", arg) < 0)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_UPROG)))
sprintf (pending_error_text, "E cannot write to %s", CVSADM_UPROG);
+ pending_error = save_errno;
return;
}
if (fclose (f) == EOF)
{
- pending_error = errno;
+ int save_errno = errno;
if (alloc_pending (80 + strlen (CVSADM_UPROG)))
sprintf (pending_error_text, "E cannot close %s", CVSADM_UPROG);
+ pending_error = save_errno;
return;
}
}
@@ -4572,7 +4668,7 @@ struct request requests[] =
REQ_LINE("Case", serve_case, 0),
REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL),
REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL),
- REQ_LINE("Global_option", serve_global_option, 0),
+ REQ_LINE("Global_option", serve_global_option, RQ_ROOTLESS),
REQ_LINE("Gzip-stream", serve_gzip_stream, 0),
REQ_LINE("wrapper-sendme-rcsOptions",
serve_wrapper_sendme_rcs_options,
@@ -4616,7 +4712,8 @@ struct request requests[] =
REQ_LINE("editors", serve_editors, 0),
REQ_LINE("init", serve_init, RQ_ROOTLESS),
REQ_LINE("annotate", serve_annotate, 0),
- REQ_LINE("noop", serve_noop, 0),
+ REQ_LINE("noop", serve_noop, RQ_ROOTLESS),
+ REQ_LINE("version", serve_version, RQ_ROOTLESS),
REQ_LINE(NULL, NULL, 0)
#undef REQ_LINE
@@ -4840,16 +4937,10 @@ server (argc, argv)
for that case. */
if (!isabsolute (Tmpdir))
{
- pending_error_text = malloc (80 + strlen (Tmpdir));
- if (pending_error_text == NULL)
- {
- pending_error = ENOMEM;
- }
- else
- {
+ if (alloc_pending (80 + strlen (Tmpdir)))
sprintf (pending_error_text,
"E Value of %s for TMPDIR is not absolute", Tmpdir);
- }
+
/* FIXME: we would like this error to be persistent, that
is, not cleared by print_pending_error. The current client
will exit as soon as it gets an error, but the protocol spec
@@ -4858,6 +4949,7 @@ server (argc, argv)
else
{
int status;
+ int i = 0;
server_temp_dir = malloc (strlen (Tmpdir) + 80);
if (server_temp_dir == NULL)
@@ -4904,12 +4996,21 @@ error ENOMEM Virtual memory exhausted.\n");
/* Create the temporary directory, and set the mode to
700, to discourage random people from tampering with
it. */
- status = mkdir_p (server_temp_dir);
- if (status != 0 && status != EEXIST)
+ while ((status = mkdir_p (server_temp_dir)) == EEXIST)
{
- if (alloc_pending (80))
- strcpy (pending_error_text,
- "E can't create temporary directory");
+ static const char suffix[] = "abcdefghijklmnopqrstuvwxyz";
+
+ if (i >= sizeof suffix - 1) break;
+ if (i == 0) p = server_temp_dir + strlen (server_temp_dir);
+ p[0] = suffix[i++];
+ p[1] = '\0';
+ }
+ if (status != 0)
+ {
+ if (alloc_pending (80 + strlen (server_temp_dir)))
+ sprintf (pending_error_text,
+ "E can't create temporary directory %s",
+ server_temp_dir);
pending_error = status;
}
#ifndef CHMOD_BROKEN
@@ -4918,9 +5019,10 @@ error ENOMEM Virtual memory exhausted.\n");
if (chmod (server_temp_dir, S_IRWXU) < 0)
{
int save_errno = errno;
- if (alloc_pending (80))
- strcpy (pending_error_text, "\
-E cannot change permissions on temporary directory");
+ if (alloc_pending (80 + strlen (server_temp_dir)))
+ sprintf (pending_error_text,
+"E cannot change permissions on temporary directory %s",
+ server_temp_dir);
pending_error = save_errno;
}
}
@@ -4928,6 +5030,9 @@ E cannot change permissions on temporary directory");
}
}
+#ifdef SIGABRT
+ (void) SIG_register (SIGABRT, server_cleanup);
+#endif
#ifdef SIGHUP
(void) SIG_register (SIGHUP, server_cleanup);
#endif
@@ -5107,7 +5212,7 @@ error 0 %s: no such user\n", username);
if (setgid (getegid ()) < 0)
{
/* See comments at setuid call below for more discussion. */
- printf ("error 0 setuid failed: %s\n", strerror (errno));
+ printf ("error 0 setgid failed: %s\n", strerror (errno));
/* Don't worry about server_cleanup;
server_active isn't set yet. */
error_exit ();
@@ -5119,7 +5224,7 @@ error 0 %s: no such user\n", username);
if (setgid (pw->pw_gid) < 0)
{
/* See comments at setuid call below for more discussion. */
- printf ("error 0 setuid failed: %s\n", strerror (errno));
+ printf ("error 0 setgid failed: %s\n", strerror (errno));
/* Don't worry about server_cleanup;
server_active isn't set yet. */
error_exit ();
@@ -5144,6 +5249,12 @@ error 0 %s: no such user\n", username);
the client. */
umask (0);
+#ifdef AUTH_SERVER_SUPPORT
+ /* Make sure our CVS_Username has been set. */
+ if (CVS_Username == NULL)
+ CVS_Username = xstrdup (username);
+#endif
+
#if HAVE_PUTENV
/* Set LOGNAME and USER in the environment, in case they are
already set to something else. */
@@ -5169,14 +5280,15 @@ extern char *crypt PROTO((const char *, const char *));
/*
* 0 means no entry found for this user.
- * 1 means entry found and password matches.
+ * 1 means entry found and password matches (or found password is empty)
* 2 means entry found, but password does not match.
*
- * If success, host_user_ptr will be set to point at the system
+ * If 1, host_user_ptr will be set to point at the system
* username (i.e., the "real" identity, which may or may not be the
* CVS username) of this user; caller may free this. Global
* CVS_Username will point at an allocated copy of cvs username (i.e.,
* the username argument below).
+ * kff todo: FIXME: last sentence is not true, it applies to caller.
*/
static int
check_repository_password (username, password, repository, host_user_ptr)
@@ -5229,18 +5341,72 @@ check_repository_password (username, password, repository, host_user_ptr)
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", filename);
- /* If found_it != 0, then linebuf contains the information we need. */
+ /* If found_it, then linebuf contains the information we need. */
if (found_it)
{
char *found_password, *host_user_tmp;
+ char *non_cvsuser_portion;
+
+ /* We need to make sure lines such as
+ *
+ * "username::sysuser\n"
+ * "username:\n"
+ * "username: \n"
+ *
+ * all result in a found_password of NULL, but we also need to
+ * make sure that
+ *
+ * "username: :sysuser\n"
+ * "username: <whatever>:sysuser\n"
+ *
+ * continues to result in an impossible password. That way,
+ * an admin would be on safe ground by going in and tacking a
+ * space onto the front of a password to disable the account
+ * (a technique some people use to close accounts
+ * temporarily).
+ */
+
+ /* Make `non_cvsuser_portion' contain everything after the CVS
+ username, but null out any final newline. */
+ non_cvsuser_portion = linebuf + namelen;
+ strtok (non_cvsuser_portion, "\n");
+
+ /* If there's a colon now, we just want to inch past it. */
+ if (strchr (non_cvsuser_portion, ':') == non_cvsuser_portion)
+ non_cvsuser_portion++;
+
+ /* Okay, after this conditional chain, found_password and
+ host_user_tmp will have useful values: */
+
+ if ((non_cvsuser_portion == NULL)
+ || (strlen (non_cvsuser_portion) == 0)
+ || ((strspn (non_cvsuser_portion, " \t"))
+ == strlen (non_cvsuser_portion)))
+ {
+ found_password = NULL;
+ host_user_tmp = NULL;
+ }
+ else if (strncmp (non_cvsuser_portion, ":", 1) == 0)
+ {
+ found_password = NULL;
+ host_user_tmp = non_cvsuser_portion + 1;
+ if (strlen (host_user_tmp) == 0)
+ host_user_tmp = NULL;
+ }
+ else
+ {
+ found_password = strtok (non_cvsuser_portion, ":");
+ host_user_tmp = strtok (NULL, ":");
+ }
- strtok (linebuf, ":");
- found_password = strtok (NULL, ": \n");
- host_user_tmp = strtok (NULL, ": \n");
+ /* Of course, maybe there was no system user portion... */
if (host_user_tmp == NULL)
host_user_tmp = username;
- if (strcmp (found_password, crypt (password, found_password)) == 0)
+ /* Verify blank passwords directly, otherwise use crypt(). */
+ if ((found_password == NULL)
+ || ((strcmp (found_password, crypt (password, found_password))
+ == 0)))
{
/* Give host_user_ptr permanent storage. */
*host_user_ptr = xstrdup (host_user_tmp);
@@ -5252,7 +5418,7 @@ check_repository_password (username, password, repository, host_user_ptr)
retval = 2;
}
}
- else
+ else /* Didn't find this user, so deny access. */
{
*host_user_ptr = NULL;
retval = 0;
@@ -5335,14 +5501,14 @@ error 0 %s: no such user\n", username);
/* user exists and has a password */
host_user = ((! strcmp (found_passwd,
crypt (password, found_passwd)))
- ? username : NULL);
+ ? xstrdup (username) : NULL);
goto handle_return;
}
else if (password && *password)
{
/* user exists and has no system password, but we got
one as parameter */
- host_user = username;
+ host_user = xstrdup (username);
goto handle_return;
}
else
@@ -5472,7 +5638,7 @@ pserver_authenticate_connection ()
#endif
/* Make sure the protocol starts off on the right foot... */
- if (getline (&tmp, &tmp_allocated, stdin) < 0)
+ if (getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX) < 0)
/* FIXME: what? We could try writing error/eof, but chances
are the network connection is dead bidirectionally. log it
somewhere? */
@@ -5503,9 +5669,9 @@ pserver_authenticate_connection ()
/* Get the three important pieces of information in order. */
/* See above comment about error handling. */
- getline (&repository, &repository_allocated, stdin);
- getline (&username, &username_allocated, stdin);
- getline (&password, &password_allocated, stdin);
+ getline_safe (&repository, &repository_allocated, stdin, PATH_MAX);
+ getline_safe (&username, &username_allocated, stdin, PATH_MAX);
+ getline_safe (&password, &password_allocated, stdin, PATH_MAX);
/* Make them pure. */
strip_trailing_newlines (repository);
@@ -5514,7 +5680,7 @@ pserver_authenticate_connection ()
/* ... and make sure the protocol ends on the right foot. */
/* See above comment about error handling. */
- getline (&tmp, &tmp_allocated, stdin);
+ getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX);
if (strcmp (tmp,
verify_and_exit ?
"END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n")
@@ -5576,6 +5742,7 @@ pserver_authenticate_connection ()
/* Switch to run as this user. */
switch_to_user (host_user);
+ free (host_user);
free (tmp);
free (repository);
free (username);
diff --git a/contrib/cvs/src/subr.c b/contrib/cvs/src/subr.c
index 6a97f28..c9f3747 100644
--- a/contrib/cvs/src/subr.c
+++ b/contrib/cvs/src/subr.c
@@ -171,7 +171,8 @@ pathname_levels (path)
if (-level > max_level)
max_level = -level;
}
- else if (p[0] == '.' && (p[1] == '\0' || p[1] == '/'))
+ else if (p[0] == '\0' || p[0] == '/' ||
+ (p[0] == '.' && (p[1] == '\0' || p[1] == '/')))
;
else
++level;
@@ -218,9 +219,7 @@ line2argv (pargc, argv, line, sepchars)
int argv_allocated;
/* Small for testing. */
- /* argv_allocated must be at least 3 because at some places
- (e.g. checkout_proc) cvs alters argv[2]. */
- argv_allocated = 4;
+ argv_allocated = 1;
*argv = (char **) xmalloc (argv_allocated * sizeof (**argv));
*pargc = 0;
@@ -586,7 +585,9 @@ file_has_markers (finfo)
error (1, errno, "cannot open %s", finfo->fullname);
while (getline (&line, &line_allocated, fp) > 0)
{
- if (strncmp (line, RCS_MERGE_PAT, sizeof RCS_MERGE_PAT - 1) == 0)
+ if (strncmp (line, RCS_MERGE_PAT_1, sizeof RCS_MERGE_PAT_1 - 1) == 0 ||
+ strncmp (line, RCS_MERGE_PAT_2, sizeof RCS_MERGE_PAT_2 - 1) == 0 ||
+ strncmp (line, RCS_MERGE_PAT_3, sizeof RCS_MERGE_PAT_3 - 1) == 0)
{
result = 1;
goto out;
@@ -647,9 +648,9 @@ get_file (name, fullname, mode, buf, bufsize, len)
e = open_file (name, mode);
}
- if (*bufsize < filesize)
+ if (*buf == NULL || *bufsize <= filesize)
{
- *bufsize = filesize;
+ *bufsize = filesize + 1;
*buf = xrealloc (*buf, *bufsize);
}
@@ -691,12 +692,9 @@ get_file (name, fullname, mode, buf, bufsize, len)
*len = nread;
/* Force *BUF to be large enough to hold a null terminator. */
- if (*buf != NULL)
- {
- if (nread == *bufsize)
- expand_string (buf, bufsize, *bufsize + 1);
- (*buf)[nread] = '\0';
- }
+ if (nread == *bufsize)
+ expand_string (buf, bufsize, *bufsize + 1);
+ (*buf)[nread] = '\0';
}
@@ -744,3 +742,37 @@ resolve_symlink (filename)
}
}
}
+
+/*
+ * Rename a file to an appropriate backup name based on BAKPREFIX.
+ * If suffix non-null, then ".<suffix>" is appended to the new name.
+ *
+ * Returns the new name, which caller may free() if desired.
+ */
+char *
+backup_file (filename, suffix)
+ const char *filename;
+ const char *suffix;
+{
+ char *backup_name;
+
+ if (suffix == NULL)
+ {
+ backup_name = xmalloc (sizeof (BAKPREFIX) + strlen (filename) + 1);
+ sprintf (backup_name, "%s%s", BAKPREFIX, filename);
+ }
+ else
+ {
+ backup_name = xmalloc (sizeof (BAKPREFIX)
+ + strlen (filename)
+ + strlen (suffix)
+ + 2); /* one for dot, one for trailing '\0' */
+ sprintf (backup_name, "%s%s.%s", BAKPREFIX, filename, suffix);
+ }
+
+ if (isfile (filename))
+ copy_file (filename, backup_name);
+
+ return backup_name;
+}
+
diff --git a/contrib/cvs/src/tag.c b/contrib/cvs/src/tag.c
index fb19cba..a9d8534 100644
--- a/contrib/cvs/src/tag.c
+++ b/contrib/cvs/src/tag.c
@@ -234,9 +234,12 @@ check_fileproc (callerdat, finfo)
if ((status != T_UPTODATE) && (status != T_CHECKOUT))
{
error (0, 0, "%s is locally modified", finfo->fullname);
+ freevers_ts (&vers);
return (1);
}
}
+ else
+ vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
if (finfo->update_dir[0] == '\0')
xdir = ".";
@@ -266,11 +269,12 @@ check_fileproc (callerdat, finfo)
p->key = xstrdup (finfo->file);
p->type = UPDATE;
p->delproc = tag_delproc;
- vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
if (vers->srcfile == NULL)
{
if (!really_quiet)
error (0, 0, "nothing known about %s", finfo->file);
+ freevers_ts (&vers);
+ freenode (p);
return (1);
}
@@ -579,6 +583,8 @@ tag_fileproc (callerdat, finfo)
if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch)
{
free (oversion);
+ if (branch_mode)
+ free (rev);
freevers_ts (&vers);
return (0);
}
@@ -600,6 +606,8 @@ tag_fileproc (callerdat, finfo)
cvs_output (rev, 0);
cvs_output ("\n", 1);
free (oversion);
+ if (branch_mode)
+ free (rev);
freevers_ts (&vers);
return (0);
}
@@ -611,9 +619,13 @@ tag_fileproc (callerdat, finfo)
error (1, retcode == -1 ? errno : 0,
"failed to set tag %s to revision %s in %s",
symtag, rev, vers->srcfile->path);
+ if (branch_mode)
+ free (rev);
freevers_ts (&vers);
return (1);
}
+ if (branch_mode)
+ free (rev);
RCS_rewrite (vers->srcfile, NULL, NULL);
/* more warm fuzzies */
@@ -718,7 +730,7 @@ val_direntproc (callerdat, dir, repository, update_dir, entries)
files in a directory which does not exist yet, but which is
about to be created. */
if (isdir (dir))
- return 0;
+ return R_PROCESS;
return R_SKIP_ALL;
}
diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c
index 4a24d15..81d4fea 100644
--- a/contrib/cvs/src/update.c
+++ b/contrib/cvs/src/update.c
@@ -94,6 +94,7 @@ static char *tag_update_dir;
static char *join_rev1, *date_rev1;
static char *join_rev2, *date_rev2;
static int aflag = 0;
+static int toss_local_changes = 0;
static int force_tag_match = 1;
static int update_build_dirs = 0;
static int update_prune_dirs = 0;
@@ -110,6 +111,7 @@ static const char *const update_usage[] =
" [-I ign] [-W spec] [files...]\n",
"\t-A\tReset any sticky tags/date/kopts.\n",
"\t-P\tPrune empty directories.\n",
+ "\t-C\tOverwrite locally modified files with clean repository copies.\n",
"\t-d\tBuild directories, like checkout does.\n",
"\t-f\tForce a head revision match if tag/date not found.\n",
"\t-l\tLocal directory only, no recursion.\n",
@@ -145,13 +147,16 @@ update (argc, argv)
/* parse the args */
optind = 0;
- while ((c = getopt (argc, argv, "+ApPflRQqduk:r:D:j:I:W:")) != -1)
+ while ((c = getopt (argc, argv, "+ApCPflRQqduk:r:D:j:I:W:")) != -1)
{
switch (c)
{
case 'A':
aflag = 1;
break;
+ case 'C':
+ toss_local_changes = 1;
+ break;
case 'I':
ign_add (optarg, 0);
break;
@@ -252,6 +257,8 @@ update (argc, argv)
send_arg("-f");
if (aflag)
send_arg("-A");
+ if (toss_local_changes)
+ send_arg("-C");
if (update_prune_dirs)
send_arg("-P");
client_prune_dirs = update_prune_dirs;
@@ -266,28 +273,35 @@ update (argc, argv)
option_with_arg ("-j", join_rev2);
wrap_send ();
- /* If the server supports the command "update-patches", that means
- that it knows how to handle the -u argument to update, which
- means to send patches instead of complete files.
-
- We don't send -u if failed_patches != NULL, so that the
- server doesn't try to send patches which will just fail
- again. At least currently, the client also clobbers the
- file and tells the server it is lost, which also will get
- a full file instead of a patch, but it seems clean to omit
- -u. */
- if (failed_patches == NULL)
+ if (failed_patches_count == 0)
{
+ unsigned int flags = 0;
+
+ /* If the server supports the command "update-patches", that
+ means that it knows how to handle the -u argument to update,
+ which means to send patches instead of complete files.
+
+ We don't send -u if failed_patches != NULL, so that the
+ server doesn't try to send patches which will just fail
+ again. At least currently, the client also clobbers the
+ file and tells the server it is lost, which also will get
+ a full file instead of a patch, but it seems clean to omit
+ -u. */
if (supported_request ("update-patches"))
send_arg ("-u");
- }
- if (failed_patches == NULL)
- {
+ if (update_build_dirs)
+ flags |= SEND_BUILD_DIRS;
+
+ if (toss_local_changes) {
+ flags |= SEND_NO_CONTENTS;
+ flags |= BACKUP_MODIFIED_FILES;
+ }
+
/* If noexec, probably could be setting SEND_NO_CONTENTS.
Same caveats as for "cvs status" apply. */
- send_files (argc, argv, local, aflag,
- update_build_dirs ? SEND_BUILD_DIRS : 0);
+
+ send_files (argc, argv, local, aflag, flags);
send_file_names (argc, argv, SEND_EXPAND_WILD);
}
else
@@ -311,11 +325,9 @@ update (argc, argv)
send_files (failed_patches_count, failed_patches, local,
aflag, update_build_dirs ? SEND_BUILD_DIRS : 0);
send_file_names (failed_patches_count, failed_patches, 0);
+ free_names (&failed_patches_count, failed_patches);
}
- failed_patches = NULL;
- failed_patches_count = 0;
-
send_to_server ("update\012", 0);
status = get_responses_and_close ();
@@ -334,13 +346,15 @@ update (argc, argv)
conflict-and-patch-failed case. */
if (status != 0
- && (failed_patches == NULL || pass > 1))
+ && (failed_patches_count == 0 || pass > 1))
{
+ if (failed_patches_count > 0)
+ free_names (&failed_patches_count, failed_patches);
return status;
}
++pass;
- } while (failed_patches != NULL);
+ } while (failed_patches_count > 0);
return 0;
}
@@ -366,15 +380,20 @@ update (argc, argv)
error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
#ifdef SERVER_SUPPORT
if (server_active)
- server_clear_entstat (".", Name_Repository (NULL, NULL));
+ {
+ char *repos = Name_Repository (NULL, NULL);
+ server_clear_entstat (".", repos);
+ free (repos);
+ }
#endif
}
/* keep the CVS/Tag file current with the specified arguments */
if (aflag || tag || date)
{
- WriteTag ((char *) NULL, tag, date, 0,
- ".", Name_Repository (NULL, NULL));
+ char *repos = Name_Repository (NULL, NULL);
+ WriteTag ((char *) NULL, tag, date, 0, ".", repos);
+ free (repos);
rewrite_tag = 1;
nonbranch = 0;
}
@@ -484,17 +503,11 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
argc, argv, local, which, aflag, 1,
preload_update_dir, 1);
- /* see if we need to sleep before returning */
+ /* see if we need to sleep before returning to avoid time-stamp races */
if (last_register_time)
{
- time_t now;
-
- for (;;)
- {
- (void) time (&now);
- if (now != last_register_time) break;
- sleep (1); /* to avoid time-stamp races */
- }
+ while (time ((time_t *) NULL) == last_register_time)
+ sleep (1);
}
return (err);
@@ -641,54 +654,82 @@ update_fileproc (callerdat, finfo)
break;
case T_MODIFIED: /* locally modified */
retval = 0;
- if (vers->ts_conflict)
- {
- char *filestamp;
- int retcode;
+ if (toss_local_changes)
+ {
+ char *bakname;
+ bakname = backup_file (finfo->file, vers->vn_user);
+ /* This behavior is sufficiently unexpected to
+ justify overinformativeness, I think. */
+#ifdef SERVER_SUPPORT
+ if ((! really_quiet) && (! server_active))
+#else /* ! SERVER_SUPPORT */
+ if (! really_quiet)
+#endif /* SERVER_SUPPORT */
+ (void) printf ("(Locally modified %s moved to %s)\n",
+ finfo->file, bakname);
+ free (bakname);
+
+ /* The locally modified file is still present, but
+ it will be overwritten by the repository copy
+ after this. */
+ status = T_CHECKOUT;
+ retval = checkout_file (finfo, vers, 0, 0, 1);
+ }
+ else
+ {
+ if (vers->ts_conflict)
+ {
+ char *filestamp;
+ int retcode;
+
+ /*
+ * If the timestamp has changed and no
+ * conflict indicators are found, it isn't a
+ * 'C' any more.
+ */
- /*
- * If the timestamp has changed and no conflict indicators
- * are found, it isn't a 'C' any more.
- */
#ifdef SERVER_SUPPORT
- if (server_active)
- retcode = vers->ts_conflict[0] != '=';
- else {
- filestamp = time_stamp (finfo->file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
- }
+ if (server_active)
+ retcode = vers->ts_conflict[0] != '=';
+ else
+ {
+ filestamp = time_stamp (finfo->file);
+ retcode = strcmp (vers->ts_conflict, filestamp);
+ free (filestamp);
+ }
#else
- filestamp = time_stamp (finfo->file);
- retcode = strcmp (vers->ts_conflict, filestamp);
- free (filestamp);
+ filestamp = time_stamp (finfo->file);
+ retcode = strcmp (vers->ts_conflict, filestamp);
+ free (filestamp);
#endif
- if (retcode)
- {
- /* The timestamps differ. But if there are conflict
- markers print 'C' anyway. */
- retcode = !file_has_markers (finfo);
- }
-
- if (!retcode)
- {
- write_letter (finfo, 'C');
- retval = 1;
- }
- else
- {
- /* Reregister to clear conflict flag. */
- Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_rcs,
- vers->options, vers->tag,
- vers->date, (char *)0);
- }
- }
- if (!retval)
- {
- write_letter (finfo, 'M');
- retval = 0;
- }
+ if (retcode)
+ {
+ /* The timestamps differ. But if there
+ are conflict markers print 'C' anyway. */
+ retcode = !file_has_markers (finfo);
+ }
+
+ if (!retcode)
+ {
+ write_letter (finfo, 'C');
+ retval = 1;
+ }
+ else
+ {
+ /* Reregister to clear conflict flag. */
+ Register (finfo->entries, finfo->file,
+ vers->vn_rcs, vers->ts_rcs,
+ vers->options, vers->tag,
+ vers->date, (char *)0);
+ }
+ }
+ if (!retval)
+ {
+ write_letter (finfo, 'M');
+ retval = 0;
+ }
+ }
break;
#ifdef SERVER_SUPPORT
case T_PATCH: /* needs patch */
@@ -928,7 +969,8 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
/* This is a guess. We will rewrite it later
via WriteTag. */
0,
- 0);
+ 0,
+ 1);
rewrite_tag = 1;
nonbranch = 0;
Subdir_Register (entries, (char *) NULL, dir);
@@ -1014,6 +1056,10 @@ update_dirleave_proc (callerdat, dir, err, update_dir, entries)
{
FILE *fp;
+ /* Delete the ignore list if it hasn't already been done. */
+ if (ignlist)
+ dellist (&ignlist);
+
/* If we set the tag or date for a new subdirectory in
update_dirent_proc, and we're now done with that subdirectory,
undo the tag/date setting. Note that we know that the tag and
@@ -1059,6 +1105,7 @@ update_dirleave_proc (callerdat, dir, err, update_dir, entries)
cvs_output (": Executing '", 0);
run_print (stdout);
cvs_output ("'\n", 0);
+ cvs_flushout ();
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
}
else if (ferror (fp))
@@ -2049,7 +2096,7 @@ join_file (finfo, vers)
Vers_TS *vers;
{
char *backup;
- char *options;
+ char *t_options;
int status;
char *rev1;
@@ -2284,6 +2331,13 @@ join_file (finfo, vers)
xvers = Version_TS (finfo, vers->options, jrev2, jdate2, 1, 0);
+ /* Reset any keyword expansion option. Otherwise, when a
+ command like `cvs update -kk -jT1 -jT2' creates a new file
+ (because a file had the T2 tag, but not T1), the subsequent
+ commit of that just-added file effectively would set the
+ admin `-kk' option for that file in the repository. */
+ options = NULL;
+
/* FIXME: If checkout_file fails, we should arrange to
return a non-zero exit status. */
status = checkout_file (finfo, xvers, 1, 0, 1);
@@ -2326,11 +2380,11 @@ join_file (finfo, vers)
if (jdate2 != NULL)
error (0, 0,
- "file %s is present in revision %s as of %s",
+ "file %s does not exist, but is present in revision %s as of %s",
finfo->fullname, jrev2, jdate2);
else
error (0, 0,
- "file %s is present in revision %s",
+ "file %s does not exist, but is present in revision %s",
finfo->fullname, jrev2);
/* FIXME: Should we arrange to return a non-zero exit status? */
@@ -2372,10 +2426,10 @@ join_file (finfo, vers)
copy_file (finfo->file, backup);
xchmod (finfo->file, 1);
- options = vers->options;
+ t_options = vers->options;
#if 0
- if (*options == '\0')
- options = "-kk"; /* to ignore keyword expansions */
+ if (*t_options == '\0')
+ t_options = "-kk"; /* to ignore keyword expansions */
#endif
/* If the source of the merge is the same as the working file
@@ -2393,12 +2447,12 @@ join_file (finfo, vers)
/* This is because of the worry below about $Name. If that
isn't a problem, I suspect this code probably works for
text files too. */
- && (strcmp (options, "-kb") == 0
+ && (strcmp (t_options, "-kb") == 0
|| wrap_merge_is_copy (finfo->file)))
{
/* FIXME: what about nametag? What does RCS_merge do with
$Name? */
- if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, options,
+ if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, t_options,
RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
status = 2;
else
@@ -2422,7 +2476,7 @@ join_file (finfo, vers)
print. */
write_letter (finfo, 'U');
}
- else if (strcmp (options, "-kb") == 0
+ else if (strcmp (t_options, "-kb") == 0
|| wrap_merge_is_copy (finfo->file)
|| special_file_mismatch (finfo, rev1, rev2))
{
@@ -2432,7 +2486,7 @@ join_file (finfo, vers)
the two files, and let them resolve it. It is possible
that we should require a "touch foo" or similar step before
we allow a checkin. */
- if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, options,
+ if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, t_options,
RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
status = 2;
else
@@ -2463,7 +2517,7 @@ join_file (finfo, vers)
}
else
status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
- options, rev1, rev2);
+ t_options, rev1, rev2);
if (status != 0 && status != 1)
{
@@ -2494,9 +2548,9 @@ join_file (finfo, vers)
(void) time (&last_register_time);
cp = time_stamp (finfo->file);
}
- Register (finfo->entries, finfo->file, vers->vn_rcs,
- "Result of merge", vers->options, vers->tag,
- vers->date, cp);
+ Register (finfo->entries, finfo->file,
+ vers->vn_rcs ? vers->vn_rcs : "0", "Result of merge",
+ vers->options, vers->tag, vers->date, cp);
if (cp)
free(cp);
}
@@ -2544,8 +2598,8 @@ special_file_mismatch (finfo, rev1, rev2)
dev_t rev1_dev, rev2_dev;
char *rev1_symlink = NULL;
char *rev2_symlink = NULL;
- List *rev1_hardlinks;
- List *rev2_hardlinks;
+ List *rev1_hardlinks = NULL;
+ List *rev2_hardlinks = NULL;
int check_uids, check_gids, check_modes;
int result;
@@ -2574,6 +2628,7 @@ special_file_mismatch (finfo, rev1, rev2)
rev1_symlink = xreadlink (finfo->file);
else
{
+#ifdef HAVE_ST_RDEV
if (CVS_LSTAT (finfo->file, &sb) < 0)
error (1, errno, "could not get file information for %s",
finfo->file);
@@ -2582,6 +2637,10 @@ special_file_mismatch (finfo, rev1, rev2)
rev1_mode = sb.st_mode;
if (S_ISBLK (rev1_mode) || S_ISCHR (rev1_mode))
rev1_dev = sb.st_rdev;
+#else
+ error (1, 0, "cannot handle device files on this system (%s)",
+ finfo->file);
+#endif
}
rev1_hardlinks = list_linked_files_on_disk (finfo->file);
}
@@ -2647,6 +2706,7 @@ special_file_mismatch (finfo, rev1, rev2)
rev2_symlink = xreadlink (finfo->file);
else
{
+#ifdef HAVE_ST_RDEV
if (CVS_LSTAT (finfo->file, &sb) < 0)
error (1, errno, "could not get file information for %s",
finfo->file);
@@ -2655,6 +2715,10 @@ special_file_mismatch (finfo, rev1, rev2)
rev2_mode = sb.st_mode;
if (S_ISBLK (rev2_mode) || S_ISCHR (rev2_mode))
rev2_dev = sb.st_rdev;
+#else
+ error (1, 0, "cannot handle device files on this system (%s)",
+ finfo->file);
+#endif
}
rev2_hardlinks = list_linked_files_on_disk (finfo->file);
}
diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c
index e1ba32d..8d55284 100644
--- a/contrib/cvs/src/vers_ts.c
+++ b/contrib/cvs/src/vers_ts.c
@@ -87,22 +87,17 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
vers_ts->vn_user = xstrdup (entdata->version);
vers_ts->ts_rcs = xstrdup (entdata->timestamp);
vers_ts->ts_conflict = xstrdup (entdata->conflict);
- if (!tag)
+ if (!(tag || date) && !(sdtp && sdtp->aflag))
{
- if (!(sdtp && sdtp->aflag))
- vers_ts->tag = xstrdup (entdata->tag);
- }
- if (!date)
- {
- if (!(sdtp && sdtp->aflag))
- vers_ts->date = xstrdup (entdata->date);
+ vers_ts->tag = xstrdup (entdata->tag);
+ vers_ts->date = xstrdup (entdata->date);
}
vers_ts->entdata = entdata;
}
/* Even if we don't have an "entries line" as such
(vers_ts->entdata), we want to pick up options which could
have been from a Kopt protocol request. */
- if (!options || (options && *options == '\0'))
+ if (!options || *options == '\0')
{
if (!(sdtp && sdtp->aflag))
vers_ts->options = xstrdup (entdata->options);
@@ -126,6 +121,8 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
char *rcsexpand = RCS_getexpand (finfo->rcs);
if (rcsexpand != NULL)
{
+ if (vers_ts->options != NULL)
+ free (vers_ts->options);
vers_ts->options = xmalloc (strlen (rcsexpand) + 3);
strcpy (vers_ts->options, "-k");
strcat (vers_ts->options, rcsexpand);
diff --git a/contrib/cvs/src/version.c b/contrib/cvs/src/version.c
index 97622ff..c8273fb 100644
--- a/contrib/cvs/src/version.c
+++ b/contrib/cvs/src/version.c
@@ -12,7 +12,7 @@
#include "cvs.h"
-char *version_string = "\nConcurrent Versions System (CVS) 1.10.7";
+char *version_string = "Concurrent Versions System (CVS) 1.11";
#ifdef CLIENT_SUPPORT
#ifdef SERVER_SUPPORT
@@ -27,3 +27,49 @@ char *config_string = " (server)\n";
char *config_string = "\n";
#endif
#endif
+
+static const char *const version_usage[] =
+{
+ "Usage: %s %s\n",
+ NULL
+};
+
+int
+version (argc, argv)
+ int argc;
+ char **argv;
+{
+ int err = 0;
+
+ if (argc == -1)
+ usage (version_usage);
+
+#ifdef CLIENT_SUPPORT
+ if (client_active)
+ (void) fputs ("Client: ", stdout);
+#endif
+
+ /* Having the year here is a good idea, so people have
+ some idea of how long ago their version of CVS was
+ released. */
+ (void) fputs (version_string, stdout);
+ (void) fputs (config_string, stdout);
+
+#ifdef CLIENT_SUPPORT
+ if (client_active)
+ {
+ (void) fputs ("Server: ", stdout);
+ start_server ();
+ if (supported_request ("version"))
+ send_to_server ("version\012", 0);
+ else
+ {
+ send_to_server ("noop\012", 0);
+ fputs ("(unknown)\n", stdout);
+ }
+ err = get_responses_and_close ();
+ }
+#endif
+ return err;
+}
+
diff --git a/contrib/cvs/src/watch.c b/contrib/cvs/src/watch.c
index b2935ac..1a0ecfe 100644
--- a/contrib/cvs/src/watch.c
+++ b/contrib/cvs/src/watch.c
@@ -473,6 +473,7 @@ watchers_fileproc (callerdat, finfo)
cvs_output ("\n", 1);
}
out:;
+ free (them);
return 0;
}
diff --git a/contrib/cvs/src/zlib.c b/contrib/cvs/src/zlib.c
index fa0c2ad..3bfc542 100644
--- a/contrib/cvs/src/zlib.c
+++ b/contrib/cvs/src/zlib.c
@@ -467,9 +467,9 @@ gunzip_and_write (fd, fullname, buf, size)
if (buf[3] & 4)
pos += buf[pos] + (buf[pos + 1] << 8) + 2;
if (buf[3] & 8)
- pos += strlen (buf + pos) + 1;
+ pos += strlen ((char *) buf + pos) + 1;
if (buf[3] & 16)
- pos += strlen (buf + pos) + 1;
+ pos += strlen ((char *) buf + pos) + 1;
if (buf[3] & 2)
pos += 2;
OpenPOWER on IntegriCloud