diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 1995-12-29 00:21:27 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 1995-12-29 00:21:27 +0000 |
commit | 68b0ccefa29ef511d016b2612a275db4339311b7 (patch) | |
tree | 587d2022d2beb62842d086593b87a3adcdc7f2d6 | |
parent | 953ce0c6cbfa3957d14efbf17673185d4676530c (diff) |
This commit was manufactured by cvs2svn to create tagvendor/misc-GNU/cvs/1.6.3-951211
'cvs_1_6_3_951211'.
Notes
Notes:
svn path=/vendor/cvs/dist/; revision=13087
svn path=/vendor/cvs/1.6.3-951211/; revision=13089; tag=vendor/misc-GNU/cvs/1.6.3-951211
42 files changed, 0 insertions, 20048 deletions
diff --git a/gnu/usr.bin/cvs/Makefile b/gnu/usr.bin/cvs/Makefile deleted file mode 100644 index d75858bc1e59..000000000000 --- a/gnu/usr.bin/cvs/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIR = lib cvs mkmodules - -.include <bsd.subdir.mk> diff --git a/gnu/usr.bin/cvs/contrib/clmerge b/gnu/usr.bin/cvs/contrib/clmerge deleted file mode 100644 index 1a29311a9c14..000000000000 --- a/gnu/usr.bin/cvs/contrib/clmerge +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/local/bin/perl - -# Merge conflicted ChangeLogs -# tromey Mon Aug 15 1994 - -# Due to popular demand, I'm posting my ChangeLog auto-merge tool. Run -# this on your ChangeLog files when an update leaves them conflicted. -# The code is appended. -# -# Usage is: -# -# cl-merge [-i] file ... -# -# With -i, it works in place (backups put in a ~ file). Otherwise the -# merged ChangeLog is printed to stdout. -# -# Style comments are welcome. This is my third perl program ever. -# -# Please report any bugs to me. I wrote this yesterday, so there are no -# guarantees about its performance. I recommend checking its output -# carefully. If you do send a bug report, please includie the failing -# ChangeLog, so I can include it in my test suite. -# -# Tom -# --- -# tromey@busco.lanl.gov Member, League for Programming Freedom -# Sadism and farce are always inexplicably linked. -# -- Alexander Theroux - -# If '-i' is given, do it in-place. -if ($ARGV[0] eq '-i') { - shift (@ARGV); - $^I = '~'; -} - -$lastkey = ''; -$lastval = ''; -$conf = 0; -%conflist = (); - -$tjd = 0; - -# Simple state machine. The states: -# -# 0 Not in conflict. Just copy input to output. -# 1 Beginning an entry. Next non-blank line is key. -# 2 In entry. Entry beginner transitions to state 1. -while (<>) { - if (/^<<<</ || /^====/) { - # Start of a conflict. - - # Copy last key into array. - if ($lastkey ne '') { - $conflist{$lastkey} = $lastval; - - $lastkey = ''; - $lastval = ''; - } - - $conf = 1; - } elsif (/^>>>>/) { - # End of conflict. Output. - - # Copy last key into array. - if ($lastkey ne '') { - $conflist{$lastkey} = $lastval; - - $lastkey = ''; - $lastval = ''; - } - - foreach (reverse sort clcmp keys %conflist) { - print STDERR "doing $_" if $tjd; - print $_; - print $conflist{$_}; - } - - $lastkey = ''; - $lastval = ''; - $conf = 0; - %conflist = (); - } elsif ($conf == 1) { - # Beginning an entry. Skip empty lines. Error if not a real - # beginner. - if (/^$/) { - # Empty line; just skip at this point. - } elsif (/^[MTWFS]/) { - # Looks like the name of a day; assume opener and move to - # "in entry" state. - $lastkey = $_; - $conf = 2; - print STDERR "found $_" if $tjd; - } else { - die ("conflict crosses entry boundaries: $_"); - } - } elsif ($conf == 2) { - # In entry. Copy into variable until we see beginner line. - if (/^[MTWFS]/) { - # Entry beginner line. - - # Copy last key into array. - if ($lastkey ne '') { - $conflist{$lastkey} = $lastval; - - $lastkey = ''; - $lastval = ''; - } - - $lastkey = $_; - print STDERR "found $_" if $tjd; - $lastval = ''; - } else { - $lastval .= $_; - } - } else { - # Just copy. - print; - } -} - -%months = ('Jan', 0, - 'Feb', 1, - 'Mar', 2, - 'Apr', 3, - 'May', 4, - 'Jun', 5, - 'Jul', 6, - 'Aug', 7, - 'Sep', 8, - 'Oct', 9, - 'Nov', 10, - 'Dec', 11); - -# Compare ChangeLog time strings like <=>. -# -# 0 1 2 3 -# Thu Aug 11 13:22:42 1994 Tom Tromey (tromey@creche.colorado.edu) -# 0123456789012345678901234567890 -# -sub clcmp { - # First check year. - $r = substr ($a, 20, 4) <=> substr ($b, 20, 4); - - # Now check month. - $r = $months{$a} <=> $months{$b} if !$r; - - # Now check day. - $r = substr ($a, 8, 2) <=> substr ($b, 8, 2) if !$r; - - # Now check time (3 parts). - $r = substr ($a, 11, 2) <=> substr ($b, 11, 2) if !$r; - $r = substr ($a, 14, 2) <=> substr ($b, 14, 2) if !$r; - $r = substr ($a, 17, 2) <=> substr ($b, 17, 2) if !$r; - - $r; -} diff --git a/gnu/usr.bin/cvs/contrib/cvscheck b/gnu/usr.bin/cvs/contrib/cvscheck deleted file mode 100644 index 1c66688cbd34..000000000000 --- a/gnu/usr.bin/cvs/contrib/cvscheck +++ /dev/null @@ -1,84 +0,0 @@ -#! /bin/sh -# $Id: cvscheck,v 1.2 1992/04/10 03:04:19 berliner Exp $ -# -# cvscheck - identify files added, changed, or removed -# in CVS working directory -# -# Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net> -# -# This program should be run in a working directory that has been -# checked out using CVS. It identifies files that have been added, -# changed, or removed in the working directory, but not "cvs -# committed". It also determines whether the files have been "cvs -# added" or "cvs removed". For directories, it is only practical to -# determine whether they have been added. - -name=cvscheck -changes=0 - -# If we can't run CVS commands in this directory -cvs status . > /dev/null 2>&1 -if [ $? != 0 ] ; then - - # Bail out - echo "$name: there is no version here; bailing out" 1>&2 - exit 1 -fi - -# Identify files added to working directory -for file in .* * ; do - - # Skip '.' and '..' - if [ $file = '.' -o $file = '..' ] ; then - continue - fi - - # If a regular file - if [ -f $file ] ; then - if cvs status $file | grep -s '^From:[ ]*New file' ; then - echo "file added: $file - not CVS committed" - changes=`expr $changes + 1` - elif cvs status $file | grep -s '^From:[ ]*no entry for' ; then - echo "file added: $file - not CVS added, not CVS committed" - changes=`expr $changes + 1` - fi - - # Else if a directory - elif [ -d $file -a $file != CVS.adm ] ; then - - # Move into it - cd $file - - # If CVS commands don't work inside - cvs status . > /dev/null 2>&1 - if [ $? != 0 ] ; then - echo "directory added: $file - not CVS added" - changes=`expr $changes + 1` - fi - - # Move back up - cd .. - fi -done - -# Identify changed files -changedfiles=`cvs diff | egrep '^diff' | awk '{print $3}'` -for file in $changedfiles ; do - echo "file changed: $file - not CVS committed" - changes=`expr $changes + 1` -done - -# Identify files removed from working directory -removedfiles=`cvs status | egrep '^File:[ ]*no file' | awk '{print $4}'` - -# Determine whether each file has been cvs removed -for file in $removedfiles ; do - if cvs status $file | grep -s '^From:[ ]*-' ; then - echo "file removed: $file - not CVS committed" - else - echo "file removed: $file - not CVS removed, not CVS committed" - fi - changes=`expr $changes + 1` -done - -exit $changes diff --git a/gnu/usr.bin/cvs/contrib/descend b/gnu/usr.bin/cvs/contrib/descend deleted file mode 100644 index 999c46f4f0a8..000000000000 --- a/gnu/usr.bin/cvs/contrib/descend +++ /dev/null @@ -1,116 +0,0 @@ -#! /bin/sh -# $Id: descend,v 1.1 1992/04/03 05:22:52 berliner Exp $ -# -# descend - walk down a directory tree and execute a command at each node - -fullname=$0 -name=descend -usage="Usage: $name [-afqrv] command [directory ...]\n -\040\040-a\040\040All: descend into directories starting with '.'\n -\040\040-f\040\040Force: ignore errors during descent\n -\040\040-q\040\040Quiet: don't print directory names\n -\040\040-r\040\040Restricted: don't descend into RCS, CVS.adm, SCCS directories\n -\040\040-v\040\040Verbose: print command before executing it" - -# Scan for options -while getopts afqrv option; do - case $option in - a) - alldirs=$option - options=$options" "-$option - ;; - f) - force=$option - options=$options" "-$option - ;; - q) - verbose= - quiet=$option - options=$options" "-$option - ;; - r) - restricted=$option - options=$options" "-$option - ;; - v) - verbose=$option - quiet= - options=$options" "-$option - ;; - \?) - /usr/5bin/echo $usage 1>&2 - exit 1 - ;; - esac -done -shift `expr $OPTIND - 1` - -# Get command to execute -if [ $# -lt 1 ] ; then - /usr/5bin/echo $usage 1>&2 - exit 1 -else - command=$1 - shift -fi - -# If no directory specified, use '.' -if [ $# -lt 1 ] ; then - default_dir=. -fi - -# For each directory specified -for dir in $default_dir "$@" ; do - - # Spawn sub-shell so we return to starting directory afterward - (cd $dir - - # Execute specified command - if [ -z "$quiet" ] ; then - echo In directory `hostname`:`pwd` - fi - if [ -n "$verbose" ] ; then - echo $command - fi - eval "$command" || if [ -z "$force" ] ; then exit 1; fi - - # Collect dot file names if necessary - if [ -n "$alldirs" ] ; then - dotfiles=.* - else - dotfiles= - fi - - # For each file in current directory - for file in $dotfiles * ; do - - # Skip '.' and '..' - if [ "$file" = "." -o "$file" = ".." ] ; then - continue - fi - - # If a directory but not a symbolic link - if [ -d "$file" -a ! -h "$file" ] ; then - - # If not skipping this type of directory - if [ \( "$file" != "RCS" -a \ - "$file" != "SCCS" -a \ - "$file" != "CVS" -a \ - "$file" != "CVS.adm" \) \ - -o -z "$restricted" ] ; then - - # Recursively descend into it - $fullname $options "$command" "$file" \ - || if [ -z "$force" ] ; then exit 1; fi - fi - - # Else if a directory AND a symbolic link - elif [ -d "$file" -a -h "$file" ] ; then - - if [ -z "$quiet" ] ; then - echo In directory `hostname`:`pwd`/$file: symbolic link: skipping - fi - fi - done - ) || if [ -z "$force" ] ; then exit 1; fi -done diff --git a/gnu/usr.bin/cvs/contrib/dirfns b/gnu/usr.bin/cvs/contrib/dirfns deleted file mode 100644 index 8324c4198e35..000000000000 --- a/gnu/usr.bin/cvs/contrib/dirfns +++ /dev/null @@ -1,481 +0,0 @@ -echo 'directory.3': -sed 's/^X//' >'directory.3' <<'!' -X.TH DIRECTORY 3 imported -X.DA 9 Oct 1985 -X.SH NAME -Xopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level directory operations -X.SH SYNOPSIS -X.B #include <sys/types.h> -X.br -X.B #include <ndir.h> -X.PP -X.SM -X.B DIR -X.B *opendir(filename) -X.br -X.B char *filename; -X.PP -X.SM -X.B struct direct -X.B *readdir(dirp) -X.br -X.B DIR *dirp; -X.PP -X.SM -X.B long -X.B telldir(dirp) -X.br -X.B DIR *dirp; -X.PP -X.SM -X.B seekdir(dirp, loc) -X.br -X.B DIR *dirp; -X.br -X.B long loc; -X.PP -X.SM -X.B rewinddir(dirp) -X.br -X.B DIR *dirp; -X.PP -X.SM -X.B closedir(dirp) -X.br -X.B DIR *dirp; -X.SH DESCRIPTION -XThis library provides high-level primitives for directory scanning, -Xsimilar to those available for 4.2BSD's (very different) directory system. -X.\"The purpose of this library is to simulate -X.\"the new flexible length directory names of 4.2bsd UNIX -X.\"on top of the old directory structure of v7. -XIt incidentally provides easy portability to and from 4.2BSD (insofar -Xas such portability is not compromised by other 4.2/VAX dependencies). -X.\"It allows programs to be converted immediately -X.\"to the new directory access interface, -X.\"so that they need only be relinked -X.\"when moved to 4.2bsd. -X.\"It is obtained with the loader option -X.\".BR \-lndir . -X.PP -X.I Opendir -Xopens the directory named by -X.I filename -Xand associates a -X.I directory stream -Xwith it. -X.I Opendir -Xreturns a pointer to be used to identify the -X.I directory stream -Xin subsequent operations. -XThe pointer -X.SM -X.B NULL -Xis returned if -X.I filename -Xcannot be accessed or is not a directory. -X.PP -X.I Readdir -Xreturns a pointer to the next directory entry. -XIt returns -X.B NULL -Xupon reaching the end of the directory or detecting -Xan invalid -X.I seekdir -Xoperation. -X.PP -X.I Telldir -Xreturns the current location associated with the named -X.I directory stream. -X.PP -X.I Seekdir -Xsets the position of the next -X.I readdir -Xoperation on the -X.I directory stream. -XThe new position reverts to the one associated with the -X.I directory stream -Xwhen the -X.I telldir -Xoperation was performed. -XValues returned by -X.I telldir -Xare good only for the lifetime of the DIR pointer from -Xwhich they are derived. -XIf the directory is closed and then reopened, -Xthe -X.I telldir -Xvalue may be invalidated -Xdue to undetected directory compaction in 4.2BSD. -XIt is safe to use a previous -X.I telldir -Xvalue immediately after a call to -X.I opendir -Xand before any calls to -X.I readdir. -X.PP -X.I Rewinddir -Xresets the position of the named -X.I directory stream -Xto the beginning of the directory. -X.PP -X.I Closedir -Xcauses the named -X.I directory stream -Xto be closed, -Xand the structure associated with the DIR pointer to be freed. -X.PP -XA -X.I direct -Xstructure is as follows: -X.PP -X.RS -X.nf -Xstruct direct { -X /* unsigned */ long d_ino; /* inode number of entry */ -X unsigned short d_reclen; /* length of this record */ -X unsigned short d_namlen; /* length of string in d_name */ -X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ -X}; -X.fi -X.RE -X.PP -XThe -X.I d_reclen -Xfield is meaningless in non-4.2BSD systems and should be ignored. -XThe use of a -X.I long -Xfor -X.I d_ino -Xis also a 4.2BSDism; -X.I ino_t -X(see -X.IR types (5)) -Xshould be used elsewhere. -XThe macro -X.I DIRSIZ(dp) -Xgives the minimum memory size needed to hold the -X.I direct -Xvalue pointed to by -X.IR dp , -Xwith the minimum necessary allocation for -X.IR d_name . -X.PP -XThe preferred way to search the current directory for entry ``name'' is: -X.PP -X.RS -X.nf -X len = strlen(name); -X dirp = opendir("."); -X if (dirp == NULL) { -X fprintf(stderr, "%s: can't read directory .\\n", argv[0]); -X return NOT_FOUND; -X } -X while ((dp = readdir(dirp)) != NULL) -X if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) { -X closedir(dirp); -X return FOUND; -X } -X closedir(dirp); -X return NOT_FOUND; -X.RE -X.\".SH LINKING -X.\"This library is accessed by specifying ``-lndir'' as the -X.\"last argument to the compile line, e.g.: -X.\".PP -X.\" cc -I/usr/include/ndir -o prog prog.c -lndir -X.SH "SEE ALSO" -Xopen(2), -Xclose(2), -Xread(2), -Xlseek(2) -X.SH HISTORY -XWritten by -XKirk McKusick at Berkeley (ucbvax!mckusick). -XMiscellaneous bug fixes from elsewhere. -XThe size of the data structure has been decreased to avoid excessive -Xspace waste under V7 (where filenames are 14 characters at most). -XFor obscure historical reasons, the include file is also available -Xas -X.IR <ndir/sys/dir.h> . -XThe Berkeley version lived in a separate library (\fI\-lndir\fR), -Xwhereas ours is -Xpart of the C library, although the separate library is retained to -Xmaximize compatibility. -X.PP -XThis manual page has been substantially rewritten to be informative in -Xthe absence of a 4.2BSD manual. -X.SH BUGS -XThe -X.I DIRSIZ -Xmacro actually wastes a bit of space due to some padding requirements -Xthat are an artifact of 4.2BSD. -X.PP -XThe returned value of -X.I readdir -Xpoints to a static area that will be overwritten by subsequent calls. -X.PP -XThere are some unfortunate name conflicts with the \fIreal\fR V7 -Xdirectory structure definitions. -! -echo 'dir.h': -sed 's/^X//' >'dir.h' <<'!' -X/* dir.h 4.4 82/07/25 */ -X -X/* -X * A directory consists of some number of blocks of DIRBLKSIZ -X * bytes, where DIRBLKSIZ is chosen such that it can be transferred -X * to disk in a single atomic operation (e.g. 512 bytes on most machines). -X * -X * Each DIRBLKSIZ byte block contains some number of directory entry -X * structures, which are of variable length. Each directory entry has -X * a struct direct at the front of it, containing its inode number, -X * the length of the entry, and the length of the name contained in -X * the entry. These are followed by the name padded to a 4 byte boundary -X * with null bytes. All names are guaranteed null terminated. -X * The maximum length of a name in a directory is MAXNAMLEN. -X * -X * The macro DIRSIZ(dp) gives the amount of space required to represent -X * a directory entry. Free space in a directory is represented by -X * entries which have dp->d_reclen >= DIRSIZ(dp). All DIRBLKSIZ bytes -X * in a directory block are claimed by the directory entries. This -X * usually results in the last entry in a directory having a large -X * dp->d_reclen. When entries are deleted from a directory, the -X * space is returned to the previous entry in the same directory -X * block by increasing its dp->d_reclen. If the first entry of -X * a directory block is free, then its dp->d_ino is set to 0. -X * Entries other than the first in a directory do not normally have -X * dp->d_ino set to 0. -X */ -X#define DIRBLKSIZ 512 -X#ifdef VMUNIX -X#define MAXNAMLEN 255 -X#else -X#define MAXNAMLEN 14 -X#endif -X -Xstruct direct { -X /* unsigned */ long d_ino; /* inode number of entry */ -X unsigned short d_reclen; /* length of this record */ -X unsigned short d_namlen; /* length of string in d_name */ -X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ -X}; -X -X/* -X * The DIRSIZ macro gives the minimum record length which will hold -X * the directory entry. This requires the amount of space in struct direct -X * without the d_name field, plus enough space for the name with a terminating -X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. -X */ -X#undef DIRSIZ -X#define DIRSIZ(dp) \ -X ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) -X -X#ifndef KERNEL -X/* -X * Definitions for library routines operating on directories. -X */ -Xtypedef struct _dirdesc { -X int dd_fd; -X long dd_loc; -X long dd_size; -X char dd_buf[DIRBLKSIZ]; -X} DIR; -X#ifndef NULL -X#define NULL 0 -X#endif -Xextern DIR *opendir(); -Xextern struct direct *readdir(); -Xextern long telldir(); -X#ifdef void -Xextern void seekdir(); -Xextern void closedir(); -X#endif -X#define rewinddir(dirp) seekdir((dirp), (long)0) -X#endif KERNEL -! -echo 'makefile': -sed 's/^X//' >'makefile' <<'!' -XDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o -XCFLAGS=-O -I. -Dvoid=int -XDEST=.. -X -Xall: $(DIR) -X -Xmv: $(DIR) -X mv $(DIR) $(DEST) -X -Xcpif: dir.h -X cp dir.h /usr/include/ndir.h -X -Xclean: -X rm -f *.o -! -echo 'closedir.c': -sed 's/^X//' >'closedir.c' <<'!' -Xstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82"; -X -X#include <sys/types.h> -X#include <dir.h> -X -X/* -X * close a directory. -X */ -Xvoid -Xclosedir(dirp) -X register DIR *dirp; -X{ -X close(dirp->dd_fd); -X dirp->dd_fd = -1; -X dirp->dd_loc = 0; -X free((char *)dirp); -X} -! -echo 'opendir.c': -sed 's/^X//' >'opendir.c' <<'!' -X/* Copyright (c) 1982 Regents of the University of California */ -X -Xstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82"; -X -X#include <sys/types.h> -X#include <sys/stat.h> -X#include <dir.h> -X -X/* -X * open a directory. -X */ -XDIR * -Xopendir(name) -X char *name; -X{ -X register DIR *dirp; -X register int fd; -X struct stat statbuf; -X char *malloc(); -X -X if ((fd = open(name, 0)) == -1) -X return NULL; -X if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) { -X close(fd); -X return NULL; -X } -X if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) { -X close (fd); -X return NULL; -X } -X dirp->dd_fd = fd; -X dirp->dd_loc = 0; -X dirp->dd_size = 0; /* so that telldir will work before readdir */ -X return dirp; -X} -! -echo 'readdir.c': -sed 's/^X//' >'readdir.c' <<'!' -X/* Copyright (c) 1982 Regents of the University of California */ -X -Xstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82"; -X -X#include <sys/types.h> -X#include <dir.h> -X -X/* -X * read an old stlye directory entry and present it as a new one -X */ -X#define ODIRSIZ 14 -X -Xstruct olddirect { -X ino_t od_ino; -X char od_name[ODIRSIZ]; -X}; -X -X/* -X * get next entry in a directory. -X */ -Xstruct direct * -Xreaddir(dirp) -X register DIR *dirp; -X{ -X register struct olddirect *dp; -X static struct direct dir; -X -X for (;;) { -X if (dirp->dd_loc == 0) { -X dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, -X DIRBLKSIZ); -X if (dirp->dd_size <= 0) { -X dirp->dd_size = 0; -X return NULL; -X } -X } -X if (dirp->dd_loc >= dirp->dd_size) { -X dirp->dd_loc = 0; -X continue; -X } -X dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc); -X dirp->dd_loc += sizeof(struct olddirect); -X if (dp->od_ino == 0) -X continue; -X dir.d_ino = dp->od_ino; -X strncpy(dir.d_name, dp->od_name, ODIRSIZ); -X dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */ -X dir.d_namlen = strlen(dir.d_name); -X dir.d_reclen = DIRBLKSIZ; -X return (&dir); -X } -X} -! -echo 'seekdir.c': -sed 's/^X//' >'seekdir.c' <<'!' -Xstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83"; -X -X#include <sys/param.h> -X#include <dir.h> -X -X/* -X * seek to an entry in a directory. -X * Only values returned by "telldir" should be passed to seekdir. -X */ -Xvoid -Xseekdir(dirp, loc) -X register DIR *dirp; -X long loc; -X{ -X long curloc, base, offset; -X struct direct *dp; -X extern long lseek(); -X -X curloc = telldir(dirp); -X if (loc == curloc) -X return; -X base = loc & ~(DIRBLKSIZ - 1); -X offset = loc & (DIRBLKSIZ - 1); -X (void) lseek(dirp->dd_fd, base, 0); -X dirp->dd_size = 0; -X dirp->dd_loc = 0; -X while (dirp->dd_loc < offset) { -X dp = readdir(dirp); -X if (dp == NULL) -X return; -X } -X} -! -echo 'telldir.c': -sed 's/^X//' >'telldir.c' <<'!' -Xstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82"; -X -X#include <sys/types.h> -X#include <dir.h> -X -X/* -X * return a pointer into a directory -X */ -Xlong -Xtelldir(dirp) -X DIR *dirp; -X{ -X long lseek(); -X -X return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc); -X} -! -echo done diff --git a/gnu/usr.bin/cvs/contrib/easy-import.perl b/gnu/usr.bin/cvs/contrib/easy-import.perl deleted file mode 100644 index 59d407a913d1..000000000000 --- a/gnu/usr.bin/cvs/contrib/easy-import.perl +++ /dev/null @@ -1,365 +0,0 @@ -#!/usr/bin/perl -# -# Support for importing a source collection into CVS. -# Tries to prevent the user from the most common pitfalls (like creating -# new top-level repositories or second-level areas accidentally), and -# cares to do some of the `dirty' work like maintaining the modules -# database accordingly. -# -# Written by Jörg Wunsch, 95/03/07, and placed in the public domain. -# - -require "complete.pl"; -require "getopts.pl"; - - -sub scan_opts -{ - &Getopts("n"); - - $dont_do_it = "-n" if $opt_n; - - die "usage: $0 [-n] [moduledir]\n" . - " -n: don't do any commit, show only\n" - unless $#ARGV <= 0; - - $moduledir = $ARGV[0] if $#ARGV == 0; -} - -sub lsdir -{ - # find all subdirectories under @_ - # ignore all CVS entries, dot entries, and non-directories - - local($base) = @_; - local(@ls, @rv, $fname); - - opendir(DIR, $base) || die "Cannot find dir $base.\n"; - - @ls = readdir(DIR); - closedir(DIR); - - @rv = (); - - foreach $fname (@ls) { - next if $fname =~ /^CVS/ || $fname eq "Attic" - || $fname =~ /^\./ || ! -d "$base/$fname"; - @rv = (@rv, $fname); - } - - return sort(@rv); -} - - -sub contains -{ - # look if the first parameter is contained in the list following it - local($item, @list) = @_; - local($found, $i); - - $found = 0; - foreach $i (@list) { - return 1 if $i eq $item; - } - return 0; -} - - - -sub term_init -{ - # first, get some terminal attributes - - # try bold mode first - $so = `tput md`; $se = `tput me`; - - # if no bold mode available, use standout mode - if ($so eq "") { - $so = `tput so`; $se = `tput se`; - } - - # try if we can underscore - $us = `tput us`; $ue = `tput ue`; - # if we don't have it available, or same as bold/standout, disable it - if ($us eq "" || $us eq $so) { - $us = $ue = ""; - } - - # look how many columns we've got - if($ENV{'COLUMNS'} ne "") { - $columns = $ENV{'COLUMNS'}; - } elsif(-t STDIN) { # if we operate on a terminal... - local($word, $tmp); - - open(STTY, "stty -a|"); - $_ = <STTY>; # try getting the tty win structure value - close(STTY); - chop; - $columns = 0; - foreach $word (split) { - $columns = $tmp if $word eq "columns;"; # the number preceding - $tmp = $word; - } - } else { - $columns = 80; - } - # sanity - $columns = 80 unless $columns >= 5; -} - - -sub list -{ - # pretty-print a list - # imports: global variable $columns - local(@items) = @_; - local($longest,$i,$item,$cols,$width); - - # find the longest item - $longest = 0; - foreach $item (@items) { - $i = length($item); - $longest = $i if $longest < $i; - } - $width = $longest + 1; - $cols = int($columns / $width); - - $i = 0; - foreach $item (@items) { - print $item; - if(++$i == $cols) { - $i = 0; print "\n"; - } else { - print ' ' x ($width - length($item)); - } - } - print "\n" unless $i == 0; -} - -sub cvs_init -{ - # get the CVS repository(s) - - die "You need to have the \$CVSROOT variable set.\n" - unless $ENV{'CVSROOT'} ne ""; - - # get the list of available repositories - $cvsroot = $ENV{'CVSROOT'}; - @reps = &lsdir($cvsroot); -} - - -sub lsmodules -{ - # list all known CVS modules - local(@rv, $mname, $_); - - @rv = (); - - open(CVS, "cvs co -c|"); - while($_ = <CVS>) { - chop; - ($mname) = split; - next if $mname eq ""; - @rv = (@rv, $mname); - } - close(CVS); - - return @rv; -} - - -sub checktag -{ - # check a given string for tag rules - local($s) = @_; - return 0 if($s !~ /^[A-Za-z][A-Za-z0-9_]*$/); - - return 1; -} - - -&scan_opts; -&term_init; -&cvs_init; - -if(! $moduledir) { - @dirs = &lsdir("."); - print "${so}Import from which directory?${se}\n"; - @dirs = (@dirs, "."); - &list(@dirs); - $moduledir = &Complete("Which? [.]: ", @dirs); - $moduledir = "." unless $moduledir ne ""; -} - -chdir $moduledir || die "Cannot chdir to $moduledir\n"; - -print "${so}Available repositories:${se}\n"; -&list(@reps); - -# the following kludge prevents the Complete package from starting -# over with the string just selected; Complete should better provide -# some reinitialize method -$Complete'return = ""; $Complete'r = 0; - -$selected = - &Complete("Enter repository (<TAB>=complete, ^D=show): ", - @reps); - -die "\aYou cannot create new repositories with this script.\n" - unless &contains($selected, @reps); - -$rep = $selected; - -print "\n${so}Selected repository:${se} ${us}$rep${ue}\n"; - - -@areas = &lsdir("$cvsroot/$rep"); - -print "${so}Existent areas in this repository:${se}\n"; -&list(@areas); - -$Complete'return = ""; $Complete'r = 0; - -$selected = - &Complete("Enter area name (<TAB>=complete, ^D=show): ", - @areas); - -print "\a${us}Warning: this will create a new area.${ue}\n" - unless &contains($selected, @areas); - -$area = "$rep/$selected"; - -print "\n${so}[Working on:${se} ${us}$area${ue}${so}]${se}\n"; - -for(;;) { - $| = 1; - print "${so}Enter the module path:${se} $area/"; - $| = 0; - $modpath = <>; - chop $modpath; - if ($modpath eq "") { - print "\a${us}You cannot use an empty module path.${ue}\n"; - next; - } - last if ! -d "$cvsroot/$area/$modpath"; - print "\a${us}This module path does already exist; " . - "choose another one.${ue}\n"; -} - - -@newdirs = (); -$dir1 = "$cvsroot/$area"; -$dir2 = "$area"; - -@newdirs = (@newdirs, "$dir2") if ! -d $dir1; - -foreach $ele (split(/\//, $modpath)) { - $dir1 = "$dir1/$ele"; - $dir2 = "$dir2/$ele"; - @newdirs = (@newdirs, "$dir2") if ! -d $dir1; -} - -print "${so}You're going to create the following new directories:${se}\n"; - -&list(@newdirs); - -@cvsmods = &lsmodules(); - -for(;;) { - $| = 1; - print "${so}Gimme the module name:${se} "; - $| = 0; - $modname = <>; - chop $modname; - if ($modname eq "") { - print "\a${us}You cannot use an empty module name.${ue}\n"; - next; - } - last if !&contains($modname, @cvsmods); - print "\a${us}This module name does already exist; " . - "choose another one.${ue}\n"; -} - - -for(;;) { - $| = 1; - print "${so}Enter a \`vendor\' tag (e. g. the authors ID):${se} "; - $| = 0; - $vtag = <>; - chop $vtag; - last if &checktag($vtag); - print "\a${us}Valid tags must match the regexp " . - "^[A-Za-z][A-Za-z0-9_]*\$.${ue}\n"; -} - -for(;;) { - $| = 1; - print "${so}Enter a \`release\' tag (e. g. the version #):${se} "; - $| = 0; - $rtag = <>; - chop $rtag; - last if &checktag($rtag); - print "\a${us}Valid tags must match the regexp " . - "^[A-Za-z][A-Za-z0-9_]*\$.${ue}\n"; -} - - -$| = 1; -print "${so}This is your last chance to interrupt, " . - "hit <return> to go on:${se} "; -$| = 0; -<>; - -$mod = ""; -foreach $tmp (@cvsmods) { - if($tmp gt $modname) { - $mod = $tmp; - last; - } -} - -if($mod eq "") { - # we are going to append our module - $cmd = "\$\na\n"; -} else { - # we can insert it - $cmd = "/^${mod}[ \t]/\ni\n"; -} - -print "${so}Checking out the modules database...${se}\n"; -system("cvs co modules") && die "${us}failed.\n${ue}"; - -print "${so}Inserting new module...${se}\n"; -open(ED, "|ed modules/modules") || die "${us}Cannot start ed${ue}\n"; -print(ED "${cmd}${modname}" . ' ' x (16 - length($modname)) . - "$area/${modpath}\n.\nw\nq\n"); -close(ED); - -print "${so}Commiting new modules database...${se}\n"; -system("cvs $dont_do_it commit -m \" " . - "${modname} --> $area/${modpath}\" modules") - && die "Commit failed\n"; - -system("cvs $dont_do_it release -dQ modules"); - -print "${so}Importing source. Enter a commit message in the editor.${se}\n"; - -system("cvs $dont_do_it import $area/$modpath $vtag $rtag"); - -print "${so}You are done now. Go to a different directory, perform a${se}\n". - "${us}cvs co ${modname}${ue} ${so}command, and see if your new module" . - " builds ok.${se}\n"; - -if($dont_do_it) { -print <<END - - -${so}Since you did not allow to commit anything, you'll have${se} -${so}to remove the edited modules' database yourself.${se} -${so}To do this, perform a${se} -${us}cd ${moduledir}; cvs release -dQ modules${ue} -${so}command.${se} -END -; -} diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/Makefile b/gnu/usr.bin/cvs/contrib/pcl-cvs/Makefile deleted file mode 100644 index 7f6f5b118a69..000000000000 --- a/gnu/usr.bin/cvs/contrib/pcl-cvs/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -# @(#) Id: dist-makefile,v 1.19 1993/05/31 22:43:45 ceder Exp -# Makefile for pcl-cvs release 1.05. -# Copyright (C) 1992, 1993 Per Cederqvist -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -# This is the directory in which the ELFILES and ELCFILES will be -# installed. - -lispdir = /usr/local/lib/elisp - -# Where to install the info file. - -prefix=/usr/local -infodir = $(prefix)/info - -# Used to byte-compile files. - -EMACS=emacs - -# -# The rest of this file should not need to be modified. -# - -# Just in case... -SHELL = /bin/sh - -ELFILES = pcl-cvs.el pcl-cvs-lucid.el -ELCFILES = pcl-cvs.elc pcl-cvs-lucid.elc -INFOFILES = pcl-cvs -TEXTMPS = pcl-cvs.aux pcl-cvs.log pcl-cvs.toc pcl-cvs.dvi pcl-cvs.cp \ - pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky pcl-cvs.pg \ - pcl-cvs.cps pcl-cvs.fns pcl-cvs.kys pcl-cvs.pgs pcl-cvs.tps \ - pcl-cvs.vrs - -INSTALL = install -INSTALL_DATA = $(INSTALL) - -elcfiles: - $(EMACS) -batch -l ./compile-all.el -f compile-pcl-cvs - -all: elcfiles info - -# Don't install the info file yet, since it requires makeinfo -# version 2.something (and version 1.something is distributed with emacs). -# -# install: install_elc install_info -install: install_elc - for i in $(ELFILES); do $(INSTALL_DATA) $$i $(lispdir)/$$i; done - -install_elc: elcfiles - for i in $(ELCFILES); do $(INSTALL_DATA) $$i $(lispdir)/$$i; done - -install_info: pcl-cvs - $(INSTALL_DATA) pcl-cvs $(infodir)/pcl-cvs - -info pcl-cvs: pcl-cvs.texinfo - makeinfo +fill-column=70 pcl-cvs.texinfo - -pcl-cvs.dvi: pcl-cvs.texinfo - tex pcl-cvs.texinfo - tex pcl-cvs.texinfo - -texindex pcl-cvs.cp pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky \ - pcl-cvs.pg - tex pcl-cvs.texinfo - -mostlyclean clean realclean: - rm -f *~ core $(ELCFILES) $(INFOFILES) $(TEXTMPS) - -tags TAGS: - etags *.el diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el deleted file mode 100644 index 8bd4bdff6ce0..000000000000 --- a/gnu/usr.bin/cvs/contrib/pcl-cvs/cookie.el +++ /dev/null @@ -1,884 +0,0 @@ -;;; cookie.el,v 1.2 1992/04/07 20:49:12 berliner Exp -;;; cookie.el -- Utility to display cookies in buffers -;;; Copyright (C) 1991, 1992 Per Cederqvist -;;; -;;; This program is free software; you can redistribute it and/or modify -;;; it under the terms of the GNU General Public License as published by -;;; the Free Software Foundation; either version 2 of the License, or -;;; (at your option) any later version. -;;; -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;; GNU General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program; if not, write to the Free Software -;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -;;;; TO-DO: Byt namn! tin -> wrapper (eller n}got b{ttre). - -;;; Note that this file is still under development. Comments, -;;; enhancements and bug fixes are welcome. -;;; Send them to ceder@lysator.liu.se. - -(defun impl nil (error "Not yet implemented!")) - -;;; Cookie is a package that imlements a connection between an -;;; elib-dll and the contents of a buffer. Possible uses are dired -;;; (have all files in a list, and show them), buffer-list, -;;; kom-prioritize (in the LysKOM elisp client) and others. pcl-cvs.el -;;; uses cookie.el. -;;; -;;; A cookie buffer contains a header, any number of cookies, and a -;;; footer. The header and footer are constant strings that are given -;;; to cookie-create when the buffer is placed under cookie. Each cookie -;;; is displayed in the buffer by calling a user-supplied function -;;; that takes a cookie and returns a string. The string may be -;;; empty, or contain any number of lines. An extra newline is always -;;; appended unless the string is empty. -;;; -;;; Cookie does not affect the mode of the buffer in any way. It -;;; merely makes it easy to connect an underlying data representation -;;; to the buffer contents. -;;; -;;; The cookie-node data type: -;;; start-marker -;;; ;; end-marker This field is no longer present. -;;; cookie The user-supplied element. -;;; -;;; A dll of cookie-nodes are held in the buffer local variable -;;; cake-tin. -;;; -;;; A tin is an object that contains one cookie. You can get the next -;;; and previous tin. -;;; - -(require 'elib-dll) -(provide 'cookie) - -(defvar cookies nil - "A doubly linked list that contains the underlying data representation -for the contents of a cookie buffer. The package elib-dll is used to -manipulate this list.") - -(defvar cookie-pretty-printer nil - "The function that is used to pretty-print a cookie in this buffer.") - -(defvar cookie-header nil - "The tin that holds the header cookie.") - -(defvar cookie-footer nil - "The tin that holds the footer cookie.") - -(defvar cookie-last-tin nil - "The tin the cursor was positioned at, the last time the cookie -package checked the cursor position. Buffer local in all buffers -the cookie package works on. You may set this if your package -thinks it knows where the cursor will be the next time this -package is called. It can speed things up. - -It must never be set to a tin that has been deleted.") - -;;; ================================================================ -;;; Internal functions for use in the cookie package - -(put 'cookie-set-buffer 'lisp-indent-hook 1) - -(defmacro cookie-set-buffer (buffer &rest forms) - - ;; Execute FORMS with BUFFER selected as current buffer. - ;; Return value of last form in FORMS. INTERNAL USE ONLY. - - (let ((old-buffer (make-symbol "old-buffer"))) - (` (let (((, old-buffer) (current-buffer))) - (set-buffer (get-buffer-create (, buffer))) - (unwind-protect - (progn (,@ forms)) - (set-buffer (, old-buffer))))))) - - -(defmacro cookie-filter-hf (tin) - - ;; Evaluate TIN once and return it. BUT if it is - ;; equal to cookie-header or cookie-footer return nil instead. - ;; INTERNAL USE ONLY. - - (let ((tempvar (make-symbol "tin"))) - (` (let (((, tempvar) (, tin))) - (if (or (eq (, tempvar) cookie-header) - (eq (, tempvar) cookie-footer)) - nil - (, tempvar)))))) - - -;;; cookie-tin -;;; Constructor: - -(defun cookie-create-tin (start-marker - cookie) - ;; Create a tin. INTERNAL USE ONLY. - (cons 'COOKIE-TIN (vector start-marker nil cookie))) - - -;;; Selectors: - -(defun cookie-tin-start-marker (cookie-tin) - ;; Get start-marker from cookie-tin. INTERNAL USE ONLY. - (elt (cdr cookie-tin) 0)) - -;(defun cookie-tin-end-marker (cookie-tin) -; ;;Get end-marker from cookie-tin. INTERNAL USE ONLY. -; (elt (cdr cookie-tin) 1)) - -(defun cookie-tin-cookie-safe (cookie-tin) - ;; Get cookie from cookie-tin. INTERNAL USE ONLY. - ;; Returns nil if given nil as input. - ;; This is the same as cookie-tin-cookie in version 18.57 - ;; of emacs, but elt should signal an error when given nil - ;; as input (according to the info files). - (elt (cdr cookie-tin) 2)) - -(defun cookie-tin-cookie (cookie-tin) - ;; Get cookie from cookie-tin. INTERNAL USE ONLY. - (elt (cdr cookie-tin) 2)) - - -;;; Modifiers: - -(defun set-cookie-tin-start-marker (cookie-tin newval) - ;; Set start-marker in cookie-tin to NEWVAL. INTERNAL USE ONLY. - (aset (cdr cookie-tin) 0 newval)) - -;(defun set-cookie-tin-end-marker (cookie-tin newval) -; ;; Set end-marker in cookie-tin to NEWVAL. INTERNAL USE ONLY. -; (aset (cdr cookie-tin) 1 newval)) - -(defun set-cookie-tin-cookie (cookie-tin newval) - ;; Set cookie in cookie-tin to NEWVAL. INTERNAL USE ONLY. - (aset (cdr cookie-tin) 2 newval)) - - - -;;; Predicate: - -(defun cookie-tin-p (object) - ;; Return t if OBJECT is a tin. INTERNAL USE ONLY. - (eq (car-safe object) 'COOKIE-TIN)) - -;;; end of cookie-tin data type. - - -(defun cookie-create-tin-and-insert (cookie string pos) - ;; Insert STRING at POS in current buffer. Remember start - ;; position. Create a tin containing them and the COOKIE. - ;; INTERNAL USE ONLY. - - (save-excursion - (goto-char pos) - ;; Remember the position as a number so that it doesn't move - ;; when we insert the string. - (let ((start (if (markerp pos) - (marker-position pos) - pos))) - ;; Use insert-before-markers so that the marker for the - ;; next cookie is updated. - (insert-before-markers string) - (insert-before-markers ?\n) - (cookie-create-tin (copy-marker start) cookie)))) - - -(defun cookie-delete-tin-internal (tin) - ;; Delete a cookie from the buffer. INTERNAL USE ONLY. - ;; Can not be used on the footer. - (delete-region (cookie-tin-start-marker (dll-element cookies tin)) - (cookie-tin-start-marker - (dll-element cookies - (dll-next cookies tin))))) - - - -(defun cookie-refresh-tin (tin) - ;; Redisplay the cookie represented by TIN. INTERNAL USE ONLY. - ;; Can not be used on the footer. - - (save-excursion - ;; First, remove the string: - (delete-region (cookie-tin-start-marker (dll-element cookies tin)) - (1- (marker-position - (cookie-tin-start-marker - (dll-element cookies - (dll-next cookies tin)))))) - - ;; Calculate and insert the string. - - (goto-char (cookie-tin-start-marker (dll-element cookies tin))) - (insert - (funcall cookie-pretty-printer - (cookie-tin-cookie (dll-element cookies tin)))))) - - -;;; ================================================================ -;;; The public members of the cookie package - - -(defun cookie-cookie (buffer tin) - "Get the cookie from a TIN. Args: BUFFER TIN." - (cookie-set-buffer buffer - (cookie-tin-cookie (dll-element cookies tin)))) - - - - -(defun cookie-create (buffer pretty-printer &optional header footer) - - "Start to use the cookie package in BUFFER. -BUFFER may be a buffer or a buffer name. It is created if it does not exist. -Beware that the entire contents of the buffer will be erased. -PRETTY-PRINTER is a function that takes one cookie and returns a string -to be displayed in the buffer. The string may be empty. If it is not -empty a newline will be added automatically. It may span several lines. -Optional third argument HEADER is a string that will always be present -at the top of the buffer. HEADER should end with a newline. Optionaly -fourth argument FOOTER is similar, and will always be inserted at the -bottom of the buffer." - - (cookie-set-buffer buffer - - (erase-buffer) - - (make-local-variable 'cookie-last-tin) - (make-local-variable 'cookie-pretty-printer) - (make-local-variable 'cookie-header) - (make-local-variable 'cookie-footer) - (make-local-variable 'cookies) - - (setq cookie-last-tin nil) - (setq cookie-pretty-printer pretty-printer) - (setq cookies (dll-create)) - - (dll-enter-first cookies - (cookie-create-tin-and-insert - header header 0)) - (setq cookie-header (dll-nth cookies 0)) - - (dll-enter-last cookies - (cookie-create-tin-and-insert - footer footer (point-max))) - (setq cookie-footer (dll-nth cookies -1)) - - (goto-char (point-min)) - (forward-line 1))) - - -(defun cookie-set-header (buffer header) - "Change the header. Args: BUFFER HEADER." - (impl)) - - -(defun cookie-set-footer (buffer header) - "Change the footer. Args: BUFFER FOOTER." - (impl)) - - - -(defun cookie-enter-first (buffer cookie) - "Enter a COOKIE first in BUFFER. -Args: BUFFER COOKIE." - - (cookie-set-buffer buffer - - ;; It is always safe to insert an element after the first element, - ;; because the header is always present. (dll-nth cookies 0) should - ;; never return nil. - - (dll-enter-after - cookies - (dll-nth cookies 0) - (cookie-create-tin-and-insert - cookie - (funcall cookie-pretty-printer cookie) - (cookie-tin-start-marker - (dll-element cookies (dll-nth cookies 1))))))) - - - -(defun cookie-enter-last (buffer cookie) - "Enter a COOKIE last in BUFFER. -Args: BUFFER COOKIE." - - (cookie-set-buffer buffer - - ;; Remember that the header and footer are always present. There - ;; is no need to check if (dll-nth cookies -2) returns nil. - - (dll-enter-before - cookies - (dll-nth cookies -1) - (cookie-create-tin-and-insert - cookie - (funcall cookie-pretty-printer cookie) - (cookie-tin-start-marker (dll-last cookies)))))) - - -(defun cookie-enter-after (buffer node cookie) - (impl)) - - -(defun cookie-enter-before (buffer node cookie) - (impl)) - - - -(defun cookie-next (buffer tin) - "Get the next tin. Args: BUFFER TIN. -Returns nil if TIN is nil or the last cookie." - (if tin - (cookie-set-buffer buffer - (cookie-filter-hf (dll-next cookies tin))))) - - - -(defun cookie-previous (buffer tin) - "Get the previous tin. Args: BUFFER TIN. -Returns nil if TIN is nil or the first cookie." - (if tin - (cookie-set-buffer buffer - (cookie-filter-hf (dll-previous cookies tin))))) - - -(defun cookie-nth (buffer n) - - "Return the Nth tin. Args: BUFFER N. -N counts from zero. Nil is returned if there is less than N cookies. -If N is negative, return the -(N+1)th last element. -Thus, (cookie-nth dll 0) returns the first node, -and (cookie-nth dll -1) returns the last node. - -Use cookie-cookie to extract the cookie from the tin." - - (cookie-set-buffer buffer - - ;; Skip the header (or footer, if n is negative). - (if (< n 0) - (setq n (1- n)) - (setq n (1+ n))) - - (cookie-filter-hf (dll-nth cookies n)))) - - - -(defun cookie-delete (buffer tin) - "Delete a cookie. Args: BUFFER TIN." - - (cookie-set-buffer buffer - (if (eq cookie-last-tin tin) - (setq cookie-last-tin nil)) - - (cookie-delete-tin-internal tin) - (dll-delete cookies tin))) - - - -(defun cookie-delete-first (buffer) - "Delete first cookie and return it. Args: BUFFER. -Returns nil if there is no cookie left." - - (cookie-set-buffer buffer - - ;; We have to check that we do not try to delete the footer. - - (let ((tin (dll-nth cookies 1))) ;Skip the header. - (if (eq tin cookie-footer) - nil - (cookie-delete-tin-internal tin) - (cookie-tin-cookie (dll-delete cookies tin)))))) - - - -(defun cookie-delete-last (buffer) - "Delete last cookie and return it. Args: BUFFER. -Returns nil if there is no cookie left." - - (cookie-set-buffer buffer - - ;; We have to check that we do not try to delete the header. - - (let ((tin (dll-nth cookies -2))) ;Skip the footer. - (if (eq tin cookie-header) - nil - (cookie-delete-tin-internal tin) - (cookie-tin-cookie (dll-delete cookies tin)))))) - - - -(defun cookie-first (buffer) - - "Return the first cookie in BUFFER. The cookie is not removed." - - (cookie-set-buffer buffer - (let ((tin (cookie-filter-hf (dll-nth cookies -1)))) - (if tin - (cookie-tin-cookie-safe - (dll-element cookies tin)))))) - - -(defun cookie-last (buffer) - - "Return the last cookie in BUFFER. The cookie is not removed." - - (cookie-set-buffer buffer - (let ((tin (cookie-filter-hf (dll-nth cookies -2)))) - (if tin - (cookie-tin-cookie-safe - (dll-element cookies tin)))))) - - -(defun cookie-empty (buffer) - - "Return true if there are no cookies in BUFFER." - - (cookie-set-buffer buffer - (eq (dll-nth cookies 1) cookie-footer))) - - -(defun cookie-length (buffer) - - "Return number of cookies in BUFFER." - - ;; Don't count the footer and header. - - (cookie-set-buffer buffer - (- (dll-length cookies) 2))) - - -(defun cookie-all (buffer) - - "Return a list of all cookies in BUFFER." - - (cookie-set-buffer buffer - (let (result - (tin (dll-nth cookies -2))) - (while (not (eq tin cookie-header)) - (setq result (cons (cookie-tin-cookie (dll-element cookies tin)) - result)) - (setq tin (dll-previous cookies tin))) - result))) - -(defun cookie-clear (buffer) - - "Remove all cookies in buffer." - - (cookie-set-buffer buffer - (cookie-create buffer cookie-pretty-printer - (cookie-tin-cookie (dll-element cookies cookie-header)) - (cookie-tin-cookie (dll-element cookies cookie-footer))))) - - - -(defun cookie-map (map-function buffer &rest map-args) - - "Apply MAP-FUNCTION to all cookies in BUFFER. -MAP-FUNCTION is applied to the first element first. -If MAP-FUNCTION returns non-nil the cookie will be refreshed. - -Note that BUFFER will be current buffer when MAP-FUNCTION is called. - -If more than two arguments are given to cookie-map, remaining -arguments will be passed to MAP-FUNCTION." - - (cookie-set-buffer buffer - (let ((tin (dll-nth cookies 1)) - result) - - (while (not (eq tin cookie-footer)) - - (if (apply map-function - (cookie-tin-cookie (dll-element cookies tin)) - map-args) - (cookie-refresh-tin tin)) - - (setq tin (dll-next cookies tin)))))) - - - -(defun cookie-map-reverse (map-function buffer &rest map-args) - - "Apply MAP-FUNCTION to all cookies in BUFFER. -MAP-FUNCTION is applied to the last cookie first. -If MAP-FUNCTION returns non-nil the cookie will be refreshed. - -Note that BUFFER will be current buffer when MAP-FUNCTION is called. - -If more than two arguments are given to cookie-map, remaining -arguments will be passed to MAP-FUNCTION." - - (cookie-set-buffer buffer - (let ((tin (dll-nth cookies -2)) - result) - - (while (not (eq tin cookie-header)) - - (if (apply map-function - (cookie-tin-cookie (dll-element cookies tin)) - map-args) - (cookie-refresh-tin tin)) - - (setq tin (dll-previous cookies tin)))))) - - - -(defun cookie-enter-cookies (buffer cookie-list) - - "Insert all cookies in the list COOKIE-LIST last in BUFFER. -Args: BUFFER COOKIE-LIST." - - (while cookie-list - (cookie-enter-last buffer (car cookie-list)) - (setq cookie-list (cdr cookie-list)))) - - -(defun cookie-filter (buffer predicate) - - "Remove all cookies in BUFFER for which PREDICATE returns nil. -Note that BUFFER will be current-buffer when PREDICATE is called. - -The PREDICATE is called with one argument, the cookie." - - (cookie-set-buffer buffer - (let ((tin (dll-nth cookies 1)) - next) - (while (not (eq tin cookie-footer)) - (setq next (dll-next cookies tin)) - (if (funcall predicate (cookie-tin-cookie (dll-element cookies tin))) - nil - (cookie-delete-tin-internal tin) - (dll-delete cookies tin)) - (setq tin next))))) - - -(defun cookie-filter-tins (buffer predicate) - - "Remove all cookies in BUFFER for which PREDICATE returns nil. -Note that BUFFER will be current-buffer when PREDICATE is called. - -The PREDICATE is called with one argument, the tin." - - (cookie-set-buffer buffer - (let ((tin (dll-nth cookies 1)) - next) - (while (not (eq tin cookie-footer)) - (setq next (dll-next cookies tin)) - (if (funcall predicate tin) - nil - (cookie-delete-tin-internal tin) - (dll-delete cookies tin)) - (setq tin next))))) - -(defun cookie-pos-before-middle-p (pos tin1 tin2) - - "Return true if POS is in the first half of the region defined by TIN1 and -TIN2." - - (< pos (/ (+ (cookie-tin-start-marker (dll-element cookeis tin1)) - (cookie-tin-start-marker (dll-element cookeis tin2))) - 2))) - - -(defun cookie-get-selection (buffer pos &optional guess force-guess) - - "Return the tin the POS is within. -Args: BUFFER POS &optional GUESS FORCE-GUESS. -GUESS should be a tin that it is likely that POS is near. If FORCE-GUESS -is non-nil GUESS is always used as a first guess, otherwise the first -guess is the first tin, last tin, or GUESS, whichever is nearest to -pos in the BUFFER. - -If pos points within the header, the first cookie is returned. -If pos points within the footer, the last cookie is returned. -Nil is returned if there is no cookie. - -It is often good to specify cookie-last-tin as GUESS, but remember -that cookie-last-tin is buffer local in all buffers that cookie -operates on." - - (cookie-set-buffer buffer - - (cond - ; No cookies present? - ((eq (dll-nth cookies 1) (dll-nth cookies -1)) - nil) - - ; Before first cookie? - ((< pos (cookie-tin-start-marker - (dll-element cookies (dll-nth cookies 1)))) - (dll-nth cookies 1)) - - ; After last cookie? - ((>= pos (cookie-tin-start-marker (dll-last cookies))) - (dll-nth cookies -2)) - - ; We now now that pos is within a cookie. - (t - ; Make an educated guess about which of the three known - ; cookies (the first, the last, or GUESS) is nearest. - (setq - guess - (cond - (force-guess guess) - (guess - (cond - ;; Closest to first cookie? - ((cookie-pos-before-middle-p - pos guess - (dll-nth cookies 1)) - (dll-nth cookies 1)) - ;; Closest to GUESS? - ((cookie-pos-before-middle-p - pos guess - cookie-footer) - guess) - ;; Closest to last cookie. - (t (dll-previous cookies cookie-footer)))) - (t - ;; No guess given. - (cond - ;; First half? - ((cookie-pos-before-middle-p - pos (dll-nth cookies 1) - cookie-footer) - (dll-nth cookies 1)) - (t (dll-previous cookies cookie-footer)))))) - - ;; GUESS is now a "best guess". - - ;; Find the correct cookie. First determine in which direction - ;; it lies, and then move in that direction until it is found. - - (cond - ;; Is pos after the guess? - ((>= pos (cookie-tin-start-marker (dll-element cookiess guess))) - - ;; Loop until we are exactly one cookie too far down... - (while (>= pos (cookie-tin-start-marker (dll-element cookiess guess))) - (setq guess (dll-next cookies guess))) - - ;; ...and return the previous cookie. - (dll-previous cookies guess)) - - ;; Pos is before guess - (t - - (while (< pos (cookie-tin-start-marker (dll-element cookiess guess))) - (setq guess (dll-previous cookies guess))) - - guess)))))) - - -(defun cookie-start-marker (buffer tin) - - "Return start-position of a cookie in BUFFER. -Args: BUFFER TIN. -The marker that is returned should not be modified in any way, -and is only valid until the contents of the cookie buffer changes." - - (cookie-set-buffer buffer - (cookie-tin-start-marker (dll-element cookies tin)))) - - -(defun cookie-end-marker (buffer tin) - - "Return end-position of a cookie in BUFFER. -Args: BUFFER TIN. -The marker that is returned should not be modified in any way, -and is only valid until the contents of the cookie buffer changes." - - (cookie-set-buffer buffer - (cookie-tin-start-marker - (dll-element cookies (dll-next cookies tin))))) - - - -(defun cookie-refresh (buffer) - - "Refresh all cookies in BUFFER. -Cookie-pretty-printer will be called for all cookies and the new result -displayed. - -See also cookie-invalidate-tins." - - (cookie-set-buffer buffer - - (erase-buffer) - - (set-marker (cookie-tin-start-marker (dll-element cookies cookie-header)) - (point) buffer) - (insert (cookie-tin-cookie (dll-element cookies cookie-header))) - (insert "\n") - - (let ((tin (dll-nth cookies 1))) - (while (not (eq tin cookie-footer)) - - (set-marker (cookie-tin-start-marker (dll-element cookies tin)) - (point) buffer) - (insert - (funcall cookie-pretty-printer - (cookie-tin-cookie (dll-element cookies tin)))) - (insert "\n") - (setq tin (dll-next cookies tin)))) - - (set-marker (cookie-tin-start-marker (dll-element cookies cookie-footer)) - (point) buffer) - (insert (cookie-tin-cookie (dll-element cookies cookie-footer))) - (insert "\n"))) - - -(defun cookie-invalidate-tins (buffer &rest tins) - - "Refresh some cookies. -Args: BUFFER &rest TINS." - - (cookie-set-buffer buffer - - (while tins - (cookie-refresh-tin (car tins)) - (setq tins (cdr tins))))) - - -;;; Cookie movement commands. - -(defun cookie-set-goal-column (buffer goal) - "Set goal-column for BUFFER. -Args: BUFFER GOAL. -goal-column is made buffer-local." - (cookie-set-buffer buffer - (make-local-variable 'goal-column) - (setq goal-column goal))) - - -(defun cookie-previous-cookie (buffer pos arg) - "Move point to the ARGth previous cookie. -Don't move if we are at the first cookie. -ARG is the prefix argument when called interactively. -Args: BUFFER POS ARG. -Sets cookie-last-tin to the cookie we move to." - - (interactive (list (current-buffer) (point) - (prefix-numeric-value current-prefix-arg))) - - (cookie-set-buffer buffer - (setq cookie-last-tin - (cookie-get-selection buffer pos cookie-last-tin)) - - (while (and cookie-last-tin (> arg 0)) - (setq arg (1- arg)) - (setq cookie-last-tin - (dll-previous cookies cookie-last-tin))) - - ;; Never step above the first cookie. - - (if (null (cookie-filter-hf cookie-last-tin)) - (setq cookie-last-tin (dll-nth cookies 1))) - - (goto-char - (cookie-tin-start-marker - (dll-element cookies cookie-last-tin))) - - (if goal-column - (move-to-column goal-column)))) - - - -(defun cookie-next-cookie (buffer pos arg) - "Move point to the ARGth next cookie. -Don't move if we are at the last cookie. -ARG is the prefix argument when called interactively. -Args: BUFFER POS ARG. -Sets cookie-last-tin to the cookie we move to." - - (interactive (list (current-buffer) (point) - (prefix-numeric-value current-prefix-arg))) - - (cookie-set-buffer buffer - (setq cookie-last-tin - (cookie-get-selection buffer pos cookie-last-tin)) - - (while (and cookie-last-tin (> arg 0)) - (setq arg (1- arg)) - (setq cookie-last-tin - (dll-next cookies cookie-last-tin))) - - (if (null (cookie-filter-hf cookie-last-tin)) - (setq cookie-last-tin (dll-nth cookies -2))) - - (goto-char - (cookie-tin-start-marker - (dll-element cookies cookie-last-tin))) - - (if goal-column - (move-to-column goal-column)))) - - -(defun cookie-collect-tins (buffer predicate &rest predicate-args) - - "Return a list of all tins in BUFFER whose cookie PREDICATE -returns true for. -PREDICATE is a function that takes a cookie as its argument. -The tins on the returned list will appear in the same order -as in the buffer. You should not rely on in which order PREDICATE -is called. Note that BUFFER is current-buffer when PREDICATE -is called. (If you call cookie-collect with another buffer set -as current-buffer and need to access buffer-local variables -from that buffer within PREDICATE you must send them via -PREDICATE-ARGS). - -If more than two arguments are given to cookie-collect the remaining -arguments will be passed to PREDICATE. - -Use cookie-cookie to get the cookie from the tin." - - (cookie-set-buffer buffer - (let ((tin (dll-nth cookies -2)) - result) - - (while (not (eq tin cookie-header)) - - (if (apply predicate - (cookie-tin-cookie (dll-element cookies tin)) - predicate-args) - (setq result (cons tin result))) - - (setq tin (dll-previous cookies tin))) - result))) - - -(defun cookie-collect-cookies (buffer predicate &rest predicate-args) - - "Return a list of all cookies in BUFFER that PREDICATE -returns true for. -PREDICATE is a function that takes a cookie as its argument. -The cookie on the returned list will appear in the same order -as in the buffer. You should not rely on in which order PREDICATE -is called. Note that BUFFER is current-buffer when PREDICATE -is called. (If you call cookie-collect with another buffer set -as current-buffer and need to access buffer-local variables -from that buffer within PREDICATE you must send them via -PREDICATE-ARGS). - -If more than two arguments are given to cookie-collect the remaining -arguments will be passed to PREDICATE." - - (cookie-set-buffer buffer - (let ((tin (dll-nth cookies -2)) - result) - - (while (not (eq tin cookie-header)) - - (if (apply predicate - (cookie-tin-cookie (dll-element cookies tin)) - predicate-args) - (setq result (cons (cookie-tin-cookie (dll-element cookies tin)) - result))) - - (setq tin (dll-previous cookies tin))) - result))) diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el deleted file mode 100644 index 733ff86f46c0..000000000000 --- a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll-debug.el +++ /dev/null @@ -1,298 +0,0 @@ -;;; elib-dll-debug -- A slow implementation of elib-dll for debugging. -;;; elib-dll-debug.el,v 1.2 1992/04/07 20:49:13 berliner Exp -;;; Copyright (C) 1991,1992 Per Cederqvist -;;; -;;; This program is free software; you can redistribute it and/or modify -;;; it under the terms of the GNU General Public License as published by -;;; the Free Software Foundation; either version 2 of the License, or -;;; (at your option) any later version. -;;; -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;; GNU General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program; if not, write to the Free Software -;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - -;;; This is a plug-in replacement for elib-dll.el. It is dreadfully -;;; slow, but it facilitates debugging. Don't trust the comments in -;;; this file too much. -(provide 'elib-dll) - -;;; -;;; A doubly linked list consists of one cons cell which holds the tag -;;; 'DL-LIST in the car cell and the list in the cdr -;;; cell. The doubly linked list is implemented as a normal list. You -;;; should use elib-dll.el and not this package in debugged code. This -;;; package is not written for speed... -;;; - -;;; ================================================================ -;;; Internal functions for use in the doubly linked list package - -(defun dll-get-dummy-node (dll) - - ;; Return the dummy node. INTERNAL USE ONLY. - dll) - -(defun dll-list-nodes (dll) - - ;; Return a list of all nodes in DLL. INTERNAL USE ONLY. - - (cdr dll)) - -(defun dll-set-from-node-list (dll list) - - ;; Set the contents of DLL to the nodes in LIST. - ;; INTERNAL USE ONLY. - - (setcdr dll list)) - -(defun dll-get-node-before (dll node) - ;; Return the node in DLL that points to NODE. Use - ;; (dll-get-node-before some-list nil) to get the last node. - ;; INTERNAL USE ONLY. - (while (and dll (not (eq (cdr dll) node))) - (setq dll (cdr dll))) - (if (not dll) - (error "Node not on list")) - dll) - -(defmacro dll-insert-after (node element) - (let ((node-v (make-symbol "node")) - (element-v (make-symbol "element"))) - (` (let (((, node-v) (, node)) - ((, element-v) (, element))) - (setcdr (, node-v) (cons (, element-v) (cdr (, node-v)))))))) - -;;; =================================================================== -;;; The public functions which operate on doubly linked lists. - -(defmacro dll-element (dll node) - - "Get the element of a NODE in a doubly linked list DLL. -Args: DLL NODE." - - (` (car (, node)))) - - -(defun dll-create () - "Create an empty doubly linked list." - (cons 'DL-LIST nil)) - - -(defun dll-p (object) - "Return t if OBJECT is a doubly linked list, otherwise return nil." - (eq (car-safe object) 'DL-LIST)) - - -(defun dll-enter-first (dll element) - "Add an element first on a doubly linked list. -Args: DLL ELEMENT." - (setcdr dll (cons element (cdr dll)))) - - -(defun dll-enter-last (dll element) - "Add an element last on a doubly linked list. -Args: DLL ELEMENT." - (dll-insert-after (dll-get-node-before dll nil) element)) - - -(defun dll-enter-after (dll node element) - "In the doubly linked list DLL, insert a node containing ELEMENT after NODE. -Args: DLL NODE ELEMENT." - - (dll-get-node-before dll node) - (dll-insert-after node element)) - - -(defun dll-enter-before (dll node element) - "In the doubly linked list DLL, insert a node containing ELEMENT before NODE. -Args: DLL NODE ELEMENT." - - (dll-insert-after (dll-get-node-before dll node) element)) - - - -(defun dll-next (dll node) - "Return the node after NODE, or nil if NODE is the last node. -Args: DLL NODE." - - (dll-get-node-before dll node) - (cdr node)) - - -(defun dll-previous (dll node) - "Return the node before NODE, or nil if NODE is the first node. -Args: DLL NODE." - - (dll-get-node-before dll node)) - - -(defun dll-delete (dll node) - - "Delete NODE from the doubly linked list DLL. -Args: DLL NODE. Return the element of node." - - ;; This is a no-op when applied to the dummy node. This will return - ;; nil if applied to the dummy node since it always contains nil. - - (setcdr (dll-get-node-before dll node) (cdr node))) - - -(defun dll-delete-first (dll) - - "Delete the first NODE from the doubly linked list DLL. -Return the element. Args: DLL. Returns nil if the DLL was empty." - - ;; Relies on the fact that dll-delete does nothing and - ;; returns nil if given the dummy node. - - (setcdr dll (cdr (cdr dll)))) - - -(defun dll-delete-last (dll) - - "Delete the last NODE from the doubly linked list DLL. -Return the element. Args: DLL. Returns nil if the DLL was empty." - - ;; Relies on the fact that dll-delete does nothing and - ;; returns nil if given the dummy node. - - (setcdr dll (dll-get-node-before dll nil) nil)) - - -(defun dll-first (dll) - - "Return the first element on the doubly linked list DLL. -Return nil if the list is empty. The element is not removed." - - (car (cdr dll))) - - - - -(defun dll-last (dll) - - "Return the last element on the doubly linked list DLL. -Return nil if the list is empty. The element is not removed." - - (car (dll-get-node-before dll nil))) - - - -(defun dll-nth (dll n) - - "Return the Nth node from the doubly linked list DLL. - Args: DLL N -N counts from zero. If DLL is not that long, nil is returned. -If N is negative, return the -(N+1)th last element. -Thus, (dll-nth dll 0) returns the first node, -and (dll-nth dll -1) returns the last node." - - ;; Branch 0 ("follow left pointer") is used when n is negative. - ;; Branch 1 ("follow right pointer") is used otherwise. - - (if (>= n 0) - (nthcdr n (cdr dll)) - (unwind-protect - (progn (setcdr dll (nreverse (cdr dll))) - (nthcdr (- n) dll)) - (setcdr dll (nreverse (cdr dll)))))) - -(defun dll-empty (dll) - - "Return t if the doubly linked list DLL is empty, nil otherwise" - - (not (cdr dll))) - -(defun dll-length (dll) - - "Returns the number of elements in the doubly linked list DLL." - - (length (cdr dll))) - - - -(defun dll-copy (dll &optional element-copy-fnc) - - "Return a copy of the doubly linked list DLL. -If optional second argument ELEMENT-COPY-FNC is non-nil it should be -a function that takes one argument, an element, and returns a copy of it. -If ELEMENT-COPY-FNC is not given the elements are not copied." - - (if element-copy-fnc - (cons 'DL-LIST (mapcar element-copy-fnc (cdr dll))) - (copy-sequence dll))) - - -(defun dll-all (dll) - - "Return all elements on the double linked list DLL as an ordinary list." - - (cdr dll)) - - -(defun dll-clear (dll) - - "Clear the doubly linked list DLL, i.e. make it completely empty." - - (setcdr dll nil)) - - -(defun dll-map (map-function dll) - - "Apply MAP-FUNCTION to all elements in the doubly linked list DLL. -The function is applied to the first element first." - - (mapcar map-function (cdr dll))) - - -(defun dll-map-reverse (map-function dll) - - "Apply MAP-FUNCTION to all elements in the doubly linked list DLL. -The function is applied to the last element first." - - (unwind-protect - (setcdr dll (nreverse (cdr dll))) - (mapcar map-function (cdr dll)) - (setcdr dll (nreverse (cdr dll))))) - - -(defun dll-create-from-list (list) - - "Given an elisp LIST create a doubly linked list with the same elements." - - (cons 'DL-LIST list)) - - - -(defun dll-sort (dll predicate) - - "Sort the doubly linked list DLL, stably, comparing elements using PREDICATE. -Returns the sorted list. DLL is modified by side effects. -PREDICATE is called with two elements of DLL, and should return T -if the first element is \"less\" than the second." - - (setcdr dll (sort (cdr dll) predicate)) - dll) - - -(defun dll-filter (dll predicate) - - "Remove all elements in the doubly linked list DLL for which PREDICATE -return nil." - - (let* ((prev dll) - (node (cdr dll))) - - (while node - (cond - ((funcall predicate (car node)) - (setq prev node)) - (t - (setcdr prev (cdr node)))) - (setq node (cdr node))))) diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el deleted file mode 100644 index 855bd19e8ee0..000000000000 --- a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-dll.el +++ /dev/null @@ -1,386 +0,0 @@ -;;; elib-dll.el,v 1.2 1992/04/07 20:49:15 berliner Exp -;;; elib-dll.el -- Some primitives for Doubly linked lists. -;;; Copyright (C) 1991, 1992 Per Cederqvist -;;; -;;; This program is free software; you can redistribute it and/or modify -;;; it under the terms of the GNU General Public License as published by -;;; the Free Software Foundation; either version 2 of the License, or -;;; (at your option) any later version. -;;; -;;; This program is distributed in the hope that it will be useful, -;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;; GNU General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program; if not, write to the Free Software -;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -;;; Mail bug reports to ceder@lysator.liu.se. - -(require 'elib-node) -(provide 'elib-dll) - -;;; -;;; A doubly linked list consists of one cons cell which holds the tag -;;; 'DL-LIST in the car cell and a pointer to a dummy node in the cdr -;;; cell. The doubly linked list is implemented as a circular list -;;; with the dummy node first and last. The dummy node is recognized -;;; by comparing it to the node which the cdr of the cons cell points -;;; to. -;;; - -;;; ================================================================ -;;; Internal functions for use in the doubly linked list package - -(defun dll-get-dummy-node (dll) - - ;; Return the dummy node. INTERNAL USE ONLY. - (cdr dll)) - -(defun dll-list-nodes (dll) - - ;; Return a list of all nodes in DLL. INTERNAL USE ONLY. - - (let* ((result nil) - (dummy (dll-get-dummy-node dll)) - (node (elib-node-left dummy))) - - (while (not (eq node dummy)) - (setq result (cons node result)) - (setq node (elib-node-left node))) - - result)) - -(defun dll-set-from-node-list (dll list) - - ;; Set the contents of DLL to the nodes in LIST. - ;; INTERNAL USE ONLY. - - (dll-clear dll) - (let* ((dummy (dll-get-dummy-node dll)) - (left dummy)) - (while list - (elib-node-set-left (car list) left) - (elib-node-set-right left (car list)) - (setq left (car list)) - (setq list (cdr list))) - - (elib-node-set-right left dummy) - (elib-node-set-left dummy left))) - - -;;; =================================================================== -;;; The public functions which operate on doubly linked lists. - -(defmacro dll-element (dll node) - - "Get the element of a NODE in a doubly linked list DLL. -Args: DLL NODE." - - (` (elib-node-data (, node)))) - - -(defun dll-create () - "Create an empty doubly linked list." - (let ((dummy-node (elib-node-create nil nil nil))) - (elib-node-set-right dummy-node dummy-node) - (elib-node-set-left dummy-node dummy-node) - (cons 'DL-LIST dummy-node))) - -(defun dll-p (object) - "Return t if OBJECT is a doubly linked list, otherwise return nil." - (eq (car-safe object) 'DL-LIST)) - -(defun dll-enter-first (dll element) - "Add an element first on a doubly linked list. -Args: DLL ELEMENT." - (dll-enter-after - dll - (dll-get-dummy-node dll) - element)) - - -(defun dll-enter-last (dll element) - "Add an element last on a doubly linked list. -Args: DLL ELEMENT." - (dll-enter-before - dll - (dll-get-dummy-node dll) - element)) - - -(defun dll-enter-after (dll node element) - "In the doubly linked list DLL, insert a node containing ELEMENT after NODE. -Args: DLL NODE ELEMENT." - - (let ((new-node (elib-node-create - node (elib-node-right node) - element))) - (elib-node-set-left (elib-node-right node) new-node) - (elib-node-set-right node new-node))) - - -(defun dll-enter-before (dll node element) - "In the doubly linked list DLL, insert a node containing ELEMENT before NODE. -Args: DLL NODE ELEMENT." - - (let ((new-node (elib-node-create - (elib-node-left node) node - element))) - (elib-node-set-right (elib-node-left node) new-node) - (elib-node-set-left node new-node))) - - - -(defun dll-next (dll node) - "Return the node after NODE, or nil if NODE is the last node. -Args: DLL NODE." - - (if (eq (elib-node-right node) (dll-get-dummy-node dll)) - nil - (elib-node-right node))) - - -(defun dll-previous (dll node) - "Return the node before NODE, or nil if NODE is the first node. -Args: DLL NODE." - - (if (eq (elib-node-left node) (dll-get-dummy-node dll)) - nil - (elib-node-left node))) - - -(defun dll-delete (dll node) - - "Delete NODE from the doubly linked list DLL. -Args: DLL NODE. Return the element of node." - - ;; This is a no-op when applied to the dummy node. This will return - ;; nil if applied to the dummy node since it always contains nil. - - (elib-node-set-right (elib-node-left node) (elib-node-right node)) - (elib-node-set-left (elib-node-right node) (elib-node-left node)) - (dll-element dll node)) - - - -(defun dll-delete-first (dll) - - "Delete the first NODE from the doubly linked list DLL. -Return the element. Args: DLL. Returns nil if the DLL was empty." - - ;; Relies on the fact that dll-delete does nothing and - ;; returns nil if given the dummy node. - - (dll-delete dll (elib-node-right (dll-get-dummy-node dll)))) - - -(defun dll-delete-last (dll) - - "Delete the last NODE from the doubly linked list DLL. -Return the element. Args: DLL. Returns nil if the DLL was empty." - - ;; Relies on the fact that dll-delete does nothing and - ;; returns nil if given the dummy node. - - (dll-delete dll (elib-node-left (dll-get-dummy-node dll)))) - - -(defun dll-first (dll) - - "Return the first element on the doubly linked list DLL. -Return nil if the list is empty. The element is not removed." - - (if (eq (elib-node-right (dll-get-dummy-node dll)) - (dll-get-dummy-node dll)) - nil - (elib-node-data (elib-node-right (dll-get-dummy-node dll))))) - - - - -(defun dll-last (dll) - - "Return the last element on the doubly linked list DLL. -Return nil if the list is empty. The element is not removed." - - (if (eq (elib-node-left (dll-get-dummy-node dll)) - (dll-get-dummy-node dll)) - nil - (elib-node-data (elib-node-left (dll-get-dummy-node dll))))) - - - -(defun dll-nth (dll n) - - "Return the Nth node from the doubly linked list DLL. - Args: DLL N -N counts from zero. If DLL is not that long, nil is returned. -If N is negative, return the -(N+1)th last element. -Thus, (dll-nth dll 0) returns the first node, -and (dll-nth dll -1) returns the last node." - - ;; Branch 0 ("follow left pointer") is used when n is negative. - ;; Branch 1 ("follow right pointer") is used otherwise. - - (let* ((dummy (dll-get-dummy-node dll)) - (branch (if (< n 0) 0 1)) - (node (elib-node-branch dummy branch))) - - (if (< n 0) - (setq n (- -1 n))) - - (while (and (not (eq dummy node)) - (> n 0)) - (setq node (elib-node-branch node branch)) - (setq n (1- n))) - - (if (eq dummy node) - nil - node))) - - -(defun dll-empty (dll) - - "Return t if the doubly linked list DLL is empty, nil otherwise" - - (eq (elib-node-left (dll-get-dummy-node dll)) - (dll-get-dummy-node dll))) - -(defun dll-length (dll) - - "Returns the number of elements in the doubly linked list DLL." - - (let* ((dummy (dll-get-dummy-node dll)) - (node (elib-node-right dummy)) - (n 0)) - - (while (not (eq node dummy)) - (setq node (elib-node-right node)) - (setq n (1+ n))) - - n)) - - - -(defun dll-copy (dll &optional element-copy-fnc) - - "Return a copy of the doubly linked list DLL. -If optional second argument ELEMENT-COPY-FNC is non-nil it should be -a function that takes one argument, an element, and returns a copy of it. -If ELEMENT-COPY-FNC is not given the elements are not copied." - - (let ((result (dll-create)) - (node (dll-nth dll 0))) - (if element-copy-fnc - - ;; Copy the elements with the user-supplied function. - (while node - (dll-enter-last result - (funcall element-copy-fnc - (dll-element dll node))) - (setq node (dll-next dll node))) - - ;; Don't try to copy the elements - they might be - ;; circular lists, or anything at all... - (while node - (dll-enter-last result (dll-element dll node)) - (setq node (dll-next dll node)))) - - result)) - - - -(defun dll-all (dll) - - "Return all elements on the double linked list DLL as an ordinary list." - - (let* ((result nil) - (dummy (dll-get-dummy-node dll)) - (node (elib-node-left dummy))) - - (while (not (eq node dummy)) - (setq result (cons (dll-element dll node) result)) - (setq node (elib-node-left node))) - - result)) - - -(defun dll-clear (dll) - - "Clear the doubly linked list DLL, i.e. make it completely empty." - - (elib-node-set-left (dll-get-dummy-node dll) (dll-get-dummy-node dll)) - (elib-node-set-right (dll-get-dummy-node dll) (dll-get-dummy-node dll))) - - -(defun dll-map (map-function dll) - - "Apply MAP-FUNCTION to all elements in the doubly linked list DLL. -The function is applied to the first element first." - - (let* ((dummy (dll-get-dummy-node dll)) - (node (elib-node-right dummy))) - - (while (not (eq node dummy)) - (funcall map-function (dll-element dll node)) - (setq node (elib-node-right node))))) - - -(defun dll-map-reverse (map-function dll) - - "Apply MAP-FUNCTION to all elements in the doubly linked list DLL. -The function is applied to the last element first." - - (let* ((dummy (dll-get-dummy-node dll)) - (node (elib-node-left dummy))) - - (while (not (eq node dummy)) - (funcall map-function (dll-element dll node)) - (setq node (elib-node-left node))))) - - -(defun dll-create-from-list (list) - - "Given an elisp LIST create a doubly linked list with the same elements." - - (let ((dll (dll-create))) - (while list - (dll-enter-last dll (car list)) - (setq list (cdr list))) - dll)) - - - -(defun dll-sort (dll predicate) - - "Sort the doubly linked list DLL, stably, comparing elements using PREDICATE. -Returns the sorted list. DLL is modified by side effects. -PREDICATE is called with two elements of DLL, and should return T -if the first element is \"less\" than the second." - - (dll-set-from-node-list - dll (sort (dll-list-nodes dll) - (function (lambda (x1 x2) - (funcall predicate - (dll-element dll x1) - (dll-element dll x2)))))) - dll) - - -(defun dll-filter (dll predicate) - - "Remove all elements in the doubly linked list DLL for which PREDICATE -return nil." - - (let* ((dummy (dll-get-dummy-node dll)) - (node (elib-node-right dummy)) - next) - - (while (not (eq node dummy)) - (setq next (elib-node-right node)) - (if (funcall predicate (dll-element dll node)) - nil - (dll-delete dll node)) - (setq node next)))) diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el deleted file mode 100644 index 6c476a35ef3d..000000000000 --- a/gnu/usr.bin/cvs/contrib/pcl-cvs/elib-node.el +++ /dev/null @@ -1,89 +0,0 @@ -;;;; elib-node.el,v 1.2 1992/04/07 20:49:16 berliner Exp -;;;; This file implements the nodes used in binary trees and -;;;; doubly linked lists -;;;; -;;;; Copyright (C) 1991 Inge Wallin -;;;; -;;;; This file is part of the GNU Emacs lisp library, Elib. -;;;; -;;;; GNU Elib is free software; you can redistribute it and/or modify -;;;; it under the terms of the GNU General Public License as published by -;;;; the Free Software Foundation; either version 1, or (at your option) -;;;; any later version. -;;;; -;;;; GNU Elib is distributed in the hope that it will be useful, -;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with GNU Emacs; see the file COPYING. If not, write to -;;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -;;;; -;;;; Author: Inge Wallin -;;;; - -;;; -;;; A node is implemented as an array with three elements, using -;;; (elt node 0) as the left pointer -;;; (elt node 1) as the right pointer -;;; (elt node 2) as the data -;;; -;;; Some types of trees, e.g. AVL trees, need bigger nodes, but -;;; as long as the first three parts are the left pointer, the -;;; right pointer and the data field, these macros can be used. -;;; - - -(provide 'elib-node) - - -(defmacro elib-node-create (left right data) - "Create a tree node from LEFT, RIGHT and DATA." - (` (vector (, left) (, right) (, data)))) - - -(defmacro elib-node-left (node) - "Return the left pointer of NODE." - (` (aref (, node) 0))) - - -(defmacro elib-node-right (node) - "Return the right pointer of NODE." - (` (aref (, node) 1))) - - -(defmacro elib-node-data (node) - "Return the data of NODE." - (` (aref (, node) 2))) - - -(defmacro elib-node-set-left (node newleft) - "Set the left pointer of NODE to NEWLEFT." - (` (aset (, node) 0 (, newleft)))) - - -(defmacro elib-node-set-right (node newright) - "Set the right pointer of NODE to NEWRIGHT." - (` (aset (, node) 1 (, newright)))) - - -(defmacro elib-node-set-data (node newdata) - "Set the data of NODE to NEWDATA." - (` (aset (, node) 2 (, newdata)))) - - - -(defmacro elib-node-branch (node branch) - "Get value of a branch of a node. -NODE is the node, and BRANCH is the branch. -0 for left pointer, 1 for right pointer and 2 for the data." - (` (aref (, node) (, branch)))) - - -(defmacro elib-node-set-branch (node branch newval) - "Set value of a branch of a node. -NODE is the node, and BRANCH is the branch. -0 for left pointer, 1 for the right pointer and 2 for the data. -NEWVAL is new value of the branch." - (` (aset (, node) (, branch) (, newval)))) diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.info b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.info deleted file mode 100644 index 060d9325e33a..000000000000 --- a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.info +++ /dev/null @@ -1,1659 +0,0 @@ -This is Info file pcl-cvs, produced by Makeinfo-1.49 from the input -file pcl-cvs.texinfo. - - Copyright (C) 1992 Per Cederqvist - - Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the section entitled "GNU General Public License" is included -exactly as in the original, and provided that the entire resulting -derived work is distributed under the terms of a permission notice -identical to this one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that the section entitled "GNU General Public -License" and this permission notice may be included in translations -approved by the Free Software Foundation instead of in the original -English. - - -File: pcl-cvs, Node: Top, Next: Copying, Prev: (dir), Up: (dir) - - This info manual describes pcl-cvs which is a GNU Emacs front-end -to CVS. It works with CVS version 1.3. This manual is updated to -release 1.05 of pcl-cvs. - -* Menu: - -* Copying:: GNU General Public License -* Installation:: How to install pcl-cvs on your system. -* About pcl-cvs:: Authors and ftp sites. - -* Getting started:: An introduction with a walk-through example. -* Buffer contents:: An explanation of the buffer contents. -* Commands:: All commands, grouped by type. - -* Customization:: How you can tailor pcl-cvs to suit your needs. -* Future enhancements:: Future enhancements of pcl-cvs. -* Bugs:: Bugs (known and unknown). -* Function and Variable Index:: List of functions and variables. -* Concept Index:: List of concepts. -* Key Index:: List of keystrokes. - - -- The Detailed Node Listing -- - -Installation - -* Pcl-cvs installation:: How to install pcl-cvs on your system. -* On-line manual installation:: How to install the on-line manual. -* Typeset manual installation:: How to create typeset documentation - about pcl-cvs. - -About pcl-cvs - -* Contributors:: Contributors to pcl-cvs. -* Archives:: Where can I get a copy of Pcl-Cvs? - -Buffer contents - -* File status:: The meaning of the second field. -* Selected files:: How selection works. - -Commands - -* Updating the directory:: Commands to update the local directory -* Movement commands:: How to move up and down in the buffer -* Marking files:: How to mark files that other commands - will later operate on. -* Committing changes:: Checking in your modifications to the - CVS repository. -* Editing files:: Loading files into Emacs. -* Getting info about files:: Display the log and status of files. -* Adding and removing files:: Adding and removing files -* Undoing changes:: Undoing changes -* Removing handled entries:: Uninteresting lines can easily be removed. -* Ignoring files:: Telling CVS to ignore generated files. -* Viewing differences:: Commands to `diff' different versions. -* Emerge:: -* Reverting your buffers:: Reverting your buffers -* Miscellaneous commands:: Miscellaneous commands - - -File: pcl-cvs, Node: Copying, Next: Installation, Prev: Top, Up: Top - -GNU GENERAL PUBLIC LICENSE -************************** - - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -Preamble -======== - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, -and (2) offer you this license which gives you legal permission to -copy, distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make -certain that everyone understands that there is no warranty for this -free software. If the software is modified by someone else and -passed on, we want its recipients to know that what they have is not -the original, so that any problems introduced by others will not -reflect on the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at -all. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 1. This License applies to any program or other work which contains - a notice placed by the copyright holder saying it may be - distributed under the terms of this General Public License. The - "Program", below, refers to any such program or work, and a - "work based on the Program" means either the Program or any - derivative work under copyright law: that is to say, a work - containing the Program or a portion of it, either verbatim or - with modifications and/or translated into another language. - (Hereinafter, translation is included without limitation in the - term "modification".) Each licensee is addressed as "you". - - Activities other than copying, distribution and modification are - not covered by this License; they are outside its scope. The - act of running the Program is not restricted, and the output - from the Program is covered only if its contents constitute a - work based on the Program (independent of having been made by - running the Program). Whether that is true depends on what the - Program does. - - 2. You may copy and distribute verbatim copies of the Program's - source code as you receive it, in any medium, provided that you - conspicuously and appropriately publish on each copy an - appropriate copyright notice and disclaimer of warranty; keep - intact all the notices that refer to this License and to the - absence of any warranty; and give any other recipients of the - Program a copy of this License along with the Program. - - You may charge a fee for the physical act of transferring a - copy, and you may at your option offer warranty protection in - exchange for a fee. - - 3. You may modify your copy or copies of the Program or any portion - of it, thus forming a work based on the Program, and copy and - distribute such modifications or work under the terms of Section - 1 above, provided that you also meet all of these conditions: - - a. You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any - change. - - b. You must cause any work that you distribute or publish, - that in whole or in part contains or is derived from the - Program or any part thereof, to be licensed as a whole at - no charge to all third parties under the terms of this - License. - - c. If the modified program normally reads commands - interactively when run, you must cause it, when started - running for such interactive use in the most ordinary way, - to print or display an announcement including an - appropriate copyright notice and a notice that there is no - warranty (or else, saying that you provide a warranty) and - that users may redistribute the program under these - conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive - but does not normally print such an announcement, your work - based on the Program is not required to print an - announcement.) - - These requirements apply to the modified work as a whole. If - identifiable sections of that work are not derived from the - Program, and can be reasonably considered independent and - separate works in themselves, then this License, and its terms, - do not apply to those sections when you distribute them as - separate works. But when you distribute the same sections as - part of a whole which is a work based on the Program, the - distribution of the whole must be on the terms of this License, - whose permissions for other licensees extend to the entire - whole, and thus to each and every part regardless of who wrote - it. - - Thus, it is not the intent of this section to claim rights or - contest your rights to work written entirely by you; rather, the - intent is to exercise the right to control the distribution of - derivative or collective works based on the Program. - - In addition, mere aggregation of another work not based on the - Program with the Program (or with a work based on the Program) - on a volume of a storage or distribution medium does not bring - the other work under the scope of this License. - - 4. You may copy and distribute the Program (or a work based on it, - under Section 2) in object code or executable form under the - terms of Sections 1 and 2 above provided that you also do one of - the following: - - a. Accompany it with the complete corresponding - machine-readable source code, which must be distributed - under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - b. Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than - your cost of physically performing source distribution, a - complete machine-readable copy of the corresponding source - code, to be distributed under the terms of Sections 1 and 2 - above on a medium customarily used for software - interchange; or, - - c. Accompany it with the information you received as to the - offer to distribute corresponding source code. (This - alternative is allowed only for noncommercial distribution - and only if you received the program in object code or - executable form with such an offer, in accord with - Subsection b above.) - - The source code for a work means the preferred form of the work - for making modifications to it. For an executable work, - complete source code means all the source code for all modules - it contains, plus any associated interface definition files, - plus the scripts used to control compilation and installation of - the executable. However, as a special exception, the source - code distributed need not include anything that is normally - distributed (in either source or binary form) with the major - components (compiler, kernel, and so on) of the operating system - on which the executable runs, unless that component itself - accompanies the executable. - - If distribution of executable or object code is made by offering - access to copy from a designated place, then offering equivalent - access to copy the source code from the same place counts as - distribution of the source code, even though third parties are - not compelled to copy the source along with the object code. - - 5. You may not copy, modify, sublicense, or distribute the Program - except as expressly provided under this License. Any attempt - otherwise to copy, modify, sublicense or distribute the Program - is void, and will automatically terminate your rights under this - License. However, parties who have received copies, or rights, - from you under this License will not have their licenses - terminated so long as such parties remain in full compliance. - - 6. You are not required to accept this License, since you have not - signed it. However, nothing else grants you permission to - modify or distribute the Program or its derivative works. These - actions are prohibited by law if you do not accept this License. - Therefore, by modifying or distributing the Program (or any - work based on the Program), you indicate your acceptance of this - License to do so, and all its terms and conditions for copying, - distributing or modifying the Program or works based on it. - - 7. Each time you redistribute the Program (or any work based on the - Program), the recipient automatically receives a license from the - original licensor to copy, distribute or modify the Program - subject to these terms and conditions. You may not impose any - further restrictions on the recipients' exercise of the rights - granted herein. You are not responsible for enforcing compliance - by third parties to this License. - - 8. If, as a consequence of a court judgment or allegation of patent - infringement or for any other reason (not limited to patent - issues), conditions are imposed on you (whether by court order, - agreement or otherwise) that contradict the conditions of this - License, they do not excuse you from the conditions of this - License. If you cannot distribute so as to satisfy - simultaneously your obligations under this License and any other - pertinent obligations, then as a consequence you may not - distribute the Program at all. For example, if a patent license - would not permit royalty-free redistribution of the Program by - all those who receive copies directly or indirectly through you, - then the only way you could satisfy both it and this License - would be to refrain entirely from distribution of the Program. - - If any portion of this section is held invalid or unenforceable - under any particular circumstance, the balance of the section is - intended to apply and the section as a whole is intended to - apply in other circumstances. - - It is not the purpose of this section to induce you to infringe - any patents or other property right claims or to contest - validity of any such claims; this section has the sole purpose - of protecting the integrity of the free software distribution - system, which is implemented by public license practices. Many - people have made generous contributions to the wide range of - software distributed through that system in reliance on - consistent application of that system; it is up to the - author/donor to decide if he or she is willing to distribute - software through any other system and a licensee cannot impose - that choice. - - This section is intended to make thoroughly clear what is - believed to be a consequence of the rest of this License. - - 9. If the distribution and/or use of the Program is restricted in - certain countries either by patents or by copyrighted - interfaces, the original copyright holder who places the Program - under this License may add an explicit geographical distribution - limitation excluding those countries, so that distribution is - permitted only in or among countries not thus excluded. In such - case, this License incorporates the limitation as if written in - the body of this License. - - 10. The Free Software Foundation may publish revised and/or new - versions of the General Public License from time to time. Such - new versions will be similar in spirit to the present version, - but may differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the - Program specifies a version number of this License which applies - to it and "any later version", you have the option of following - the terms and conditions either of that version or of any later - version published by the Free Software Foundation. If the - Program does not specify a version number of this License, you - may choose any version ever published by the Free Software - Foundation. - - 11. If you wish to incorporate parts of the Program into other free - programs whose distribution conditions are different, write to - the author to ask for permission. For software which is - copyrighted by the Free Software Foundation, write to the Free - Software Foundation; we sometimes make exceptions for this. Our - decision will be guided by the two goals of preserving the free - status of all derivatives of our free software and of promoting - the sharing and reuse of software generally. - - NO WARRANTY - - 12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO - WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE - LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT - HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT - WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE - QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE - PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY - SERVICING, REPAIR OR CORRECTION. - - 13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN - WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY - MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE - LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, - INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR - INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS - OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY - YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH - ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - -Appendix: How to Apply These Terms to Your New Programs -======================================================= - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is -safest to attach them to the start of each source file to most -effectively convey the exclusion of warranty; and each file should -have at least the "copyright" line and a pointer to where the full -notice is found. - - ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES. - Copyright (C) 19YY NAME OF AUTHOR - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Also add information on how to contact you by electronic and paper -mail. - - If the program is interactive, make it output a short notice like -this when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - - The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, the -commands you use may be called something other than `show w' and -`show c'; they could even be mouse-clicks or menu items--whatever -suits your program. - - You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the -program, if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - SIGNATURE OF TY COON, 1 April 1989 - Ty Coon, President of Vice - - This General Public License does not permit incorporating your -program into proprietary programs. If your program is a subroutine -library, you may consider it more useful to permit linking -proprietary applications with the library. If this is what you want -to do, use the GNU Library General Public License instead of this -License. - - -File: pcl-cvs, Node: Installation, Next: About pcl-cvs, Prev: Copying, Up: Top - -Installation -************ - - This section describes the installation of pcl-cvs, the GNU Emacs -CVS front-end. You should install not only the elisp files -themselves, but also the on-line documentation so that your users -will know how to use it. You can create typeset documentation from -the file `pcl-cvs.texinfo' as well as an on-line info file. The -following steps are also described in the file `INSTALL' in the source -directory. - -* Menu: - -* Pcl-cvs installation:: How to install pcl-cvs on your system. -* On-line manual installation:: How to install the on-line manual. -* Typeset manual installation:: How to create typeset documentation - about pcl-cvs. - - -File: pcl-cvs, Node: Pcl-cvs installation, Next: On-line manual installation, Prev: Installation, Up: Installation - -Installation of the pcl-cvs program -=================================== - - 1. Edit the file `Makefile' to reflect the situation at your site. - The only things you have to change is the definition of `lispdir' - and `infodir'. The elisp files will be copied to `lispdir', and - the info file to `infodir'. - - 2. Configure pcl-cvs.el - - There are a couple of paths that you have to check to make sure - that they match you system. They appear early in the file - pcl-cvs.el. - - *NOTE:* If your system is running emacs 18.57 or earlier you - MUST uncomment the line that says: - - (setq delete-exited-processes nil) - - Setting `delete-exited-processes' to `nil' works around a bug in - emacs that causes it to dump core. The bug was fixed in emacs - 18.58. - - 3. Release 1.05 and later of pcl-cvs requires parts of the Elib - library, version 0.07 or later. Elib is available via anonymous - ftp from prep.ai.mit.edu in `pub/gnu/elib-0.07.tar.z', and from - a lot of other sites that mirrors prep. Get Elib, and install - it, before proceeding. - - 4. Type `make install' in the source directory. This will - byte-compile all `.el' files and copy both the `.el' and the - `.elc' into the directory you specified in step 1. - - If you don't want to install the `.el' files but only the `.elc' - files (the byte-compiled files), you can type ``make - install_elc'' instead of ``make install''. - - If you only want to create the compiled elisp files, but don't - want to install them, you can type `make elcfiles' instead. - This is what happens if you only type `make' without parameters. - - 5. Edit the file `default.el' in your emacs lisp directory (usually - `/usr/gnu/emacs/lisp' or something similar) and enter the - contents of the file `pcl-cvs-startup.el' into it. It contains - a couple of `auto-load's that facilitates the use of pcl-cvs. - - - -File: pcl-cvs, Node: On-line manual installation, Next: Typeset manual installation, Prev: Pcl-cvs installation, Up: Installation - -Installation of the on-line manual. -=================================== - - 1. Create the info file `pcl-cvs' from `pcl-cvs.texinfo' by typing - `make info'. If you don't have the program `makeinfo' you can - get it by anonymous ftp from e.g. `ftp.gnu.ai.mit.edu' as - `pub/gnu/texinfo-2.14.tar.Z' (there might be a newer version - there when you read this), or you could use the preformatted - info file `pcl-cvs.info' that is included in the distribution - (type `cp pcl-cvs.info pcl-cvs'). - - 2. Move the info file `pcl-cvs' to your standard info directory. - This might be called something like `/usr/gnu/emacs/info'. - - 3. Edit the file `dir' in the info directory and enter one line to - contain a pointer to the info file `pcl-cvs'. The line can, for - instance, look like this: - - * Pcl-cvs: (pcl-cvs). An Emacs front-end to CVS. - - -File: pcl-cvs, Node: Typeset manual installation, Prev: On-line manual installation, Up: Installation - -How to make typeset documentation from pcl-cvs.texinfo -====================================================== - - If you have TeX installed at your site, you can make a typeset -manual from `pcl-cvs.texinfo'. - - 1. Run TeX by typing ``make pcl-cvs.dvi''. You will not get the - indices unless you have the `texindex' program. - - 2. Convert the resulting device independent file `pcl-cvs.dvi' to a - form which your printer can output and print it. If you have a - postscript printer there is a program, `dvi2ps', which does. - There is also a program which comes together with TeX, `dvips', - which you can use. - - - -File: pcl-cvs, Node: About pcl-cvs, Next: Getting started, Prev: Installation, Up: Top - -About pcl-cvs -************* - - Pcl-cvs is a front-end to CVS version 1.3. It integrates the most -frequently used CVS commands into emacs. - -* Menu: - -* Contributors:: Contributors to pcl-cvs. -* Archives:: Where can I get a copy of Pcl-Cvs? - - -File: pcl-cvs, Node: Contributors, Next: Archives, Prev: About pcl-cvs, Up: About pcl-cvs - -Contributors to pcl-cvs -======================= - - Contributions to the package are welcome. I have limited time to -work on this project, but I will gladly add any code that you -contribute to me to this package (*note Bugs::.). - - The following persons have made contributions to pcl-cvs. - - * Brian Berliner wrote CVS, together with some other contributors. - Without his work on CVS this package would be useless... - - * Per Cederqvist wrote most of the otherwise unattributed - functions in pcl-cvs as well as all documentation. - - * Inge Wallin (`inge@lysator.liu.se') wrote the skeleton to - `pcl-cvs.texinfo', and gave useful comments on it. He also wrote - the files `elib-node.el' and `compile-all.el'. The file - `cookie.el' was inspired by Inge. - - * Linus Tolke (`linus@lysator.liu.se') contributed useful comments - on both the functionality and the documentation. - - * Jamie Zawinski (`jwz@lucid.com') contributed `pcl-cvs-lucid.el'. - - * Leif Lonnblad contributed RCVS support. - - Apart from these, a lot of people have send me suggestions, ideas, -requests, bug reports and encouragement. Thanks a lot! Without your -there would be no new releases of pcl-cvs. - - -File: pcl-cvs, Node: Archives, Prev: Contributors, Up: About pcl-cvs - -Where can I get pcl-cvs? -======================== - - The latest release of pcl-cvs can be fetched via anonymous ftp from -`ftp.lysator.liu.se', (IP no. 130.236.254.1) in the directory -`pub/emacs'. If you don't live in Scandinavia you should probably -check with archie to see if there is a site closer to you that -archives pcl-cvs. - - New releases will be announced to appropriate newsgroups. If you -send your email address to me I will add you to my list of people to -mail when I make a new release. - - -File: pcl-cvs, Node: Getting started, Next: Buffer contents, Prev: About pcl-cvs, Up: Top - -Getting started -*************** - - This document assumes that you know what CVS is, and that you at -least knows the fundamental concepts of CVS. If that is not the case -you should read the man page for CVS. - - Pcl-cvs is only useful once you have checked out a module. So -before you invoke it you must have a copy of a module somewhere in -the file system. - - You invoke pcl-cvs by typing `M-x cvs-update RET'. If your emacs -responds with `[No match]' your system administrator has not -installed pcl-cvs properly. Try `M-x load-library RET pcl-cvs RET'. -If that also fails - talk to your root. If it succeeds you might put -this line in your `.emacs' file so that you don't have to type the -`load-library' command every time you wish to use pcl-cvs: - - (autoload 'cvs-update "pcl-cvs" nil t) - - The function `cvs-update' will ask for a directory. The command -`cvs update' will be run in that directory. (It should contain files -that have been checked out from a CVS archive.) The output from -`cvs' will be parsed and presented in a table in a buffer called -`*cvs*'. It might look something like this: - - PCL-CVS release 1.05. - - In directory /users/ceder/FOO/test: - Updated bar - Updated file.txt - Modified ci namechange - Updated newer - - In directory /users/ceder/FOO/test/sub: - Modified ci ChangeLog - ---------- End ----- - - In this example the three files (`bar', `file.txt' and `newer') -that are marked with `Updated' have been copied from the CVS -repository to `/users/ceder/FOO/test/' since someone else have -checked in newer versions of them. Two files (`namechange' and -`sub/ChangeLog') have been modified locally, and needs to be checked -in. - - You can move the cursor up and down in the buffer with `C-n' and -`C-p' or `n' and `p'. If you press `c' on one of the `Modified' -files that file will be checked in to the CVS repository. *Note -Committing changes::. You can press `x' to get rid of the -"uninteresting" files that have only been `Updated' (and don't -require any further action from you). - - You can also easily get a `diff' between your modified file and the -base version that you started from, and you can get the output from -`cvs log' and `cvs status' on the listed files simply by pressing a -key (*note Getting info about files::.). - - -File: pcl-cvs, Node: Buffer contents, Next: Commands, Prev: Getting started, Up: Top - -Buffer contents -*************** - - The display contains four columns. They contain, from left to -right: - - * An asterisk when the file is "marked" (*note Selected files::.). - - * The status of the file. See *Note File status::, for more - information. - - * A "need to be checked in"-marker (`ci'). - - * The file name. - -* Menu: - -* File status:: The meaning of the second field. -* Selected files:: How selection works. - - -File: pcl-cvs, Node: File status, Next: Selected files, Prev: Buffer contents, Up: Buffer contents - -File status -=========== - - The `file status' field can have the following values: - -`Updated' - The file was brought up to date with respect to the repository. - This is done for any file that exists in the repository but not - in your source, and for files that you haven't changed but are - not the most recent versions available in the repository. - -`Modified' - The file is modified in your working directory, and there was - no modification to the same file in the repository. - -`Merged' - The file is modified in your working directory, and there were - modifications in the repository as well as in your copy, but - they were merged successfully, without conflict, in your working - directory. - -`Conflict' - A conflict was detected while trying to merge your changes to - FILE with changes from the source repository. FILE (the copy in - your working directory) is now the output of the `rcsmerge' - command on the two versions; an unmodified copy of your file is - also in your working directory, with the name `.#FILE.VERSION', - where VERSION is the RCS revision that your modified file started - from. *Note Viewing differences::, for more details. - -`Added' - The file has been added by you, but it still needs to be checked - in to the repository. - -`Removed' - The file has been removed by you, but it needs to be checked in - to the repository. You can resurrect it by typing `a' (*note - Adding and removing files::.). - -`Unknown' - A file that was detected in your directory, but that neither - appears in the repository, nor is present on the list of files - that CVS should ignore. - - There are also a few special cases, that rarely occur, which have -longer strings in the fields: - -`Removed from repository' - The file has been removed from your directory since someone has - removed it from the repository. (It is still present in the - Attic directory, so no permanent loss has occurred). This, - unlike the other entries in this table, is not an error - condition. - -`Removed from repository, changed by you' - You have modified a file that someone have removed from the - repository. You can correct this situation by removing the file - manually (see *note Adding and removing files::.). - -`Removed by you, changed in repository' - You have removed a file, and before you committed the removal - someone committed a change to that file. You could use `a' to - resurrect the file (see *note Adding and removing files::.). - -`Move away FILE - it is in the way' - For some reason CVS does not like the file FILE. Rename or - remove it. - -`This repository is missing! Remove this dir manually.' - It is impossible to remove a directory in the CVS repository in - a clean way. Someone have tried to remove one, and CVS gets - confused. Remove your copy of the directory. - - -File: pcl-cvs, Node: Selected files, Prev: File status, Up: Buffer contents - -Selected files -============== - - Many of the commands works on the current set of "selected" files. - - * If there are any files that are marked they constitute the set of - selected files. - - * Otherwise, if the cursor points to a file, that file is the - selected file. - - * Otherwise, if the cursor points to a directory, all the files in - that directory that appears in the buffer are the selected files. - - This scheme might seem a little complicated, but once one get used -to it, it is quite powerful. - - *Note Marking files:: tells how you mark and unmark files. - - -File: pcl-cvs, Node: Commands, Next: Customization, Prev: Buffer contents, Up: Top - -Commands -******** - - The nodes in this menu contains explanations about all the -commands that you can use in pcl-cvs. They are grouped together by -type. - -* Menu: - -* Updating the directory:: Commands to update the local directory -* Movement commands:: How to move up and down in the buffer -* Marking files:: How to mark files that other commands - will later operate on. -* Committing changes:: Checking in your modifications to the - CVS repository. -* Editing files:: Loading files into Emacs. -* Getting info about files:: Display the log and status of files. -* Adding and removing files:: Adding and removing files -* Undoing changes:: Undoing changes -* Removing handled entries:: Uninteresting lines can easily be removed. -* Ignoring files:: Telling CVS to ignore generated files. -* Viewing differences:: Commands to `diff' different versions. -* Emerge:: -* Reverting your buffers:: Reverting your buffers -* Miscellaneous commands:: Miscellaneous commands - - -File: pcl-cvs, Node: Updating the directory, Next: Movement commands, Prev: Commands, Up: Commands - -Updating the directory -====================== - -`M-x cvs-update' - Run a `cvs update' command. You will be asked for the directory - in which the `cvs update' will be run. The output will be - parsed by pcl-cvs, and the result printed in the `*cvs*' buffer - (see *note Buffer contents::. for a description of the contents). - - By default, `cvs-update' will descend recursively into - subdirectories. You can avoid that behavior by giving a prefix - argument to it (e.g., by typing `C-u M-x cvs-update RET'). - - All other commands in pcl-cvs requires that you have a `*cvs*' - buffer. This is the command that you use to get one. - - CVS uses lock files in the repository to ensure the integrity of - the data files in the repository. They might be left behind - i.e. if a workstation crashes in the middle of a CVS operation. - CVS outputs a message when it is waiting for a lock file to go - away. Pcl-cvs will show the same message in the *cvs* buffer, - together with instructions for deleting the lock files. You - should normally not have to delete them manually -- just wait a - little while and the problem should fix itself. But if the lock - files doesn't disappear you can delete them with `M-x - cvs-delete-lock RET'. - -`g' - This will run `cvs update' again. It will always use the same - buffer that was used with the previous `cvs update'. Give a - prefix argument to avoid descending into subdirectories. This - runs the command `cvs-mode-update-no-prompt'. - - -File: pcl-cvs, Node: Movement commands, Next: Marking files, Prev: Updating the directory, Up: Commands - -Movement Commands -================= - - You can use most normal Emacs commands to move forward and -backward in the buffer. Some keys are rebound to functions that take -advantage of the fact that the buffer is a pcl-cvs buffer: - -`SPC' -`C-n' -`n' - These keys move the cursor one file forward, towards the end of - the buffer (`cookie-next-cookie'). - -`C-p' -`p' - These keys move one file backward, towards the beginning of the - buffer (`cookie-previous-cookie'). - - -File: pcl-cvs, Node: Marking files, Next: Committing changes, Prev: Movement commands, Up: Commands - -Marking files -============= - - Pcl-cvs works on a set of "selected files" (*note Selected -files::.). You can mark and unmark files with these commands: - -`m' - This marks the file that the cursor is positioned on. If the - cursor is positioned on a directory all files in that directory - will be marked. (`cvs-mode-mark'). - -`u' - Unmark the file that the cursor is positioned on. If the cursor - is on a directory, all files in that directory will be unmarked. - (`cvs-mode-unmark'). - -`M' - Mark *all* files in the buffer (`cvs-mode-mark-all-files'). - -`ESC DEL' - Unmark *all* files (`cvs-mode-unmark-all-files'). - -`DEL' - Unmark the file on the previous line, and move point to that line - (`cvs-mode-unmark-up'). - - -File: pcl-cvs, Node: Committing changes, Next: Editing files, Prev: Marking files, Up: Commands - -Committing changes -================== - -`c' - All files that have a "need to be checked in"-marker (*note - Buffer contents::.) can be checked in with the `c' command. It - checks in all selected files (*note Selected files::.) (except - those who lack the "ci"-marker - they are ignored). Pressing - `c' causes `cvs-mode-commit' to be run. - - When you press `c' you will get a buffer called - `*cvs-commit-message*'. Enter the log message for the file(s) in - it. When you are ready you should press `C-c C-c' to actually - commit the files (using `cvs-edit-done'). - - Normally the `*cvs-commit-message*' buffer will retain the log - message from the previous commit, but if the variable - `cvs-erase-input-buffer' is set to a non-`nil' value the buffer - will be erased. Point and mark will always be located around the - entire buffer so that you can easily erase it with `C-w' - (`kill-region'). - - If you are editing the files in your emacs an automatic - `revert-buffer' will be performed. (If the file contains `$Id$' - keywords `cvs commit' will write a new file with the new values - substituted. The auto-revert makes sure that you get them into - your buffer). The revert will not occur if you have modified - your buffer, or if `cvs-auto-revert-after-commit' is set to - `nil'. - - -File: pcl-cvs, Node: Editing files, Next: Getting info about files, Prev: Committing changes, Up: Commands - -Editing files -============= - - There are currently three commands that can be used to find a file -(that is, load it into a buffer and start editing it there). These -commands work on the line that the cursor is situated at. They -ignore any marked files. - -`f' - Find the file that the cursor points to. Run `dired' (*note - Dired: (Emacs)Dired.) if the cursor points to a directory - (`cvs-mode-find-file'). - -`o' - Like `f', but use another window - (`cvs-mode-find-file-other-window'). - -`A' - Invoke `add-change-log-entry-other-window' to edit a `ChangeLog' - file. The `ChangeLog' will be found in the directory of the - file the cursor points to. - (`cvs-mode-add-change-log-entry-other-window'). - - -File: pcl-cvs, Node: Getting info about files, Next: Adding and removing files, Prev: Editing files, Up: Commands - -Getting info about files -======================== - - Both of the following commands can be customized. *Note -Customization::. - -`l' - Run `cvs log' on all selected files, and show the result in a - temporary buffer (`cvs-mode-log'). - -`s' - Run `cvs status' on all selected files, and show the result in a - temporary buffer (`cvs-mode-status'). - - -File: pcl-cvs, Node: Adding and removing files, Next: Undoing changes, Prev: Getting info about files, Up: Commands - -Adding and removing files -========================= - - The following commands are available to make it easy to add and -remove files from the CVS repository. - -`a' - Add all selected files. This command can be used on `Unknown' - files (see *note File status::.). The status of the file will - change to `Added', and you will have to use `c' - (`cvs-mode-commit', see *note Committing changes::.) to really - add the file to the repository. - - This command can also be used on `Removed' files (before you - commit them) to resurrect them. - - Selected files that are neither `Unknown' nor `Removed' will be - ignored by this command. - - The command that is run is `cvs-mode-add'. - -`r' - This command removes the selected files (after prompting for - confirmation). The files are `rm'ed from your directory and - (unless the status was `Unknown'; *note File status::.) they will - also be `cvs remove'd. If the files were `Unknown' they will - disappear from the buffer. Otherwise their status will change to - `Removed', and you must use `c' (`cvs-mode-commit', *note - Committing changes::.) to commit the removal. - - The command that is run is `cvs-mode-remove-file'. - - -File: pcl-cvs, Node: Undoing changes, Next: Removing handled entries, Prev: Adding and removing files, Up: Commands - -Undoing changes -=============== - -`U' - If you have modified a file, and for some reason decide that you - don't want to keep the changes, you can undo them with this - command. It works by removing your working copy of the file and - then getting the latest version from the repository - (`cvs-mode-undo-local-changes'. - - -File: pcl-cvs, Node: Removing handled entries, Next: Ignoring files, Prev: Undoing changes, Up: Commands - -Removing handled entries -======================== - -`x' - This command allows you to remove all entries that you have - processed. More specifically, the lines for `Updated' files - (*note File status::. and files that have been checked in (*note - Committing changes::.) are removed from the buffer. If a - directory becomes empty the heading for that directory is also - removed. This makes it easier to get an overview of what needs - to be done. - - The command is called `cvs-mode-remove-handled'. If - `cvs-auto-remove-handled' is set to non-`nil' this will - automatically be performed after every commit. - -`C-k' - This command can be used for lines that - `cvs-mode-remove-handled' would not delete, but that you want to - delete (`cvs-mode-acknowledge'). - - -File: pcl-cvs, Node: Ignoring files, Next: Viewing differences, Prev: Removing handled entries, Up: Commands - -Ignoring files -============== - -`i' - Arrange so that CVS will ignore the selected files. The file - names are added to the `.cvsignore' file in the corresponding - directory. If the `.cvsignore' doesn't exist it will be created. - - The `.cvsignore' file should normally be added to the repository, - but you could ignore it also if you like it better that way. - - This runs `cvs-mode-ignore'. - - -File: pcl-cvs, Node: Viewing differences, Next: Emerge, Prev: Ignoring files, Up: Commands - -Viewing differences -=================== - -`d' - Display a `cvs diff' between the selected files and the RCS - version that they are based on. *Note Customization:: describes - how you can send flags to `cvs diff'. If CVS-DIFF-IGNORE-MARKS - is set to a non-`nil' value or if a prefix argument is given - (but not both) any marked files will not be considered to be - selected. (`cvs-mode-diff-cvs'). - -`b' - If CVS finds a conflict while merging two versions of a file - (during a `cvs update', *note Updating the directory::.) it will - save the original file in a file called `.#FILE.VERSION' where - FILE is the name of the file, and VERSION is the RCS version - number that your file was based on. - - With the `b' command you can run a `diff' on the files - `.#FILE.VERSION' and `FILE'. You can get a context- or Unidiff - by setting `cvs-diff-flags' - *note Customization::.. This - command only works on files that have status `Conflict' or - `Merged'. - - If CVS-DIFF-IGNORE-MARKS is set to a non-`nil' value or if a - prefix argument is given (but not both) any marked files will - not be considered to be selected. (`cvs-mode-diff-backup'). - - -File: pcl-cvs, Node: Emerge, Next: Reverting your buffers, Prev: Viewing differences, Up: Commands - -Running emerge -============== - -`e' - Invoke `emerge' on one file. This command works slightly - different depending on the file status. - - `Modified' - Run `emerge-files' with your working file as file A, and - the latest revision in the repository as file B. - - `Merged' - `Conflict' - Run `emerge-files-with-ancestor' with your working file (as - it was prior to your invocation of `cvs-update') as file A, - the latest revision in the repository as file B, and the - revision that you based your local modifications on as - ancestor. - - *Note:* CVS has already performed a merge. The resulting file is - not used in any way if you use this command. If you use the `q' - command inside `emerge' (to successfully terminate the merge) the - file that CVS created will be overwritten. - - -File: pcl-cvs, Node: Reverting your buffers, Next: Miscellaneous commands, Prev: Emerge, Up: Commands - -Reverting your buffers -====================== - -`R' - If you are editing (or just viewing) a file in a buffer, and - that file is changed by CVS during a `cvs-update', all you have - to do is type `R' in the *cvs* buffer to read in the new - versions of the files. - - All files that are `Updated', `Merged' or in `Conflict' are - reverted from the disk. Any other files are ignored. Only files - that you were already editing are read. - - An error is signalled if you have modified the buffer since it - was last changed. (`cvs-mode-revert-updated-buffers'). - - -File: pcl-cvs, Node: Miscellaneous commands, Prev: Reverting your buffers, Up: Commands - -Miscellaneous commands -====================== - -`M-x cvs-byte-compile-files' - Byte compile all selected files that end in .el. - -`M-x cvs-delete-lock' - This command can be used in any buffer, and deletes the lock - files that the *cvs* buffer informs you about. You should - normally never have to use this command since CVS tries very - carefully to always remove the lock files itself. - - You can only use this command when a message in the *cvs* buffer - tells you so. You should wait a while before using this command - in case someone else is running a cvs command. - -`q' - Bury the *cvs* buffer. (`bury-buffer'). - - -File: pcl-cvs, Node: Customization, Next: Future enhancements, Prev: Commands, Up: Top - -Customization -************* - - If you have an idea about any customization that would be handy but -isn't present in this list, please tell me! *Note Bugs:: for info on -how to reach me. - -`cvs-erase-input-buffer' - If set to anything else than `nil' the edit buffer will be erased - before you write the log message (*note Committing changes::.). - -`cvs-inhibit-copyright-message' - The copyright message that is displayed on startup can be - annoying after a while. Set this variable to `t' if you want to - get rid of it. (But don't set this to `t' in the system defaults - file - new users should see this message at least once). - -`cvs-diff-flags' - A list of strings to pass as arguments to the `cvs diff' and - `diff' programs. This is used by `cvs-mode-diff-cvs' and - `cvs-mode-diff-backup' (key `b', *note Viewing differences::.). - If you prefer the Unidiff format you could add this line to your - `.emacs' file: - - (setq cvs-diff-flags '("-u")) - -`cvs-diff-ignore-marks' - If this variable is non-`nil' or if a prefix argument is given - (but not both) to `cvs-mode-diff-cvs' or `cvs-mode-diff-backup' - marked files are not considered selected. - -`cvs-log-flags' - List of strings to send to `cvs log'. Used by `cvs-mode-log' - (key `l', *note Getting info about files::.). - -`cvs-status-flags' - List of strings to send to `cvs status'. Used by - `cvs-mode-status' (key `s', *note Getting info about files::.). - -`cvs-auto-remove-handled' - If this variable is set to any non-`nil' value - `cvs-mode-remove-handled' will be called every time you check in - files, after the check-in is ready. *Note Removing handled - entries::. - -`cvs-auto-revert-after-commit' - If this variable is set to any non-`nil' value any buffers you - have that visit a file that is committed will be automatically - reverted. This variable is default `t'. *Note Committing - changes::. - -`cvs-update-prog-output-skip-regexp' - The `-u' flag in the `modules' file can be used to run a command - whenever a `cvs update' is performed (see cvs(5)). This regexp - is used to search for the last line in that output. It is - normally set to `"$"'. That setting is only correct if the - command outputs nothing. Note that pcl-cvs will get very - confused if the command outputs *anything* to `stderr'. - -`cvs-cvsroot' - This variable can be set to override `CVSROOT'. It should be a - string. If it is set then everytime a cvs command is run it will - be called as `cvs -d CVS-CVSROOT...' This can be useful if your - site has several repositories. - -`TMPDIR' - Pcl-cvs uses this *environment variable* to decide where to put - the temporary files it needs. It defaults to `/tmp' if it is - not set. - -`cvs-commit-buffer-require-final-newline' - When you enter a log message in the `*cvs-commit-message*' buffer - pcl-cvs will normally automatically insert a trailing newline, - unless there already is one. This behavior can be controlled via - `cvs-commit-buffer-require-final-newline'. If it is `t' (the - default behavior), a newline will always be appended. If it is - `nil', newlines will never be appended. Any other value causes - pcl-cvs to ask the user whenever there is no trailing newline in - the commit message buffer. - -`cvs-sort-ignore-file' - If this variable is set to any non-`nil' value the `.cvsignore' - will always be sorted whenever you use `cvs-mode-ignore' to add - a file to it. This option is on by default. - - -File: pcl-cvs, Node: Future enhancements, Next: Bugs, Prev: Customization, Up: Top - -Future enhancements -******************* - - Pcl-cvs is still under development and needs a number of -enhancements to be called complete. Below is my current wish-list -for future releases of pcl-cvs. Please, let me know which of these -features you want most. They are listed below in approximately the -order that I currently think I will implement them in. - - * Rewritten parser code. There are many situations where pcl-cvs - will fail to recognize the output from CVS. The situation could - be greatly increased. - - * `cvs-status'. This will run `cvs status' in a directory and - produce a buffer that looks pretty much like the current *cvs* - buffer. That buffer will include information for all - version-controlled files. (There will be a simple keystroke to - remove all "uninteresting" files, that is, files that are - "Up-to-date"). In this new buffer you will be able to update a - file, commit a file, et c. The big win with this is that you - will be able to watch the differences between your current - working file and the head revision in the repository before you - update the file, and you can then choose to update it or let it - wait for a while longer. - - * Log mode. When this mode is finished you will be able to move - around (using `n' and `p') between the revisions of a file, mark - two of them, and run a diff between them. You will be able to - hide branches (similar to the way you can hide sub-paragraphs in - outline-mode) and do merges between revisions. Other ideas - about this are welcome. - - * The current model for marks in the *cvs* buffer seems to be - confusing. I am considering to use the VM model instead, where - marks are normally inactive. To activate the mark, you issue a - command like `cvs-mode-next-command-uses-marks'. I might - implement a flag so that you can use either version. Feedback - on this before I start coding it is very welcome. - - * It should be possible to run commands such as `cvs log', `cvs - status' and `cvs commit' directly from a buffer containing a - file, instead of having to `cvs-update'. If the directory - contains many files the `cvs-update' can take quite some time, - especially on a slow machine. I planed to put these kind of - commands on the prefix `C-c C-v', but that turned out to be used - by for instance c++-mode. If you have any suggestions for a - better prefix key, please let me know. - - * Increased robustness. For instance, you can not currently press - `C-g' when you are entering the description of a file that you - are adding without confusing pcl-cvs. - - * Support for multiple active *cvs* buffers. - - * Dired support. I have an experimental `dired-cvs.el' that works - together with CVS 1.2. Unfortunately I wrote it on top of a - non-standard `dired.el', so it must be rewritten. - - * An ability to send user-supplied options to all the cvs commands. - - * Pcl-cvs is not at all clever about what it should do when `cvs - update' runs a program (due to the `-u' option in the `modules' - file -- see `cvs(5)'). The current release uses a regexp to - search for the end. At the very least that regexp should be - configured for different modules. Tell me if you have any idea - about what is the right thing to do. In a perfect world the - program should also be allowed to print to `stderr' without - causing pcl-cvs to crash. - - If you miss something in this wish-list, let me know! I don't -promise that I will write it, but I will at least try to coordinate -the efforts of making a good Emacs front end to CVS. See *Note -Bugs:: for information about how to reach me. - - So far, I have written most of pcl-cvs in my all-to-rare spare -time. If you want pcl-cvs to be developed faster you can write a -contract with Signum Support to do the extension. You can reach -Signum Support by email to `info@signum.se' or via mail to Signum -Support AB, Box 2044, S-580 02 Linkoping, Sweden. Phone: +46 (0) 13 - -21 46 00. Fax: +46 (0) 13 - 21 47 00. - - -File: pcl-cvs, Node: Bugs, Next: Function and Variable Index, Prev: Future enhancements, Up: Top - -Bugs (known and unknown) -************************ - - If you find a bug or misfeature, don't hesitate to tell me! Send -email to `ceder@lysator.liu.se'. - - If you have ideas for improvements, or if you have written some -extensions to this package, I would like to hear from you. I hope -that you find this package useful! - - Below is a partial list of currently known problems with pcl-cvs -version 1.05. - -Commit causes Emacs to hang - Emacs waits for the `cvs commit' command to finish before you can - do anything. If you start a background job from the loginfo - file you must take care that it closes `stdout' and `stderr' if - you do not want to wait for it. (You do that with - `background-command &>- 2&>- &' if you are starting - `background-command' from a `/bin/sh' shell script). - - Your emacs will also hang if there was a lock file in the - repository. In this case you can type `C-g' to get control over - your emacs again. - -Name clash in Emacs 19 - This is really a bug in Elib or the Emacs 19 distribution. Both - Elib and Emacs 19.6 through at least 19.10 contains a file named - `cookie.el'. One of the files will have to be renamed, and we - are currently negotiating about which of the files to rename. - -Commands while cvs-update is running - It is possible to type commands in the *cvs* buffer while the - update is running, but error messages is all that you will get. - The error messages should be better. - -Unexpected output from CVS - Unexpected output from CVS confuses pcl-cvs. It will currently - create a bug report that you can mail to me. It should do - something more civilized. - - -File: pcl-cvs, Node: Function and Variable Index, Next: Concept Index, Prev: Bugs, Up: Top - -Function and Variable Index -*************************** - -* Menu: - -* bury-buffer: Miscellaneous commands. -* cookie-next-cookie: Movement commands. -* cookie-previous-cookie: Movement commands. -* cvs-auto-remove-handled (variable): Customization. -* cvs-auto-revert-after-commit (variable): Customization. -* cvs-auto-revert-after-commit (variable): Committing changes. -* cvs-byte-compile-files: Miscellaneous commands. -* cvs-commit-buffer-require-final-newline (variable): Customization. -* cvs-cvsroot (variable): Customization. -* cvs-delete-lock: Updating the directory. -* cvs-diff-flags (variable): Customization. -* cvs-diff-ignore-marks (variable): Customization. -* cvs-diff-ignore-marks (variable): Viewing differences. -* cvs-erase-input-buffer (variable): Customization. -* cvs-erase-input-buffer (variable): Committing changes. -* cvs-inhibit-copyright-message (variable): Customization. -* cvs-log-flags (variable): Customization. -* cvs-mode-acknowledge: Removing handled entries. -* cvs-mode-add: Adding and removing files. -* cvs-mode-add-change-log-entry-other-window: Editing files. -* cvs-mode-commit: Committing changes. -* cvs-mode-diff-backup: Viewing differences. -* cvs-mode-diff-cvs: Viewing differences. -* cvs-mode-emerge: Emerge. -* cvs-mode-find-file: Editing files. -* cvs-mode-find-file-other-window: Editing files. -* cvs-mode-ignore: Removing handled entries. -* cvs-mode-log: Getting info about files. -* cvs-mode-mark: Marking files. -* cvs-mode-mark-all-files: Marking files. -* cvs-mode-remove-file: Adding and removing files. -* cvs-mode-remove-handled: Removing handled entries. -* cvs-mode-revert-updated-buffers: Reverting your buffers. -* cvs-mode-status: Getting info about files. -* cvs-mode-undo-local-changes: Undoing changes. -* cvs-mode-unmark: Marking files. -* cvs-mode-unmark-all-files: Marking files. -* cvs-mode-unmark-up: Marking files. -* cvs-mode-update-no-prompt: Updating the directory. -* cvs-sort-ignore-file (variable): Customization. -* cvs-status-flags (variable): Customization. -* cvs-update: Updating the directory. -* cvs-update-prog-output-skip-regexp (variable): Customization. -* TMPDIR (environment variable): Customization. - - -File: pcl-cvs, Node: Concept Index, Next: Key Index, Prev: Function and Variable Index, Up: Top - -Concept Index -************* - -* Menu: - -* -u option in modules file: Customization. -* .cvsignore file, sorting: Customization. -* About pcl-cvs: About pcl-cvs. -* Active files: Selected files. -* Added (file status): File status. -* Adding files: Adding and removing files. -* Archives: Archives. -* Author, how to reach: Bugs. -* Authors: Contributors. -* Automatically inserting newline: Customization. -* Automatically remove handled files: Customization. -* Automatically sorting .cvsignore: Customization. -* Buffer contents: Buffer contents. -* Bugs, how to report them: Bugs. -* Bugs, known: Bugs. -* Byte compilation: Miscellaneous commands. -* Ci: Committing changes. -* Commit buffer: Committing changes. -* Commit message, inserting newline: Customization. -* Committing changes: Committing changes. -* Conflict (file status): File status. -* Conflicts, how to resolve them: Viewing differences. -* Conflicts, resolving: Emerge. -* Context diff, how to get: Customization. -* Contributors: Contributors. -* Copyright message, getting rid of it: Customization. -* Customization: Customization. -* Deleting files: Adding and removing files. -* Diff: Viewing differences. -* Dired: Editing files. -* Edit buffer: Committing changes. -* Editing files: Editing files. -* Email archives: Archives. -* Email to the author: Bugs. -* Emerge: Emerge. -* Enhancements: Future enhancements. -* Erasing commit message: Committing changes. -* Erasing the input buffer: Customization. -* Example run: Getting started. -* Expunging uninteresting entries: Removing handled entries. -* FAQ: Bugs. -* File selection: Selected files. -* File status: File status. -* Finding files: Editing files. -* Flush changes: Undoing changes. -* Ftp-sites: Archives. -* Generating a typeset manual: Typeset manual installation. -* Generating the on-line manual: On-line manual installation. -* Getting pcl-cvs: Archives. -* Getting rid of lock files: Miscellaneous commands. -* Getting rid of the Copyright message.: Customization. -* Getting rid of uninteresting lines: Removing handled entries. -* Getting status: Getting info about files. -* Getting the *cvs* buffer: Updating the directory. -* Handled lines, removing them: Removing handled entries. -* Info-file (how to generate): On-line manual installation. -* Inhibiting the Copyright message.: Customization. -* Installation: Installation. -* Installation of elisp files: Pcl-cvs installation. -* Installation of on-line manual: On-line manual installation. -* Installation of typeset manual: Typeset manual installation. -* Introduction: Getting started. -* Invoking dired: Editing files. -* Invoking emerge: Emerge. -* Known bugs: Bugs. -* Loading files: Editing files. -* Lock files: Miscellaneous commands. -* Log (RCS/cvs command): Getting info about files. -* Manual installation (on-line): On-line manual installation. -* Manual installation (typeset): Typeset manual installation. -* Marked files: Selected files. -* Marking files: Marking files. -* Merged (file status): File status. -* Modified (file status): File status. -* Modules file (-u option): Customization. -* Move away FILE - it is in the way (file status): File status. -* Movement Commands: Movement commands. -* On-line manual (how to generate): On-line manual installation. -* Printing a manual: Typeset manual installation. -* Problems, list of common: Bugs. -* Putting files under CVS control: Adding and removing files. -* Recompiling elisp files: Miscellaneous commands. -* Removed (file status): File status. -* Removed by you, changed in repository (file status): File status. -* Removed from repository (file status): File status. -* Removed from repository, changed by you (file status): File status. -* Removing files: Adding and removing files. -* Removing uninteresting (processed) lines: Removing handled entries. -* Reporting bugs and ideas: Bugs. -* Require final newline: Customization. -* Resolving conflicts: Emerge. -* Resurrecting files: Adding and removing files. -* Reverting buffers: Reverting your buffers. -* Reverting buffers after commit: Committing changes. -* Reverting buffers after commit: Customization. -* Selected files: Selected files. -* Selecting files (commands to mark files): Marking files. -* Sites: Archives. -* Sorting the .cvsignore file: Customization. -* Status (cvs command): Getting info about files. -* Syncing buffers: Reverting your buffers. -* TeX - generating a typeset manual: Typeset manual installation. -* This repository is missing!... (file status): File status. -* Undo changes: Undoing changes. -* Unidiff, how to get: Customization. -* Uninteresting entries, getting rid of them: Removing handled entries. -* Unknown (file status): File status. -* Update program (-u option in modules file): Customization. -* Updated (file status): File status. -* Variables, list of all: Customization. -* Viewing differences: Viewing differences. - - -File: pcl-cvs, Node: Key Index, Prev: Concept Index, Up: Top - -Key Index -********* - -* Menu: - -* a - add a file: Adding and removing files. -* A - add ChangeLog entry: Editing files. -* b - diff backup file: Viewing differences. -* c - commit files: Committing changes. -* C-k - remove selected entries: Removing handled entries. -* C-n - Move down one file: Movement commands. -* C-p - Move up one file: Movement commands. -* d - run cvs diff: Viewing differences. -* DEL - unmark previous file: Marking files. -* e - invoke emerge: Emerge. -* ESC DEL - unmark all files: Marking files. -* f - find file or directory: Editing files. -* g - Rerun cvs update: Updating the directory. -* l - run cvs log: Getting info about files. -* m - marking a file: Marking files. -* M - marking all files: Marking files. -* n - Move down one file: Movement commands. -* o - find file in other window: Editing files. -* p - Move up on file: Movement commands. -* q - bury the *cvs* buffer: Miscellaneous commands. -* r - remove a file: Adding and removing files. -* R - revert buffers: Reverting your buffers. -* s - run cvs status: Getting info about files. -* SPC - Move down one file: Movement commands. -* U - undo changes: Undoing changes. -* u - unmark a file: Marking files. -* x - remove processed entries: Removing handled entries. - - - -Tag Table: -Node: Top1007 -Node: Copying3571 -Node: Installation22803 -Node: Pcl-cvs installation23593 -Node: On-line manual installation25654 -Node: Typeset manual installation26672 -Node: About pcl-cvs27411 -Node: Contributors27780 -Node: Archives29083 -Node: Getting started29662 -Node: Buffer contents32105 -Node: File status32654 -Node: Selected files35679 -Node: Commands36347 -Node: Updating the directory37558 -Node: Movement commands39217 -Node: Marking files39803 -Node: Committing changes40658 -Node: Editing files42124 -Node: Getting info about files42969 -Node: Adding and removing files43448 -Node: Undoing changes44799 -Node: Removing handled entries45259 -Node: Ignoring files46176 -Node: Viewing differences46706 -Node: Emerge48014 -Node: Reverting your buffers48988 -Node: Miscellaneous commands49685 -Node: Customization50427 -Node: Future enhancements54107 -Node: Bugs58298 -Node: Function and Variable Index60079 -Node: Concept Index62872 -Node: Key Index69468 - -End Tag Table diff --git a/gnu/usr.bin/cvs/contrib/rcs-to-cvs b/gnu/usr.bin/cvs/contrib/rcs-to-cvs deleted file mode 100644 index 5863ed87414c..000000000000 --- a/gnu/usr.bin/cvs/contrib/rcs-to-cvs +++ /dev/null @@ -1,184 +0,0 @@ -#!/bin/sh -# -# $Id: rcs-to-cvs,v 1.4 1994/09/21 07:23:16 berliner Exp $ -# Based on the CVS 1.0 checkin csh script. -# Contributed by Per Cederqvist <ceder@signum.se>. -# Rewritten in sh by David MacKenzie <djm@cygnus.com>. -# -# Copyright (c) 1989, Brian Berliner -# -# You may distribute under the terms of the GNU General Public License. -# -############################################################################# -# -# Check in sources that previously were under RCS or no source control system. -# -# The repository is the directory where the sources should be deposited. -# -# Traverses the current directory, ensuring that an -# identical directory structure exists in the repository directory. It -# then checks the files in in the following manner: -# -# 1) If the file doesn't yet exist, check it in as revision 1.1 -# -# The script also is somewhat verbose in letting the user know what is -# going on. It prints a diagnostic when it creates a new file, or updates -# a file that has been modified on the trunk. -# -# Bugs: doesn't put the files in branch 1.1.1 -# doesn't put in release and vendor tags -# -############################################################################# - -usage="Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository" -vbose=0 -message="" -message_file=/usr/tmp/checkin.$$ -got_one=0 - -if [ $# -lt 1 ]; then - echo "$usage" >&2 - exit 1 -fi - -while [ $# -ne 0 ]; do - case "$1" in - -v) - vbose=1 - ;; - -m) - shift - echo $1 > $message_file - got_one=1 - ;; - -f) - shift - message_file=$1 - got_one=2 - ;; - *) - break - esac - shift -done - -if [ $# -lt 1 ]; then - echo "$usage" >&2 - exit 1 -fi - -repository=$1 -shift - -if [ -z "$CVSROOT" ]; then - echo "Please the environmental variable CVSROOT to the root" >&2 - echo " of the tree you wish to update" >&2 - exit 1 -fi - -if [ $got_one -eq 0 ]; then - echo "Please Edit this file to contain the RCS log information" >$message_file - echo "to be associated with this directory (please remove these lines)">>$message_file - ${EDITOR-/usr/ucb/vi} $message_file - got_one=1 -fi - -umask 22 - -update_dir=${CVSROOT}/${repository} -[ ! -d ${update_dir} ] && mkdir $update_dir - -if [ -d SCCS ]; then - echo SCCS files detected! >&2 - exit 1 -fi -if [ -d RCS ]; then - co RCS/* -fi - -for name in * .[a-zA-Z0-9]* -do - case "$name" in - RCS | \* | .\[a-zA-Z0-9\]\* ) continue ;; - esac - echo $name - if [ $vbose -ne 0 ]; then - echo "Updating ${repository}/${name}" - fi - if [ -d "$name" ]; then - if [ ! -d "${update_dir}/${name}" ]; then - echo "WARNING: Creating new directory ${repository}/${name}" - mkdir "${update_dir}/${name}" - if [ $? -ne 0 ]; then - echo "ERROR: mkdir failed - aborting" >&2 - exit 1 - fi - fi - cd "$name" - if [ $? -ne 0 ]; then - echo "ERROR: Couldn\'t cd to $name - aborting" >&2 - exit 1 - fi - if [ $vbose -ne 0 ]; then - $0 -v -f $message_file "${repository}/${name}" - else - $0 -f $message_file "${repository}/${name}" - fi - if [ $? -ne 0 ]; then - exit 1 - fi - cd .. - else # if not directory - if [ ! -f "$name" ]; then - echo "WARNING: $name is neither a regular file" - echo " nor a directory - ignored" - continue - fi - file="${update_dir}/${name},v" - comment="" - if grep -s '\$Log.*\$' "${name}"; then # If $Log keyword - myext=`echo $name | sed 's,.*\.,,'` - [ "$myext" = "$name" ] && myext= - case "$myext" in - c | csh | e | f | h | l | mac | me | mm | ms | p | r | red | s | sh | sl | cl | ml | el | tex | y | ye | yr | "" ) - ;; - - * ) - echo "For file ${file}:" - grep '\$Log.*\$' "${name}" - echo -n "Please insert a comment leader for file ${name} > " - read comment - ;; - esac - fi - if [ ! -f "$file" ]; then # If not exists in repository - if [ ! -f "${update_dir}/Attic/${name},v" ]; then - echo "WARNING: Creating new file ${repository}/${name}" - if [ -f RCS/"${name}",v ]; then - echo "MSG: Copying old rcs file." - cp RCS/"${name}",v "$file" - else - if [ -n "${comment}" ]; then - rcs -q -i -c"${comment}" -t${message_file} -m'.' "$file" - fi - ci -q -u1.1 -t${message_file} -m'.' "$file" - if [ $? -ne 0 ]; then - echo "ERROR: Initial check-in of $file failed - aborting" >&2 - exit 1 - fi - fi - else - file="${update_dir}/Attic/${name},v" - echo "WARNING: IGNORED: ${repository}/Attic/${name}" - continue - fi - else # File existed - echo "ERROR: File exists in repository: Ignored: $file" - continue - fi - fi -done - -[ $got_one -eq 1 ] && rm -f $message_file - -exit 0 diff --git a/gnu/usr.bin/cvs/contrib/rcs2log b/gnu/usr.bin/cvs/contrib/rcs2log deleted file mode 100644 index d7900025b851..000000000000 --- a/gnu/usr.bin/cvs/contrib/rcs2log +++ /dev/null @@ -1,326 +0,0 @@ -#!/bin/sh - -# RCS to ChangeLog generator - -# Generate a change log prefix from RCS/* and the existing ChangeLog (if any). -# Output the new prefix to standard output. -# You can edit this prefix by hand, and then prepend it to ChangeLog. - -# Ignore log entries that start with `#'. -# Clump together log entries that start with `{topic} ', -# where `topic' contains neither white space nor `}'. - -# Author: Paul Eggert <eggert@twinsun.com> - -# OrigId: rcs2log,v 1.9 1993/01/15 05:33:29 eggert Exp - -# Copyright 1992, 1993 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - - -# Parse options. - -# defaults -indent=8 # indent of log line -length=79 # suggested max width of log line -tabwidth=8 # width of horizontal tab - -while : -do - case $1 in - -i) indent=${2?};; - -l) length=${2?};; - -t) tabwidth=${2?};; - -*) echo >&2 "$0: usage: $0 [-i indent] [-l length] [-t tabwidth] [file ...]" - exit 1;; - *) break - esac - shift; shift -done - - -# Log into $rlogout the revisions checked in since the first ChangeLog entry. - -date=1970 -if test -s ChangeLog -then - # Add 1 to seconds to avoid duplicating most recent log. - # It's a good thing `rlog' doesn't mind a time ending in `:60'. - e=' - /^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{ - printf "%s%02d %s\n", substr($0,1,17), substr($0,18,2)+1, $5 - exit - } - ' - d=`awk "$e" <ChangeLog` || exit - case $d in - ?*) date=$d - esac -fi -datearg="-d>$date" - -rlogout=/tmp/chg$$ -trap exit 1 2 13 15 -trap 'rm -f $rlogout; exit 1' 0 - -case $# in -0) set RCS/* -esac - -rlog "$datearg" "$@" >$rlogout || exit - - -# Get the full name of each author the logs mention, and set initialize_fullname -# to awk code that initializes the `fullname' awk associative array. -# Warning: foreign authors (i.e. not known in the passwd file) are mishandled; -# you have to fix the resulting output by hand. - -initialize_fullname= -authors=` - sed -n 's|^date: *[0-9]*/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]; *author: *\([^; ]*\).*|\1|p' <$rlogout | - sort -u -` -case $authors in -?*) - initialize_author= - for author in $authors - do - initialize_author="$initialize_author - author[\"$author\"] = 1 - " - done - - awkscript=' - BEGIN { - alphabet = "abcdefghijklmnopqrstuvwxyz" - ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - '"$initialize_author"' - } - { - if (author[$1]) { - fullname = $5 - abbr = index(fullname, "&") - if (abbr) { - a = substr($1, 1, 1) - A = a - i = index(alphabet, a) - if (i) A = substr(ALPHABET, i, 1) - fullname = substr(fullname, 1, abbr-1) A substr($1, 2) substr(fullname, abbr+1) - } - printf "fullname[\"%s\"] = \"%s\"\n", $1, fullname - author[$1] = 0 - } - } - ' - - initialize_fullname=` - (cat /etc/passwd; ypmatch $authors passwd) 2>/dev/null | - awk -F: "$awkscript" - ` -esac - - -# Function to print a single log line. -# We don't use awk functions, to stay compatible with old awk versions. -# `Log' is the log message (with \n replaced by \r). -# `files' contains the affected files. -printlogline='{ - - # Following the GNU coding standards, rewrite - # * file: (function): comment - # to - # * file (function): comment - if (Log ~ /^\([^)]*\): /) { - i = index(Log, ")") - files = files " " substr(Log, 1, i) - Log = substr(Log, i+3) - } - - # If "label: comment" is too long, break the line after the ":". - sep = " " - if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, "\r")) sep = "\n" indent_string - - # Print the label. - printf "%s*%s:", indent_string, files - - # Print each line of the log, transliterating \r to \n. - while ((i = index(Log, "\r")) != 0) { - printf "%s%s\n", sep, substr(Log, 1, i-1) - sep = indent_string - Log = substr(Log, i+1) - } -}' - -hostname=`( - hostname || cat /etc/whoami || uuname -l || uname -n -) 2>/dev/null` || { - echo >&2 "$0: cannot deduce hostname" - exit 1 -} - - -# Process the rlog output, generating ChangeLog style entries. - -# First, reformat the rlog output so that each line contains one log entry. -# Transliterate \n to \r so that multiline entries fit on a single line. -# Discard irrelevant rlog output. -awk <$rlogout ' - /^Working file:/ { filename = $3 } - /^date: /, /^(-----------*|===========*)$/ { - if ($0 ~ /^branches: /) { next } - if ($0 ~ /^date: [0-9][ /0-9:]*;/) { - time = substr($3, 1, length($3)-1) - author = substr($5, 1, length($5)-1) - printf "%s %s %s %s \r", filename, $2, time, author - next - } - if ($0 ~ /^(-----------*|===========*)$/) { print ""; next } - printf "%s\r", $0 - } -' | - -# Now each line is of the form -# FILENAME YYYY/MM/DD HH:MM:SS AUTHOR \rLOG -# where \r stands for a carriage return, -# and each line of the log is terminated by \r instead of \n. -# Sort the log entries, first by date+time (in reverse order), -# then by author, then by log entry, and finally by file name (just in case). -sort +1 -3r +3 +0 | - -# Finally, reformat the sorted log entries. -awk ' - BEGIN { - - # Initialize the fullname associative array. - '"$initialize_fullname"' - - # Initialize indent string. - indent_string = "" - i = '"$indent"' - if (0 < '"$tabwidth"') - for (; '"$tabwidth"' <= i; i -= '"$tabwidth"') - indent_string = indent_string "\t" - while (1 <= i--) - indent_string = indent_string " " - - # Set up date conversion tables. - # RCS uses a nice, clean, sortable format, - # but ChangeLog wants the traditional, ugly ctime format. - - # January 1, 0 AD (Gregorian) was Saturday = 6 - EPOCH_WEEKDAY = 6 - # Of course, there was no 0 AD, but the algorithm works anyway. - - w[0]="Sun"; w[1]="Mon"; w[2]="Tue"; w[3]="Wed" - w[4]="Thu"; w[5]="Fri"; w[6]="Sat" - - m[0]="Jan"; m[1]="Feb"; m[2]="Mar" - m[3]="Apr"; m[4]="May"; m[5]="Jun" - m[6]="Jul"; m[7]="Aug"; m[8]="Sep" - m[9]="Oct"; m[10]="Nov"; m[11]="Dec" - - # days in non-leap year thus far, indexed by month (0-12) - mo[0]=0; mo[1]=31; mo[2]=59; mo[3]=90 - mo[4]=120; mo[5]=151; mo[6]=181; mo[7]=212 - mo[8]=243; mo[9]=273; mo[10]=304; mo[11]=334 - mo[12]=365 - } - - { - newlog = substr($0, 1 + index($0, "\r")) - - # Ignore log entries prefixed by "#". - if (newlog ~ /^#/) { next } - - if (Log != newlog || date != $2 || author != $4) { - - # The previous log and this log differ. - - # Print the old log. - if (date != "") '"$printlogline"' - - # Logs that begin with "{clumpname} " should be grouped together, - # and the clumpname should be removed. - # Extract the new clumpname from the log header, - # and use it to decide whether to output a blank line. - newclumpname = "" - sep = "\n" - if (date == "") sep = "" - if (newlog ~ /^{[^ }]*}[ ]/) { - i = index(newlog, "}") - newclumpname = substr(newlog, 1, i) - while (substr(newlog, i+1) ~ /^[ ]/) i++ - newlog = substr(newlog, i+1) - if (clumpname == newclumpname) sep = "" - } - printf sep - clumpname = newclumpname - - # Get ready for the next log. - Log = newlog - if (files != "") - for (i in filesknown) - filesknown[i] = 0 - files = "" - } - if (date != $2 || author != $4) { - # The previous date+author and this date+author differ. - # Print the new one. - date = $2 - author = $4 - - # Convert nice RCS date like "1992/01/03 00:03:44" - # into ugly ctime date like "Fri Jan 3 00:03:44 1992". - # Calculate day of week from Gregorian calendar. - i = index($2, "/") - year = substr($2, 1, i-1) + 0 - monthday = substr($2, i+1) - i = index(monthday, "/") - month = substr(monthday, 1, i-1) + 0 - day = substr(monthday, i+1) + 0 - leap = 0 - if (2 < month && year%4 == 0 && (year%100 != 0 || year%400 == 0)) leap = 1 - days_since_Sunday_before_epoch = EPOCH_WEEKDAY + year * 365 + int((year + 3) / 4) - int((year + 99) / 100) + int((year + 399) / 400) + mo[month-1] + leap + day - 1 - - # Print "date fullname (email address)" if the fullname is known; - # print "date author" otherwise. - # Get the fullname from the associative array. - # The email address is just author@thishostname. - printf "%s %s %2d %s %d ", w[days_since_Sunday_before_epoch%7], m[month-1], day, $3, year - if (fullname[author]) - printf "%s (%s@%s)\n\n", fullname[author], author, "'"$hostname"'" - else - printf "%s\n\n", author - } - if (! filesknown[$1]) { - filesknown[$1] = 1 - if (files == "") files = " " $1 - else files = files ", " $1 - } - } - END { - # Print the last log. - if (date != "") { - '"$printlogline"' - printf "\n" - } - } -' && - - -# Exit successfully. - -exec rm -f $rlogout diff --git a/gnu/usr.bin/cvs/contrib/rcs2sccs b/gnu/usr.bin/cvs/contrib/rcs2sccs deleted file mode 100644 index 054ac6c1eca9..000000000000 --- a/gnu/usr.bin/cvs/contrib/rcs2sccs +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/sh -# -# -# OrigId: rcs2sccs,v 1.12 90/10/04 20:52:23 kenc Exp Locker: kenc -# $Id: rcs2sccs,v 1.1 1993/12/06 06:37:14 berliner Exp $ - -############################################################ -# Error checking -# -if [ ! -d SCCS ] ; then - mkdir SCCS -fi - -logfile=/tmp/rcs2sccs_$$_log -rm -f $logfile -tmpfile=/tmp/rcs2sccs_$$_tmp -rm -f $tmpfile -emptyfile=/tmp/rcs2sccs_$$_empty -echo -n "" > $emptyfile -initialfile=/tmp/rcs2sccs_$$_init -echo "Initial revision" > $initialfile -sedfile=/tmp/rcs2sccs_$$_sed -rm -f $sedfile -revfile=/tmp/rcs2sccs_$$_rev -rm -f $revfile -commentfile=/tmp/rcs2sccs_$$_comment -rm -f $commentfile - -# create the sed script -cat > $sedfile << EOF -s,;Id;,%Z%%M% %I% %E%,g -s,;SunId;,%Z%%M% %I% %E%,g -s,;RCSfile;,%M%,g -s,;Revision;,%I%,g -s,;Date;,%E%,g -s,;Id:.*;,%Z%%M% %I% %E%,g -s,;SunId:.*;,%Z%%M% %I% %E%,g -s,;RCSfile:.*;,%M%,g -s,;Revision:.*;,%I%,g -s,;Date:.*;,%E%,g -EOF -sed -e 's/;/\\$/g' $sedfile > $tmpfile -cp $tmpfile $sedfile -############################################################ -# Loop over every RCS file in RCS dir -# -for vfile in *,v; do - # get rid of the ",v" at the end of the name - file=`echo $vfile | sed -e 's/,v$//'` - - # work on each rev of that file in ascending order - firsttime=1 - rlog $file | grep "^revision [0-9][0-9]*\." | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile - for rev in `cat $revfile`; do - if [ $? != 0 ]; then - echo ERROR - revision - exit - fi - # get file into current dir and get stats - date=`rlog -r$rev $file | grep "^date: " | awk '{print $2; exit}' | sed -e 's/^19//'` - time=`rlog -r$rev $file | grep "^date: " | awk '{print $3; exit}' | sed -e 's/;//'` - author=`rlog -r$rev $file | grep "^date: " | awk '{print $5; exit}' | sed -e 's/;//'` - date="$date $time" - echo "" - rlog -r$rev $file | sed -e '/^branches: /d' -e '1,/^date: /d' -e '/^===========/d' -e 's/$/\\/' | awk '{if ((total += length($0) + 1) < 510) print $0}' > $commentfile - echo "==> file $file, rev=$rev, date=$date, author=$author" - rm -f $file - co -r$rev $file >> $logfile 2>&1 - if [ $? != 0 ]; then - echo ERROR - co - exit - fi - echo checked out of RCS - - # add SCCS keywords in place of RCS keywords - sed -f $sedfile $file > $tmpfile - if [ $? != 0 ]; then - echo ERROR - sed - exit - fi - echo performed keyword substitutions - rm -f $file - cp $tmpfile $file - - # check file into SCCS - if [ "$firsttime" = "1" ]; then - firsttime=0 - echo about to do sccs admin - echo sccs admin -n -i$file $file < $commentfile - sccs admin -n -i$file $file < $commentfile >> $logfile 2>&1 - if [ $? != 0 ]; then - echo ERROR - sccs admin - exit - fi - echo initial rev checked into SCCS - else - case $rev in - *.*.*.*) - brev=`echo $rev | sed -e 's/\.[0-9]*$//'` - sccs admin -fb $file 2>>$logfile - echo sccs get -e -p -r$brev $file - sccs get -e -p -r$brev $file >/dev/null 2>>$logfile - ;; - *) - echo sccs get -e -p $file - sccs get -e -p $file >/dev/null 2>> $logfile - ;; - esac - if [ $? != 0 ]; then - echo ERROR - sccs get - exit - fi - sccs delta $file < $commentfile >> $logfile 2>&1 - if [ $? != 0 ]; then - echo ERROR - sccs delta -r$rev $file - exit - fi - echo checked into SCCS - fi - sed -e "s;^d D $rev ../../.. ..:..:.. [^ ][^ ]*;d D $rev $date $author;" SCCS/s.$file > $tmpfile - rm -f SCCS/s.$file - cp $tmpfile SCCS/s.$file - chmod 444 SCCS/s.$file - sccs admin -z $file - if [ $? != 0 ]; then - echo ERROR - sccs admin -z - exit - fi - done - rm -f $file -done - - -############################################################ -# Clean up -# -echo cleaning up... -rm -f $tmpfile $emptyfile $initialfile $sedfile $commentfile -echo =================================================== -echo " Conversion Completed Successfully" -echo =================================================== - -rm -f *,v diff --git a/gnu/usr.bin/cvs/contrib/sccs2rcs b/gnu/usr.bin/cvs/contrib/sccs2rcs deleted file mode 100644 index 654024bf3fc3..000000000000 --- a/gnu/usr.bin/cvs/contrib/sccs2rcs +++ /dev/null @@ -1,277 +0,0 @@ -#!/bin/csh -f -# -# Sccs2rcs is a script to convert an existing SCCS -# history into an RCS history without losing any of -# the information contained therein. -# It has been tested under the following OS's: -# SunOS 3.5, 4.0.3, 4.1 -# Ultrix-32 2.0, 3.1 -# -# Things to note: -# + It will NOT delete or alter your ./SCCS history under any circumstances. -# -# + Run in a directory where ./SCCS exists and where you can -# create ./RCS -# -# + /usr/local/bin is put in front of the default path. -# (SCCS under Ultrix is set-uid sccs, bad bad bad, so -# /usr/local/bin/sccs here fixes that) -# -# + Date, time, author, comments, branches, are all preserved. -# -# + If a command fails somewhere in the middle, it bombs with -# a message -- remove what it's done so far and try again. -# "rm -rf RCS; sccs unedit `sccs tell`; sccs clean" -# There is no recovery and exit is far from graceful. -# If a particular module is hanging you up, consider -# doing it separately; move it from the current area so that -# the next run will have a better chance or working. -# Also (for the brave only) you might consider hacking -# the s-file for simpler problems: I've successfully changed -# the date of a delta to be in sync, then run "sccs admin -z" -# on the thing. -# -# + After everything finishes, ./SCCS will be moved to ./old-SCCS. -# -# This file may be copied, processed, hacked, mutilated, and -# even destroyed as long as you don't tell anyone you wrote it. -# -# Ken Cox -# Viewlogic Systems, Inc. -# kenstir@viewlogic.com -# ...!harvard!cg-atla!viewlog!kenstir -# -# Various hacks made by Brian Berliner before inclusion in CVS contrib area. -# -# $Id: sccs2rcs,v 1.1 1992/04/10 03:04:26 berliner Exp $ - - -#we'll assume the user set up the path correctly -# for the Pmax, /usr/ucb/sccs is suid sccs, what a pain -# /usr/local/bin/sccs should override /usr/ucb/sccs there -set path = (/usr/local/bin $path) - - -############################################################ -# Error checking -# -if (! -w .) then - echo "Error: ./ not writeable by you." - exit 1 -endif -if (! -d SCCS) then - echo "Error: ./SCCS directory not found." - exit 1 -endif -set edits = (`sccs tell`) -if ($#edits) then - echo "Error: $#edits file(s) out for edit...clean up before converting." - exit 1 -endif -if (-d RCS) then - echo "Warning: RCS directory exists" - if (`ls -a RCS | wc -l` > 2) then - echo "Error: RCS directory not empty - exit 1 - endif -else - mkdir RCS -endif - -sccs clean - -set logfile = /tmp/sccs2rcs_$$_log -rm -f $logfile -set tmpfile = /tmp/sccs2rcs_$$_tmp -rm -f $tmpfile -set emptyfile = /tmp/sccs2rcs_$$_empty -echo -n "" > $emptyfile -set initialfile = /tmp/sccs2rcs_$$_init -echo "Initial revision" > $initialfile -set sedfile = /tmp/sccs2rcs_$$_sed -rm -f $sedfile -set revfile = /tmp/sccs2rcs_$$_rev -rm -f $revfile - -# the quotes surround the dollar signs to fool RCS when I check in this script -set sccs_keywords = (\ - '%W%[ ]*%G%'\ - '%W%[ ]*%E%'\ - '%W%'\ - '%Z%%M%[ ]*%I%[ ]*%G%'\ - '%Z%%M%[ ]*%I%[ ]*%E%'\ - '%M%[ ]*%I%[ ]*%G%'\ - '%M%[ ]*%I%[ ]*%E%'\ - '%M%'\ - '%I%'\ - '%G%'\ - '%E%'\ - '%U%') -set rcs_keywords = (\ - '$'Id'$'\ - '$'Id'$'\ - '$'Id'$'\ - '$'SunId'$'\ - '$'SunId'$'\ - '$'Id'$'\ - '$'Id'$'\ - '$'RCSfile'$'\ - '$'Revision'$'\ - '$'Date'$'\ - '$'Date'$'\ - '') - - -############################################################ -# Get some answers from user -# -echo "" -echo "Do you want to be prompted for a description of each" -echo "file as it is checked in to RCS initially?" -echo -n "(y=prompt for description, n=null description) [y] ?" -set ans = $< -if ((_$ans == _) || (_$ans == _y) || (_$ans == _Y)) then - set nodesc = 0 -else - set nodesc = 1 -endif -echo "" -echo "The default keyword substitutions are as follows and are" -echo "applied in the order specified:" -set i = 1 -while ($i <= $#sccs_keywords) -# echo ' '\"$sccs_keywords[$i]\"' ==> '\"$rcs_keywords[$i]\" - echo " $sccs_keywords[$i] ==> $rcs_keywords[$i]" - @ i = $i + 1 -end -echo "" -echo -n "Do you want to change them [n] ?" -set ans = $< -if ((_$ans != _) && (_$ans != _n) && (_$ans != _N)) then - echo "You can't always get what you want." - echo "Edit this script file and change the variables:" - echo ' $sccs_keywords' - echo ' $rcs_keywords' -else - echo "good idea." -endif - -# create the sed script -set i = 1 -while ($i <= $#sccs_keywords) - echo "s,$sccs_keywords[$i],$rcs_keywords[$i],g" >> $sedfile - @ i = $i + 1 -end - -onintr ERROR - -############################################################ -# Loop over every s-file in SCCS dir -# -foreach sfile (SCCS/s.*) - # get rid of the "s." at the beginning of the name - set file = `echo $sfile:t | sed -e "s/^..//"` - - # work on each rev of that file in ascending order - set firsttime = 1 - sccs prs $file | grep "^D " | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u +0 +1 +2 +3 +4 +5 +6 +7 +8 | sed -e 's/ /./g' > $revfile - foreach rev (`cat $revfile`) - if ($status != 0) goto ERROR - - # get file into current dir and get stats - 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 "" - echo "==> file $file, rev=$rev, date=$date, author=$author" - sccs edit -r$rev $file >>& $logfile - if ($status != 0) goto ERROR - echo checked out of SCCS - - # add RCS keywords in place of SCCS keywords - sed -f $sedfile $file > $tmpfile - if ($status != 0) goto ERROR - echo performed keyword substitutions - cp $tmpfile $file - - # check file into RCS - if ($firsttime) then - set firsttime = 0 - if ($nodesc) then - echo about to do ci - echo ci -f -r$rev -d"$date" -w$author -t$emptyfile $file - ci -f -r$rev -d"$date" -w$author -t$emptyfile $file < $initialfile >>& $logfile - if ($status != 0) goto ERROR - echo initial rev checked into RCS without description - else - echo "" - echo Enter a brief description of the file $file \(end w/ Ctrl-D\): - cat > $tmpfile - ci -f -r$rev -d"$date" -w$author -t$tmpfile $file < $initialfile >>& $logfile - if ($status != 0) goto ERROR - echo initial rev checked into RCS - endif - else - # get RCS lock - set lckrev = `echo $rev | sed -e 's/\.[0-9]*$//'` - if ("$lckrev" =~ [0-9]*.*) then - # need to lock the brach -- it is OK if the lock fails - rcs -l$lckrev $file >>& $logfile - else - # need to lock the trunk -- must succeed - rcs -l $file >>& $logfile - if ($status != 0) goto ERROR - endif - echo got lock - sccs prs -r$rev $file | grep "." > $tmpfile - # it's OK if grep fails here and gives status == 1 - # put the delta message in $tmpfile - ed $tmpfile >>& $logfile <<EOF -/COMMENTS -1,.d -w -q -EOF - ci -f -r$rev -d"$date" -w$author $file < $tmpfile >>& $logfile - if ($status != 0) goto ERROR - echo checked into RCS - endif - sccs unedit $file >>& $logfile - if ($status != 0) goto ERROR - end - rm -f $file -end - - -############################################################ -# Clean up -# -echo cleaning up... -mv SCCS old-SCCS -rm -f $tmpfile $emptyfile $initialfile $sedfile -echo =================================================== -echo " Conversion Completed Successfully" -echo "" -echo " SCCS history now in old-SCCS/" -echo =================================================== -set exitval = 0 -goto cleanup - -ERROR: -foreach f (`sccs tell`) - sccs unedit $f -end -echo "" -echo "" -echo Danger\! Danger\! -echo Some command exited with a non-zero exit status. -echo Log file exists in $logfile. -echo "" -echo Incomplete history in ./RCS -- remove it -echo Original unchanged history in ./SCCS -set exitval = 1 - -cleanup: -# leave log file -rm -f $tmpfile $emptyfile $initialfile $sedfile $revfile - -exit $exitval diff --git a/gnu/usr.bin/cvs/cvs/Makefile b/gnu/usr.bin/cvs/cvs/Makefile deleted file mode 100644 index 5be0fbe3238c..000000000000 --- a/gnu/usr.bin/cvs/cvs/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -PROG = cvs -CFLAGS += -I${.CURDIR}/../lib \ - -DDIRENT -DSTDC_HEADERS -DPOSIX -DBROKEN_SIGISMEMBER \ - -DFTIME_MISSING -DHAVE_TIMEZONE -DUTIME_NULL_MISSING - -LDADD= -L${.CURDIR}/../lib/obj -lcvs - -SRCS = add.c admin.c checkin.c checkout.c classify.c commit.c \ -create_adm.c diff.c entries.c find_names.c history.c ignore.c \ -import.c lock.c log.c logmsg.c main.c rcs.c modules.c \ -no_diff.c parseinfo.c patch.c recurse.c release.c remove.c repos.c rtag.c \ -status.c tag.c update.c vers_ts.c version.c - -MAN1= cvs.0 -MAN5= cvs.0 - -.include <bsd.prog.mk> -.include "../../Makefile.inc" diff --git a/gnu/usr.bin/cvs/cvs/config.h b/gnu/usr.bin/cvs/cvs/config.h deleted file mode 100644 index b3bee5f97b09..000000000000 --- a/gnu/usr.bin/cvs/cvs/config.h +++ /dev/null @@ -1,217 +0,0 @@ -/* @(#)config.h 1.19 92/03/31 */ - -/* - * Copyright (c) 1992, Brian Berliner and Jeff Polk - * Copyright (c) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS 1.3 kit. - * - * This file holds (most of) the configuration tweaks that can be made to - * customize CVS for your site. CVS comes configured for a typical SunOS 4.x - * environment. The comments for each configurable item are intended to be - * self-explanatory. All #defines are tested first to see if an over-riding - * option was specified on the "make" command line. - * - * If special libraries are needed, you will have to edit the Makefile.in file - * or the configure script directly. Sorry. - */ - -/* - * CVS provides the most features when used in conjunction with the Version-5 - * release of RCS. Thus, it is the default. This also assumes that GNU diff - * Version-1.15 is being used as well -- you will have to configure your RCS - * V5 release separately to make this the case. If you do not have RCS V5 and - * GNU diff V1.15, comment out this define. You should not try mixing and - * matching other combinations of these tools. - */ -#ifndef HAVE_RCS5 -#define HAVE_RCS5 -#endif - -/* - * If, before installing this version of CVS, you were running RCS V4 AND you - * are installing this CVS and RCS V5 and GNU diff 1.15 all at the same time, - * you should turn on the following define. It only exists to try to do - * reasonable things with your existing checked out files when you upgrade to - * RCS V5, since the keyword expansion formats have changed with RCS V5. - * - * If you already have been running with RCS5, or haven't been running with CVS - * yet at all, or are sticking with RCS V4 for now, leave the commented out. - */ -#ifndef HAD_RCS4 -/* #define HAD_RCS4 */ -#endif - -/* - * For portability and heterogeneity reasons, CVS is shipped by default using - * my own text-file version of the ndbm database library in the src/myndbm.c - * file. If you want better performance and are not concerned about - * heterogeneous hosts accessing your modules file, turn this option off. - */ -#ifndef MY_NDBM -#define MY_NDBM -#endif - -/* - * The "diff" program to execute when creating patch output. This "diff" - * must support the "-c" option for context diffing. Specify a full pathname - * if your site wants to use a particular diff. If you are using the GNU - * version of diff (version 1.15 or later), this should be "diff -a". - * - * NOTE: this program is only used for the ``patch'' sub-command. The other - * commands use rcsdiff which will use whatever version of diff was specified - * when rcsdiff was built on your system. - */ -#ifndef DIFF -#define DIFF "diff" -#endif - -/* - * The "grep" program to execute when checking to see if a merged file had - * any conflicts. This "grep" must support the "-s" option and a standard - * regular expression as an argument. Specify a full pathname if your site - * wants to use a particular grep. - */ -#ifndef GREP -#define GREP "grep" -#endif - -/* - * The "rm" program to execute when pruning directories that are not part of - * a release. This "rm" must support the "-fr" options. Specify a full - * pathname if your site wants to use a particular rm. - */ -#ifndef RM -#define RM "rm" -#endif - -/* - * The "sort" program to execute when displaying the module database. Specify - * a full pathname if your site wants to use a particular sort. - */ -#ifndef SORT -#define SORT "sort" -#endif - -/* - * By default, RCS programs are executed with the shell or through execlp(), - * so the user's PATH environment variable is searched. If you'd like to - * bind all RCS programs to a certain directory (perhaps one not in most - * people's PATH) then set the default in RCSBIN_DFLT. Note that setting - * this here will cause all RCS programs to be executed from this directory, - * unless the user overrides the default with the RCSBIN environment variable - * or the "-b" option to CVS. - * - * This define should be either the empty string ("") or a full pathname to the - * directory containing all the installed programs from the RCS distribution. - */ -#ifndef RCSBIN_DFLT -#define RCSBIN_DFLT "" -#endif - -/* - * The default editor to use, if one does not specify the "-e" option to cvs, - * or does not have an EDITOR environment variable. I set this to just "vi", - * and use the shell to find where "vi" actually is. This allows sites with - * /usr/bin/vi or /usr/ucb/vi to work equally well (assuming that your PATH - * is reasonable). - */ -#ifndef EDITOR_DFLT -#define EDITOR_DFLT "vi" -#endif - -/* - * The Repository file holds the path to the directory within the source - * repository that contains the RCS ,v files for each CVS working directory. - * This path is either a full-path or a path relative to CVSROOT. - * - * The only advantage that I can see to having a relative path is that One can - * change the physical location of the master source repository, change one's - * CVSROOT environment variable, and CVS will work without problems. I - * recommend using full-paths. - */ -#ifndef RELATIVE_REPOS -/* #define RELATIVE_REPOS */ -#endif - -/* - * When committing or importing files, you must enter a log message. - * Normally, you can do this either via the -m flag on the command line or an - * editor will be started for you. If you like to use logging templates (the - * rcsinfo file within the $CVSROOT/CVSROOT directory), you might want to - * force people to use the editor even if they specify a message with -m. - * Enabling FORCE_USE_EDITOR will cause the -m message to be appended to the - * temp file when the editor is started. - */ -#ifndef FORCE_USE_EDITOR -/* #define FORCE_USE_EDITOR */ -#endif - -/* - * When locking the repository, some sites like to remove locks and assume - * the program that created them went away if the lock has existed for a long - * time. This used to be the default for previous versions of CVS. CVS now - * attempts to be much more robust, so lock files should not be left around - * by mistake. The new behaviour will never remove old locks (they must now - * be removed by hand). Enabling CVS_FUDGELOCKS will cause CVS to remove - * locks that are older than CVSLCKAGE seconds. - * Use of this option is NOT recommended. - */ -#ifndef CVS_FUDGELOCKS -/* #define CVS_FUDGELOCKS */ -#endif - -/* - * When committing a permanent change, CVS and RCS make a log entry of - * who committed the change. If you are committing the change logged in - * as "root" (not under "su" or other root-priv giving program), CVS/RCS - * cannot determine who is actually making the change. - * - * As such, by default, CVS disallows changes to be committed by users - * logged in as "root". You can disable this option by commenting - * out the lines below. - */ -#ifndef CVS_BADROOT -#define CVS_BADROOT -#endif - -/* - * The "cvs diff" command accepts all the single-character options that GNU - * diff (1.15) accepts. Except -D. GNU diff uses -D as a way to put - * cpp-style #define's around the output differences. CVS, by default, uses - * -D to specify a free-form date (like "cvs diff -D '1 week ago'"). If - * you would prefer that the -D option of "cvs diff" work like the GNU diff - * option, then comment out this define. - */ -#ifndef CVS_DIFFDATE -#define CVS_DIFFDATE -#endif - -/* End of CVS configuration section */ - -/* - * Externs that are included in libc, but are used frequently enough to - * warrant defining here. - */ -#ifndef STDC_HEADERS -extern void exit (); -#endif - -#ifndef getwd -extern char *getwd (); -#endif - -/* - * Some UNIX distributions don't include these in their stat.h Defined here - * because "config.h" is always included last. - */ -#ifndef S_IWRITE -#define S_IWRITE 0000200 /* write permission, owner */ -#endif -#ifndef S_IWGRP -#define S_IWGRP 0000020 /* write permission, grougroup */ -#endif -#ifndef S_IWOTH -#define S_IWOTH 0000002 /* write permission, other */ -#endif diff --git a/gnu/usr.bin/cvs/cvs/convert.sh b/gnu/usr.bin/cvs/cvs/convert.sh deleted file mode 100644 index 94bbdcc8b551..000000000000 --- a/gnu/usr.bin/cvs/cvs/convert.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -# -# short script to convert cvs repositories to support file death. -# - -WORKDIR=/tmp/$$-cvs-convert -mkdir ${WORKDIR} -cd ${WORKDIR} - -case $# in -1) ;; -*) - echo Usage: convert repository 2>&1 - exit 1 - ;; -esac - -attics=`find $1 -name Attic -print` - -for i in ${attics} ; do - mkdir $i/SAVE - for j in $i/*,v ; do - echo $j - cp $j $i/SAVE - co -l $j - ci -K -m"recording file death" $j - done -done diff --git a/gnu/usr.bin/cvs/cvs/cvsbug.sh b/gnu/usr.bin/cvs/cvs/cvsbug.sh deleted file mode 100644 index 8c6a5bbd36b1..000000000000 --- a/gnu/usr.bin/cvs/cvs/cvsbug.sh +++ /dev/null @@ -1,533 +0,0 @@ -#!/bin/sh -# Submit a problem report to a GNATS site. -# Copyright (C) 1993 Free Software Foundation, Inc. -# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a -# version written by Heinz G. Seidl (hgs@ide.com). -# -# This file is part of GNU GNATS. -# Modified by Berliner for CVS. -# $CVSid: @(#)cvsbug.sh 1.2 94/10/22 $ -# -# GNU GNATS is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# GNU GNATS is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU GNATS; see the file COPYING. If not, write to -# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - -# The version of this send-pr. -VERSION=3.2 - -# The submitter-id for your site. -SUBMITTER=net - -## # Where the GNATS directory lives, if at all. -## [ -z "$GNATS_ROOT" ] && -## GNATS_ROOT=/usr/local/lib/gnats/gnats-db - -# The default mail address for PR submissions. -GNATS_ADDR=bug-cvs@prep.ai.mit.edu - -## # Where the gnats category tree lives. -## DATADIR=/usr/local/lib - -## # If we've been moved around, try using GCC_EXEC_PREFIX. -## [ ! -d $DATADIR/gnats -a -d "$GCC_EXEC_PREFIX" ] && DATADIR=${GCC_EXEC_PREFIX}.. - -# The default release for this host. -DEFAULT_RELEASE="cvs-1.4A2" - -# The default organization. -DEFAULT_ORGANIZATION="net" - -## # The default site to look for. -## GNATS_SITE=unknown - -## # Newer config information? -## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config - -# What mailer to use. This must come after the config file, since it is -# host-dependent. -MAIL_AGENT="/usr/lib/sendmail -oi -t" -MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'` -if [ ! -f "$MAILER" ] ; then - echo "$COMMAND: Cannot file mail program \"$MAILER\"." - echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file." - exit 1 -fi - -if test "`echo -n foo`" = foo ; then - ECHON=bsd -elif test "`echo 'foo\c'`" = foo ; then - ECHON=sysv -else - ECHON=none -fi - -if [ $ECHON = bsd ] ; then - ECHON1="echo -n" - ECHON2= -elif [ $ECHON = sysv ] ; then - ECHON1=echo - ECHON2='\c' -else - ECHON1=echo - ECHON2= -fi - -# - -[ -z "$TMPDIR" ] && TMPDIR=/tmp - -TEMP=$TMPDIR/p$$ -BAD=$TMPDIR/pbad$$ -REF=$TMPDIR/pf$$ - -if [ -z "$LOGNAME" -a -n "$USER" ]; then - LOGNAME=$USER -fi - -FROM="$LOGNAME" -REPLY_TO="$LOGNAME" - -# Find out the name of the originator of this PR. -if [ -n "$NAME" ]; then - ORIGINATOR="$NAME" -elif [ -f $HOME/.fullname ]; then - ORIGINATOR="`sed -e '1q' $HOME/.fullname`" -elif [ -f /bin/domainname ]; then - if [ "`/bin/domainname`" != "" -a -f /usr/bin/ypcat ]; then - # Must use temp file due to incompatibilities in quoting behavior - # and to protect shell metacharacters in the expansion of $LOGNAME - /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" | - cut -f5 -d':' | sed -e 's/,.*//' > $TEMP - ORIGINATOR="`cat $TEMP`" - rm -f $TEMP - fi -fi - -if [ "$ORIGINATOR" = "" ]; then - grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP - ORIGINATOR="`cat $TEMP`" - rm -f $TEMP -fi - -if [ -n "$ORGANIZATION" ]; then - if [ -f "$ORGANIZATION" ]; then - ORGANIZATION="`cat $ORGANIZATION`" - fi -else - if [ -n "$DEFAULT_ORGANIZATION" ]; then - ORGANIZATION="$DEFAULT_ORGANIZATION" - elif [ -f $HOME/.organization ]; then - ORGANIZATION="`cat $HOME/.organization`" - elif [ -f $HOME/.signature ]; then - ORGANIZATION="`cat $HOME/.signature`" - fi -fi - -# If they don't have a preferred editor set, then use -if [ -z "$VISUAL" ]; then - if [ -z "$EDITOR" ]; then - EDIT=vi - else - EDIT="$EDITOR" - fi -else - EDIT="$VISUAL" -fi - -# Find out some information. -SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \ - ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo ""` -ARCH=`[ -f /bin/arch ] && /bin/arch` -MACHINE=`[ -f /bin/machine ] && /bin/machine` - -COMMAND=`echo $0 | sed -e 's,.*/,,'` -## USAGE="Usage: $COMMAND [-PVL] [-t address] [-f filename] [--request-id] -USAGE="Usage: $COMMAND [-PVL] -[--version]" -REMOVE= -BATCH= - -while [ $# -gt 0 ]; do - case "$1" in - -r) ;; # Ignore for backward compat. -## -t | --to) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi -## shift ; GNATS_ADDR="$1" -## EXPLICIT_GNATS_ADDR=true -## ;; -## -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi -## shift ; IN_FILE="$1" -## if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then -## echo "$COMMAND: cannot read $IN_FILE" -## exit 1 -## fi -## ;; - -b | --batch) BATCH=true ;; - -p | -P | --print) PRINT=true ;; - -L | --list) FORMAT=norm ;; - -l | -CL | --lisp) FORMAT=lisp ;; -## --request-id) REQUEST_ID=true ;; - -h | --help) echo "$USAGE"; exit 0 ;; - -V | --version) echo "$VERSION"; exit 0 ;; - -*) echo "$USAGE" ; exit 1 ;; - *) echo "$USAGE" ; exit 1 -## if [ -z "$USER_GNATS_SITE" ]; then -## if [ ! -r "$DATADIR/gnats/$1" ]; then -## echo "$COMMAND: the GNATS site $1 does not have a categories list." -## exit 1 -## else -## # The site name is the alias they'll have to have created. -## USER_GNATS_SITE=$1 -## fi -## else -## echo "$USAGE" ; exit 1 -## fi - ;; - esac - shift -done - -if [ -n "$USER_GNATS_SITE" ]; then - GNATS_SITE=$USER_GNATS_SITE - GNATS_ADDR=$USER_GNATS_SITE-gnats -fi - -if [ "$SUBMITTER" = "unknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then - cat << '__EOF__' -It seems that send-pr is not installed with your unique submitter-id. -You need to run - - install-sid YOUR-SID - -where YOUR-SID is the identification code you received with `send-pr'. -`send-pr' will automatically insert this value into the template field -`>Submitter-Id'. If you've downloaded `send-pr' from the Net, use `net' -for this value. If you do not know your id, run `send-pr --request-id' to -get one from your support site. -__EOF__ - exit 1 -fi - -## if [ -r "$DATADIR/gnats/$GNATS_SITE" ]; then -## CATEGORIES=`grep -v '^#' $DATADIR/gnats/$GNATS_SITE | sort` -## else -## echo "$COMMAND: could not read $DATADIR/gnats/$GNATS_SITE for categories list." -## exit 1 -## fi -CATEGORIES="contrib cvs doc pcl-cvs portability" - -if [ -z "$CATEGORIES" ]; then - echo "$COMMAND: the categories list for $GNATS_SITE was empty!" - exit 1 -fi - -case "$FORMAT" in - lisp) echo "$CATEGORIES" | \ - awk 'BEGIN {printf "( "} {printf "(\"%s\") ",$0} END {printf ")\n"}' - exit 0 - ;; - norm) l=`echo "$CATEGORIES" | \ - awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } } - END {print max + 1;}'` - c=`expr 70 / $l` - if [ $c -eq 0 ]; then c=1; fi - echo "$CATEGORIES" | \ - awk 'BEGIN {print "Known categories:"; i = 0 } - { printf ("%-'$l'.'$l's", $0); if ((++i % '$c') == 0) { print "" } } - END { print ""; }' - exit 0 - ;; -esac - -ORIGINATOR_C='<name of the PR author (one line)>' -ORGANIZATION_C='<organization of PR author (multiple lines)>' -CONFIDENTIAL_C='<[ yes | no ] (one line)>' -SYNOPSIS_C='<synopsis of the problem (one line)>' -SEVERITY_C='<[ non-critical | serious | critical ] (one line)>' -PRIORITY_C='<[ low | medium | high ] (one line)>' -CATEGORY_C='<name of the product (one line)>' -CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>' -RELEASE_C='<release number or tag (one line)>' -ENVIRONMENT_C='<machine, os, target, libraries (multiple lines)>' -DESCRIPTION_C='<precise description of the problem (multiple lines)>' -HOW_TO_REPEAT_C='<code/input/activities to reproduce the problem (multiple lines)>' -FIX_C='<how to correct or work around the problem, if known (multiple lines)>' - -# Catch some signals. ($xs kludge needed by Sun /bin/sh) -xs=0 -trap 'rm -f $REF $TEMP; exit $xs' 0 -trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15 - -# If they told us to use a specific file, then do so. -if [ -n "$IN_FILE" ]; then - if [ "$IN_FILE" = "-" ]; then - # The PR is coming from the standard input. - if [ -n "$EXPLICIT_GNATS_ADDR" ]; then - sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" > $TEMP - else - cat > $TEMP - fi - else - # Use the file they named. - if [ -n "$EXPLICIT_GNATS_ADDR" ]; then - sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" $IN_FILE > $TEMP - else - cat $IN_FILE > $TEMP - fi - fi -else - - if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then - # If their PR_FORM points to a bogus entry, then bail. - if [ ! -f "$PR_FORM" -o ! -r "$PR_FORM" -o ! -s "$PR_FORM" ]; then - echo "$COMMAND: can't seem to read your template file (\`$PR_FORM'), ignoring PR_FORM" - sleep 1 - PRINT_INTERN=bad_prform - fi - fi - - if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then - cp $PR_FORM $TEMP || - ( echo "$COMMAND: could not copy $PR_FORM" ; xs=1; exit ) - else - for file in $TEMP $REF ; do - cat > $file << '__EOF__' -SEND-PR: -*- send-pr -*- -SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as -SEND-PR: will all comments (text enclosed in `<' and `>'). -SEND-PR: -SEND-PR: Choose from the following categories: -SEND-PR: -__EOF__ - - # Format the categories so they fit onto lines. - l=`echo "$CATEGORIES" | \ - awk 'BEGIN {max = 0; } { if (length($0) > max) { max = length($0); } } - END {print max + 1;}'` - c=`expr 61 / $l` - if [ $c -eq 0 ]; then c=1; fi - echo "$CATEGORIES" | \ - awk 'BEGIN {printf "SEND-PR: "; i = 0 } - { printf ("%-'$l'.'$l's", $0); - if ((++i % '$c') == 0) { printf "\nSEND-PR: " } } - END { printf "\nSEND-PR:\n"; }' >> $file - - cat >> $file << __EOF__ -To: $GNATS_ADDR -Subject: -From: $FROM -Reply-To: $REPLY_TO -X-send-pr-version: $VERSION - - ->Submitter-Id: $SUBMITTER ->Originator: $ORIGINATOR ->Organization: -` - if [ -n "$ORGANIZATION" ]; then - echo "$ORGANIZATION" - else - echo " $ORGANIZATION_C" ; - fi ; -` ->Confidential: $CONFIDENTIAL_C ->Synopsis: $SYNOPSIS_C ->Severity: $SEVERITY_C ->Priority: $PRIORITY_C ->Category: $CATEGORY_C ->Class: $CLASS_C ->Release: `if [ -n "$DEFAULT_RELEASE" ]; then - echo "$DEFAULT_RELEASE" - else - echo " $RELEASE_C" - fi; ` ->Environment: - $ENVIRONMENT_C -`[ -n "$SYSTEM" ] && echo System: $SYSTEM` -`[ -n "$ARCH" ] && echo Architecture: $ARCH` -`[ -n "$MACHINE" ] && echo Machine: $MACHINE` ->Description: - $DESCRIPTION_C ->How-To-Repeat: - $HOW_TO_REPEAT_C ->Fix: - $FIX_C -__EOF__ - done - fi - - if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then - cat $TEMP - xs=0; exit - fi - - chmod u+w $TEMP - if [ -z "$REQUEST_ID" ]; then - eval $EDIT $TEMP - else - ed -s $TEMP << '__EOF__' -/^Subject/s/^Subject:.*/Subject: request for a customer id/ -/^>Category/s/^>Category:.*/>Category: send-pr/ -w -q -__EOF__ - fi - - if cmp -s $REF $TEMP ; then - echo "$COMMAND: problem report not filled out, therefore not sent" - xs=1; exit - fi -fi - -# -# Check the enumeration fields - -# This is a "sed-subroutine" with one keyword parameter -# (with workaround for Sun sed bug) -# -SED_CMD=' -/$PATTERN/{ -s||| -s|<.*>|| -s|^[ ]*|| -s|[ ]*$|| -p -q -}' - - -while [ -z "$REQUEST_ID" ]; do - CNT=0 - - # 1) Confidential - # - PATTERN=">Confidential:" - CONFIDENTIAL=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$CONFIDENTIAL" in - ""|yes|no) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$CONFIDENTIAL' is not a valid value for \`Confidential'." ;; - esac - # - # 2) Severity - # - PATTERN=">Severity:" - SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$SEVERITY" in - ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'." - esac - # - # 3) Priority - # - PATTERN=">Priority:" - PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$PRIORITY" in - ""|low|medium|high) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'." - esac - # - # 4) Category - # - PATTERN=">Category:" - CATEGORY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - FOUND= - for C in $CATEGORIES - do - if [ "$C" = "$CATEGORY" ]; then FOUND=true ; break ; fi - done - if [ -n "$FOUND" ]; then - CNT=`expr $CNT + 1` - else - if [ -z "$CATEGORY" ]; then - echo "$COMMAND: you must include a Category: field in your report." - else - echo "$COMMAND: \`$CATEGORY' is not a known category." - fi - fi - # - # 5) Class - # - PATTERN=">Class:" - CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$CLASS" in - ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'." - esac - - [ $CNT -lt 5 -a -z "$BATCH" ] && - echo "Errors were found with the problem report." - - while true; do - if [ -z "$BATCH" ]; then - $ECHON1 "a)bort, e)dit or s)end? $ECHON2" - read input - else - if [ $CNT -eq 5 ]; then - input=s - else - input=a - fi - fi - case "$input" in - a*) - if [ -z "$BATCH" ]; then - echo "$COMMAND: the problem report remains in $BAD and is not sent." - mv $TEMP $BAD - else - echo "$COMMAND: the problem report is not sent." - fi - xs=1; exit - ;; - e*) - eval $EDIT $TEMP - continue 2 - ;; - s*) - break 2 - ;; - esac - done -done -# -# Remove comments and send the problem report -# (we have to use patterns, where the comment contains regex chars) -# -# /^>Originator:/s;$ORIGINATOR;; -sed -e " -/^SEND-PR:/d -/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;; -/^>Confidential:/s;<.*>;; -/^>Synopsis:/s;$SYNOPSIS_C;; -/^>Severity:/s;<.*>;; -/^>Priority:/s;<.*>;; -/^>Category:/s;$CATEGORY_C;; -/^>Class:/s;<.*>;; -/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;; -/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;; -/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;; -/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;; -/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;; -" $TEMP > $REF - -if $MAIL_AGENT < $REF; then - echo "$COMMAND: problem report sent" - xs=0; exit -else - echo "$COMMAND: mysterious mail failure." - if [ -z "$BATCH" ]; then - echo "$COMMAND: the problem report remains in $BAD and is not sent." - mv $REF $BAD - else - echo "$COMMAND: the problem report is not sent." - fi - xs=1; exit -fi diff --git a/gnu/usr.bin/cvs/cvs/sanity.el b/gnu/usr.bin/cvs/cvs/sanity.el deleted file mode 100644 index a1470570a011..000000000000 --- a/gnu/usr.bin/cvs/cvs/sanity.el +++ /dev/null @@ -1,18 +0,0 @@ -;;;; -*- lisp-interaction -*- -;;;; Time-stamp: <29 Nov 93 14:25:28, by rich@sendai.cygnus.com> - -(defun reset-fail-counter (arg) - (interactive "p") - (setq fail-counter arg) - (message (concat "fail-counter = " (int-to-string arg)))) - - -(defun inc-next-fail-counter nil - (interactive) - (search-forward "failed test ") - (kill-word 1) - (insert-string fail-counter) - (setq fail-counter (+ 1 fail-counter))) - -(global-set-key [f15] 'reset-fail-counter) -(global-set-key [f16] 'inc-next-fail-counter) diff --git a/gnu/usr.bin/cvs/cvs/version.c b/gnu/usr.bin/cvs/cvs/version.c deleted file mode 100644 index 18a9d14f2b3d..000000000000 --- a/gnu/usr.bin/cvs/cvs/version.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 1992, Brian Berliner and Jeff Polk - * Copyright (c) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS 1.3 kit. - * - * version.c - the CVS version number - */ - -char *version_string = "\nConcurrent Versions System (CVS) 1.3\n"; diff --git a/gnu/usr.bin/cvs/doc/cvs.ms b/gnu/usr.bin/cvs/doc/cvs.ms deleted file mode 100644 index 567179b393f8..000000000000 --- a/gnu/usr.bin/cvs/doc/cvs.ms +++ /dev/null @@ -1,1073 +0,0 @@ -.\" soelim cvs.ms | pic | tbl | troff -ms -.\" @(#)cvs.ms 1.2 92/01/30 -.\" -.\" troff source to the cvs USENIX article, Winter 1990, Washington, D.C. -.\" Copyright (c) 1989, Brian Berliner -.\" -.\" This program is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 1, or (at your option) -.\" any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program; if not, write to the Free Software -.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -.\" -.\" The author can be reached at: berliner@prisma.com -.\" -.de SP -.if n .sp -.if t .sp .5 -.. -.de hl -.br -.in +0.5i -\l'\\n(LLu-1i' -.in -0.5i -.sp -.. -.OH "" -.nr PS 11 -.nr PO 1.25i -.pl -0.2i -.TL -.ps 14 -.ft B -.nf -CVS II: -Parallelizing Software Development -.fi -.ft -.ps -.AU -.ps 12 -.ft I -Brian Berliner -.ft -.ps -.AI -.ps 12 -.ft I -Prisma, Inc. -5465 Mark Dabling Blvd. -Colorado Springs, CO 80918 -berliner@prisma.com -.ft -.ps -.AB -The program described in this paper fills a need in the UNIX -community for a freely available tool to manage software revision and -release control in a multi-developer, multi-directory, multi-group -environment. -This tool also addresses the increasing need for tracking third-party vendor -source distributions while trying to maintain local modifications to -earlier releases. -.AE -.NH -Background -.PP -In large software development projects, it is usually necessary for more -than one software developer to be modifying (usually different) modules of the -code at the same time. -Some of these code modifications are done in an -experimental sense, at least until the code functions correctly, and some -testing of the entire program is usually necessary. -Then, the modifications are returned to a master source repository -so that others in the project can -enjoy the new bug-fix or functionality. -In order to manage such a project, some sort of revision control system is -necessary. -.PP -Specifically, UNIX\** -.FS -UNIX is a registered trademark of AT&T. -.FE -kernel development is an excellent example of the -problems that an adequate revision control system must address. -The SunOS\** -.FS -SunOS is a trademark of Sun Microsystems, Inc. -.FE -kernel is composed of over a thousand files spread across a -hierarchy of dozens of directories.\** -.FS -Yes, the SunOS 4.0 kernel is composed of over a \fIthousand\fP files! -.FE -Pieces of the kernel must be edited -by many software developers within an organization. -While undesirable in -theory, it is not uncommon to have two or more people making -modifications to the same file within the kernel sources in -order to facilitate a desired change. -Existing revision control systems like -.SM -RCS -.LG -[Tichy] or -.SM -SCCS -.LG -[Bell] serialize file modifications by -allowing only one developer to have a writable copy of a particular file at -any one point in time. -That developer is said to -have \*Qlocked\*U the file for his exclusive use, and no other developer is -allowed to check out a writable copy of the file until the locking -developer has finished impeding others' productivity. -Development pressures of productivity and deadlines -often force organizations to require that multiple developers be able to -simultaneously edit -copies of the same revision controlled file. -.PP -The necessity for multiple developers to modify the same file concurrently -questions the value of serialization-based policies in traditional revision -control. -This paper discusses the approach that -Prisma took in adapting a standard revision control system, -.SM -RCS\c -.LG -, along with an existing public-domain collection of shell scripts that sits -atop -.SM -RCS -.LG -and provides the basic conflict-resolution algorithms. -The resulting -program, \fBcvs\fP, addresses not only the issue of conflict-resolution in -a multi-developer open-editing environment, but also the issues of -software release control and vendor source support and integration. -.NH -The CVS Program -.PP -\fBcvs\fP -(Concurrent Versions System) -is a front end to the -.SM -RCS -.LG -revision control system which extends -the notion of revision control from a collection of files in a single -directory to a hierarchical collection of directories each containing -revision controlled files. -Directories and files in the \fBcvs\fP system can be combined together in -many ways to form a software release. -\fBcvs\fP -provides the functions necessary to manage these software releases and to -control the concurrent editing of source files among multiple software -developers. -.PP -The six major features of \fBcvs\fP are listed below, and will be -described in more detail in the following sections: -.RS -.IP 1. -Concurrent access and conflict-resolution algorithms to guarantee that -source changes are not \*Qlost.\*U -.IP 2. -Support for tracking third-party vendor source distributions while -maintaining the local modifications made to those sources. -.IP 3. -A flexible module database that provides a symbolic mapping of names to -components of a larger software distribution. -This symbolic mapping provides for location independence within the software -release and, for example, allows one to check out a copy of the \*Qdiff\*U -program without ever knowing that the sources to \*Qdiff\*U actually reside -in the \*Qbin/diff\*U directory. -.IP 4. -Configurable logging support allows all \*Qcommitted\*U source file changes -to be logged using an arbitrary program to save the log messages in a file, -notesfile, or news database. -.IP 5. -A software release can be symbolically tagged and checked out at any time -based on that tag. -An exact copy of a previous software release can be checked out at -any time, \fIregardless\fP of whether files or directories have been -added/removed from the \*Qcurrent\*U software release. -As well, -a \*Qdate\*U can be used to check out the \fIexact\fP version of the software -release as of the specified date. -.IP 6. -A \*Qpatch\*U format file [Wall] can be produced between two software -releases, even if the releases span multiple directories. -.RE -.PP -The sources maintained by \fBcvs\fP are kept within a single directory -hierarchy known as the \*Qsource repository.\*U -This \*Qsource repository\*U holds the actual -.SM -RCS -.LG -\*Q,v\*U files directly, as well as a special per-repository directory -(\c -.SM -CVSROOT.adm\c -.LG -) which contains a small number of administrative files that describe the -repository and how it can be accessed. -See Figure 1 for a picture of the \fBcvs\fP tree. -.KF -.hl -.DS B -.PS -line from 4.112,9.200 to 5.550,8.887 -line from 5.447,8.884 to 5.550,8.887 to 5.458,8.933 -line from 4.112,9.200 to 4.550,8.950 -line from 4.451,8.978 to 4.550,8.950 to 4.476,9.021 -line from 4.112,9.200 to 3.737,8.887 -line from 3.798,8.971 to 3.737,8.887 to 3.830,8.932 -line from 3.612,8.762 to 4.737,8.137 -line from 4.638,8.164 to 4.737,8.137 to 4.662,8.208 -line from 3.612,8.762 to 3.737,8.137 -line from 3.693,8.231 to 3.737,8.137 to 3.742,8.240 -line from 3.612,8.762 to 2.612,8.200 -line from 2.687,8.271 to 2.612,8.200 to 2.712,8.227 -line from 2.362,9.262 to 2.737,8.950 -line from 2.645,8.995 to 2.737,8.950 to 2.677,9.033 -line from 2.362,9.262 to 1.925,8.950 -line from 1.992,9.028 to 1.925,8.950 to 2.021,8.988 -line from 3.362,9.762 to 4.050,9.387 -line from 3.950,9.413 to 4.050,9.387 to 3.974,9.457 -line from 3.362,9.762 to 2.487,9.387 -line from 2.570,9.450 to 2.487,9.387 to 2.589,9.404 -.ps 11 -"newfs.c,v" at 4.487,8.043 ljust -.ps 11 -"mkfs.c,v" at 3.487,8.043 ljust -.ps 11 -"Makefile,v" at 2.237,8.043 ljust -.ps 11 -"newfs" at 3.487,8.793 ljust -.ps 11 -"halt.c,v" at 5.487,8.793 ljust -.ps 11 -"Makefile,v" at 4.237,8.793 ljust -.ps 11 -"modules,v" at 2.487,8.793 ljust -.ps 11 -"loginfo,v" at 1.488,8.793 ljust -.ps 11 -"etc" at 3.987,9.293 ljust -.ps 11 -"CVSROOT.adm" at 1.988,9.293 ljust -.ps 11 -"/src/master" at 2.987,9.793 ljust -.PE -.DE -.hl -.ce 100 -.LG -\fBFigure 1.\fP -.SM -\fBcvs\fP Source Repository -.ce 0 -.sp -.KE -.NH 2 -Software Conflict Resolution\** -.FS -The basic conflict-resolution algorithms -used in the \fBcvs\fP program find their roots -in the original work done by Dick Grune at Vrije Universiteit in Amsterdam -and posted to \fBcomp.sources.unix\fP in the volume 6 release sometime in 1986. -This original version of \fBcvs\fP was a collection of shell scripts that -combined to form a front end to the -.SM -RCS -.LG -programs. -.FE -.PP -\fBcvs\fP allows several software developers to edit personal copies of a -revision controlled file concurrently. -The revision number of each checked out file is maintained independently -for each user, and \fBcvs\fP forces the checked out file to be current with -the \*Qhead\*U revision before it can be \*Qcommitted\*U as a permanent change. -A checked out file is brought up-to-date with the \*Qhead\*U revision using -the \*Qupdate\*U command of \fBcvs\fP. -This command compares the \*Qhead\*U revision number with that of the user's -file and performs an -.SM -RCS -.LG -merge operation if they are not the same. -The result of the merge is a file that contains the user's modifications -and those modifications that were \*Qcommitted\*U after the user -checked out his version of the file (as well as a backup copy of the -user's original file). -\fBcvs\fP points out any conflicts during the merge. -It is the user's responsibility to resolve these conflicts -and to \*Qcommit\*U his/her changes when ready. -.PP -Although the \fBcvs\fP conflict-resolution algorithm was defined in 1986, -it is remarkably similar to the \*QCopy-Modify-Merge\*U scenario included -with NSE\** -.FS -NSE is the Network Software Environment, a product of Sun Microsystems, Inc. -.FE -and described in [Honda] and [Courington]. -The following explanation from [Honda] also applies to \fBcvs\fP: -.QP -Simply stated, a developer copies an object without locking it, modifies -the copy, and then merges the modified copy with the original. -This paradigm allows developers to work in isolation from one another since -changes are made to copies of objects. -Because locks are not used, development is not serialized and can proceed -in parallel. -Developers, however, must merge objects after the changes have been made. -In particular, a developer must resolve conflicts when the same object has -been modified by someone else. -.PP -In practice, Prisma has found that conflicts that occur when the same -object has been modified by someone else are quite rare. -When they do happen, the changes made by the other developer are usually -easily resolved. -This practical use has shown that the \*QCopy-Modify-Merge\*U paradigm is a -correct and useful one. -.NH 2 -Tracking Third-Party Source Distributions -.PP -Currently, a large amount of software is based on source -distributions from a third-party distributor. -It is often the case that local modifications are to be made to this -distribution, \fIand\fP that the vendor's future releases should be -tracked. -Rolling your local modifications forward into the new vendor release is a -time-consuming task, but \fBcvs\fP can ease this burden somewhat. -The \fBcheckin\fP program of \fBcvs\fP initially sets up a source -repository by integrating the source modules directly from the vendor's -release, preserving the directory hierarchy of the vendor's distribution. -The branch support of -.SM -RCS -.LG -is used to build this vendor release as a branch of the main -.SM -RCS -.LG -trunk. -Figure 2 shows how the \*Qhead\*U tracks a sample vendor -branch when no local modifications have been made to the file. -.KF -.hl -.DS B -.PS -ellipse at 3.237,6.763 wid 1.000 ht 0.500 -dashwid = 0.050i -line dashed from 3.237,7.513 to 3.737,7.513 to 3.737,9.762 to 4.237,9.762 -line from 4.138,9.737 to 4.237,9.762 to 4.138,9.787 -line dashed from 2.237,8.262 to 3.237,8.262 to 3.237,7.013 -line from 3.212,7.112 to 3.237,7.013 to 3.262,7.112 -line from 3.737,6.763 to 4.237,6.763 -line from 4.138,6.737 to 4.237,6.763 to 4.138,6.788 -line from 2.237,6.763 to 2.737,6.763 -line from 2.637,6.737 to 2.737,6.763 to 2.637,6.788 -line from 1.738,6.013 to 1.738,6.513 -line from 1.762,6.413 to 1.738,6.513 to 1.713,6.413 -line from 1.238,7.013 to 2.237,7.013 to 2.237,6.513 to 1.238,6.513 to 1.238,7.013 -line from 4.237,9.012 to 5.237,9.012 to 5.237,8.512 to 4.237,8.512 to 4.237,9.012 -line from 4.237,8.012 to 5.237,8.012 to 5.237,7.513 to 4.237,7.513 to 4.237,8.012 -line from 4.237,7.013 to 5.237,7.013 to 5.237,6.513 to 4.237,6.513 to 4.237,7.013 -line from 4.737,7.013 to 4.737,7.513 -line from 4.763,7.413 to 4.737,7.513 to 4.712,7.413 -line from 4.737,8.012 to 4.737,8.512 -line from 4.763,8.412 to 4.737,8.512 to 4.712,8.412 -line from 4.237,10.012 to 5.237,10.012 to 5.237,9.512 to 4.237,9.512 to 4.237,10.012 -line from 4.737,9.012 to 4.737,9.512 -line from 4.763,9.412 to 4.737,9.512 to 4.712,9.412 -line from 5.987,5.013 to 5.987,6.013 to 0.988,6.013 to 0.988,5.013 to 5.987,5.013 -.ps 11 -"\"HEAD\"" at 1.550,8.231 ljust -.ps 11 -"'SunOS'" at 2.987,6.293 ljust -.ps 11 -"1.1.1" at 3.050,6.793 ljust -.ps 11 -"1.1" at 1.613,6.793 ljust -.ps 11 -"1.1.1.1" at 4.487,6.793 ljust -.ps 11 -"1.1.1.2" at 4.487,7.793 ljust -.ps 11 -"1.1.1.3" at 4.487,8.793 ljust -.ps 11 -"1.1.1.4" at 4.487,9.793 ljust -.ps 11 -"'SunOS_4_0'" at 5.487,6.793 ljust -.ps 11 -"'SunOS_4_0_1'" at 5.487,7.793 ljust -.ps 11 -"'YAPT_5_5C'" at 5.487,8.793 ljust -.ps 11 -"'SunOS_4_0_3'" at 5.487,9.793 ljust -.ps 11 -"rcsfile.c,v" at 2.987,5.543 ljust -.PE -.DE -.hl -.ce 100 -.LG -\fBFigure 2.\fP -.SM -\fBcvs\fP Vendor Branch Example -.ce 0 -.sp .3 -.KE -Once this is done, developers can check out files and make local changes to -the vendor's source distribution. -These local changes form a new branch to the tree which is then used as the -source for future check outs. -Figure 3 shows how the \*Qhead\*U moves to the main -.SM -RCS -.LG -trunk when a local modification is made. -.KF -.hl -.DS B -.PS -ellipse at 3.237,6.763 wid 1.000 ht 0.500 -dashwid = 0.050i -line dashed from 2.800,9.075 to 1.738,9.075 to 1.738,8.012 -line from 1.713,8.112 to 1.738,8.012 to 1.762,8.112 -line from 1.738,7.013 to 1.738,7.513 -line from 1.762,7.413 to 1.738,7.513 to 1.713,7.413 -line from 1.238,8.012 to 2.237,8.012 to 2.237,7.513 to 1.238,7.513 to 1.238,8.012 -line from 3.737,6.763 to 4.237,6.763 -line from 4.138,6.737 to 4.237,6.763 to 4.138,6.788 -line from 2.237,6.763 to 2.737,6.763 -line from 2.637,6.737 to 2.737,6.763 to 2.637,6.788 -line from 1.738,6.013 to 1.738,6.513 -line from 1.762,6.413 to 1.738,6.513 to 1.713,6.413 -line from 1.238,7.013 to 2.237,7.013 to 2.237,6.513 to 1.238,6.513 to 1.238,7.013 -line from 4.237,9.012 to 5.237,9.012 to 5.237,8.512 to 4.237,8.512 to 4.237,9.012 -line from 4.237,8.012 to 5.237,8.012 to 5.237,7.513 to 4.237,7.513 to 4.237,8.012 -line from 4.237,7.013 to 5.237,7.013 to 5.237,6.513 to 4.237,6.513 to 4.237,7.013 -line from 4.737,7.013 to 4.737,7.513 -line from 4.763,7.413 to 4.737,7.513 to 4.712,7.413 -line from 4.737,8.012 to 4.737,8.512 -line from 4.763,8.412 to 4.737,8.512 to 4.712,8.412 -line from 4.237,10.012 to 5.237,10.012 to 5.237,9.512 to 4.237,9.512 to 4.237,10.012 -line from 4.737,9.012 to 4.737,9.512 -line from 4.763,9.412 to 4.737,9.512 to 4.712,9.412 -line from 5.987,5.013 to 5.987,6.013 to 0.988,6.013 to 0.988,5.013 to 5.987,5.013 -.ps 11 -"1.2" at 1.613,7.793 ljust -.ps 11 -"\"HEAD\"" at 2.862,9.043 ljust -.ps 11 -"'SunOS'" at 2.987,6.293 ljust -.ps 11 -"1.1.1" at 3.050,6.793 ljust -.ps 11 -"1.1" at 1.613,6.793 ljust -.ps 11 -"1.1.1.1" at 4.487,6.793 ljust -.ps 11 -"1.1.1.2" at 4.487,7.793 ljust -.ps 11 -"1.1.1.3" at 4.487,8.793 ljust -.ps 11 -"1.1.1.4" at 4.487,9.793 ljust -.ps 11 -"'SunOS_4_0'" at 5.487,6.793 ljust -.ps 11 -"'SunOS_4_0_1'" at 5.487,7.793 ljust -.ps 11 -"'YAPT_5_5C'" at 5.487,8.793 ljust -.ps 11 -"'SunOS_4_0_3'" at 5.487,9.793 ljust -.ps 11 -"rcsfile.c,v" at 2.987,5.543 ljust -.PE -.DE -.hl -.ce 100 -.LG -\fBFigure 3.\fP -.SM -\fBcvs\fP Local Modification to Vendor Branch -.ce 0 -.sp -.KE -.PP -When a new version of the vendor's source distribution arrives, the -\fBcheckin\fP program adds the new and changed vendor's files to the -already existing source repository. -For files that have not been changed locally, the new file from the -vendor becomes the current \*Qhead\*U revision. -For files that have been modified locally, \fBcheckin\fP warns that the -file must be merged with the new vendor release. -The \fBcvs\fP \*Qjoin\*U command is a useful tool that aids this process by -performing the necessary -.SM -RCS -.LG -merge, as is done above when performing an \*Qupdate.\*U -.PP -There is also limited support for \*Qdual\*U derivations for source files. -See Figure 4 for a sample dual-derived file. -.KF -.hl -.DS B -.PS -ellipse at 2.337,8.575 wid 0.700 ht 0.375 -ellipse at 2.312,9.137 wid 0.700 ht 0.375 -line from 1.225,9.012 to 1.225,9.363 -line from 1.250,9.263 to 1.225,9.363 to 1.200,9.263 -line from 0.875,9.725 to 1.600,9.725 to 1.600,9.363 to 0.875,9.363 to 0.875,9.725 -line from 0.875,9.012 to 1.600,9.012 to 1.600,8.650 to 0.875,8.650 to 0.875,9.012 -line from 4.050,10.200 to 4.775,10.200 to 4.775,9.850 to 4.050,9.850 to 4.050,10.200 -line from 4.050,9.475 to 4.775,9.475 to 4.775,9.113 to 4.050,9.113 to 4.050,9.475 -line from 4.050,8.762 to 4.775,8.762 to 4.775,8.400 to 4.050,8.400 to 4.050,8.762 -line from 4.425,8.762 to 4.425,9.113 -line from 4.450,9.013 to 4.425,9.113 to 4.400,9.013 -line from 4.425,9.475 to 4.425,9.850 -line from 4.450,9.750 to 4.425,9.850 to 4.400,9.750 -line from 3.050,10.000 to 3.775,10.000 to 3.775,9.637 to 3.050,9.637 to 3.050,10.000 -line from 3.050,9.312 to 3.775,9.312 to 3.775,8.950 to 3.050,8.950 to 3.050,9.312 -line from 0.713,7.325 to 0.713,8.075 to 4.925,8.075 to 4.925,7.325 to 0.713,7.325 -line from 1.238,8.075 to 1.238,8.637 -line from 1.262,8.537 to 1.238,8.637 to 1.213,8.537 -line from 1.613,8.825 to 1.975,8.575 -line from 1.878,8.611 to 1.975,8.575 to 1.907,8.652 -line from 2.675,8.575 to 4.050,8.575 -line from 3.950,8.550 to 4.050,8.575 to 3.950,8.600 -line from 2.675,9.137 to 3.050,9.137 -line from 2.950,9.112 to 3.050,9.137 to 2.950,9.162 -line from 3.425,9.325 to 3.425,9.637 -line from 3.450,9.537 to 3.425,9.637 to 3.400,9.537 -line from 1.613,8.825 to 1.925,9.137 -line from 1.872,9.049 to 1.925,9.137 to 1.837,9.084 -.ps 11 -"'BSD'" at 2.138,9.481 ljust -.ps 11 -"1.2" at 1.113,9.543 ljust -.ps 11 -"1.1" at 1.125,8.831 ljust -.ps 11 -"1.1.1.1" at 4.175,8.543 ljust -.ps 11 -"1.1.1.2" at 4.175,9.281 ljust -.ps 11 -"1.1.1.3" at 4.175,9.993 ljust -.ps 11 -"1.1.2.2" at 3.175,9.793 ljust -.ps 11 -"1.1.2.1" at 3.175,9.106 ljust -.ps 11 -"rcsfile.c,v" at 2.425,7.706 ljust -.ps 11 -"1.1.1" at 2.175,8.568 ljust -.ps 11 -"'SunOS'" at 2.125,8.243 ljust -.ps 11 -"1.1.2" at 2.163,9.131 ljust -.PE -.DE -.hl -.ce 100 -.LG -\fBFigure 4.\fP -.SM -\fBcvs\fP Support For \*QDual\*U Derivations -.ce 0 -.sp -.KE -This example tracks the SunOS distribution but includes major changes from -Berkeley. -These BSD files are saved directly in the -.SM -RCS -.LG -file off a new branch. -.NH 2 -Location Independent Module Database -.PP -\fBcvs\fP contains support for a simple, yet powerful, \*Qmodule\*U database. -For reasons of efficiency, this database is stored in \fBndbm\fP\|(3) format. -The module database is used to apply names to collections of directories -and files as a matter of convenience for checking out pieces of a large -software distribution. -The database records the physical location of the sources as a form of -information hiding, allowing one to check out whole directory hierarchies -or individual files without regard for their actual location within the -global source distribution. -.PP -Consider the following small sample of a module database, which must be -tailored manually to each specific source repository environment: -.DS -\f(CW #key [-option argument] directory [files...] - diff bin/diff - libc lib/libc - sys -o sys/tools/make_links sys - modules -i mkmodules CVSROOT.adm modules - kernel -a sys lang/adb - ps bin Makefile ps.c\fP -.DE -.PP -The \*Qdiff\*U and \*Qlibc\*U modules refer to whole directory hierarchies that -are extracted on check out. -The \*Qsys\*U module extracts the \*Qsys\*U hierarchy, and runs the -\*Qmake_links\*U program at the end of the check out process (the \fI-o\fP -option specifies a program to run on check\fIo\fPut). -The \*Qmodules\*U module allows one to edit the module database file and -runs the \*Qmkmodules\*U program on check\fIi\fPn to regenerate the -\fBndbm\fP database that \fBcvs\fP uses. -The \*Qkernel\*U module is an alias (as the \fI-a\fP option specifies) -which causes the remaining arguments after the \fI-a\fP to be interpreted -exactly as if they had been specified on the command line. -This is useful for objects that require shared pieces of code from far away -places to be compiled (as is the case with the kernel debugger, \fBkadb\fP, -which shares code with the standard \fBadb\fP debugger). -The \*Qps\*U module shows that the source for \*Qps\*U lives in the \*Qbin\*U -directory, but only \fIMakefile\fP and \fIps.c\fP are required to build the -object. -.PP -The module database at Prisma is now populated for the entire UNIX -distribution and thereby allows us to issue the -following convenient commands to check out components of the UNIX -distribution without regard for their actual location within the master source -repository: -.DS -\f(CW example% cvs checkout diff - example% cvs checkout libc ps - example% cd diff; make\fP -.DE -.PP -In building the module database file, it is quite possible to have name -conflicts within a global software distribution. -For example, SunOS provides two \fBcat\fP programs: -one for the standard environment, \fI/bin/cat\fP, and one for the System V -environment, \fI/usr/5bin/cat\fP. -We resolved this conflict by naming the standard \fBcat\fP module -\*Qcat\*U, and the System V \fBcat\fP module \*Q5cat\*U. -Similar name modifications must be applied to other conflicting names, as -might be found between a utility program and a library function, though -Prisma chose not to include individual library functions within the module -database at this time. -.NH 2 -Configurable Logging Support -.PP -The \fBcvs\fP \*Qcommit\*U command is used to make a permanent change to the -master source repository (where the -.SM -RCS -.LG -\*Q,v\*U files live). -Whenever a \*Qcommit\*U is done, the log message for the change is carefully -logged by an arbitrary program (in a file, notesfile, news database, or -mail). -For example, a collection of these updates can be used to produce release -notices. -\fBcvs\fP can be configured to send log updates through one or more filter -programs, based on a regular expression match on the directory that is -being changed. -This allows multiple related or unrelated projects to exist within a single -\fBcvs\fP source repository tree, with each different project sending its -\*Qcommit\*U reports to a unique log device. -.PP -A sample logging configuration file might look as follows: -.DS -\f(CW #regex filter-program - DEFAULT /usr/local/bin/nfpipe -t %s utils.updates - ^diag /usr/local/bin/nfpipe -t %s diag.updates - ^local /usr/local/bin/nfpipe -t %s local.updates - ^perf /usr/local/bin/nfpipe -t %s perf.updates - ^sys /usr/local/bin/nfpipe -t %s kernel.updates\fP -.DE -.PP -This sample allows the diagnostics and performance groups to -share the same source repository with the kernel and utilities groups. -Changes that they make are sent directly to their own notesfile [Essick] -through the \*Qnfpipe\*U program. -A sufficiently simple title is substituted for the \*Q%s\*U argument before -the filter program is executed. -This logging configuration file is tailored manually to each specific -source repository environment. -.NH 2 -Tagged Releases and Dates -.PP -Any release can be given a symbolic tag name that is stored directly in the -.SM -RCS -.LG -files. -This tag can be used at any time to get an exact copy of any previous -release. -With equal ease, one can also extract an exact copy of the source files as -of any arbitrary date in the past as well. -Thus, all that's required to tag the current kernel, and to tag the kernel -as of the Fourth of July is: -.DS -\f(CW example% cvs tag TEST_KERNEL kernel - example% cvs tag -D 'July 4' PATRIOTIC_KERNEL kernel\fP -.DE -The following command would retrieve an exact copy of the test kernel at -some later date: -.DS -\f(CW example% cvs checkout -fp -rTEST_KERNEL kernel\fP -.DE -The \fI-f\fP option causes only files that match the specified tag to be -extracted, while the \fI-p\fP option automatically prunes empty directories. -Consequently, directories added to the kernel after the test kernel was -tagged are not included in the newly extracted copy of the test kernel. -.PP -The \fBcvs\fP date support has exactly the same interface as that provided -with -.SM -RCS\c -.LG -, however \fBcvs\fP must process the \*Q,v\*U files directly due to the -special handling required by the vendor branch support. -The standard -.SM -RCS -.LG -date handling only processes one branch (or the main trunk) when checking -out based on a date specification. -\fBcvs\fP must instead process the current \*Qhead\*U branch and, if a -match is not found, proceed to look for a match on the vendor branch. -This, combined with reasons of performance, is why \fBcvs\fP processes -revision (symbolic and numeric) and date specifications directly from the -\*Q,v\*U files. -.NH 2 -Building \*Qpatch\*U Source Distributions -.PP -\fBcvs\fP can produce a \*Qpatch\*U format [Wall] output file which can be -used to bring a previously released software distribution current with the -newest release. -This patch file supports an entire directory hierarchy within a single -patch, as well as being able to add whole new files to the previous -release. -One can combine symbolic revisions and dates together to display changes in -a very generic way: -.DS -\f(CW example% cvs patch -D 'December 1, 1988' \e - -D 'January 1, 1989' sys\fP -.DE -This example displays the kernel changes made in the month of December, -1988. -To release a patch file, for example, to take the \fBcvs\fP distribution -from version 1.0 to version 1.4 might be done as follows: -.DS -\f(CW example% cvs patch -rCVS_1_0 -rCVS_1_4 cvs\fP -.DE -.NH -CVS Experience -.NH 2 -Statistics -.PP -A quick summary of the scale that \fBcvs\fP is addressing today -can be found in Table 1. -.KF -.TS -box center tab(:); -c s -c s -c | c -l | n . -\fB\s+2Revision Control Statistics at Prisma -as of 11/11/89\fP\s-2 -_ -How Many...:Total -= -Files:17243 -Directories:1005 -Lines of code:3927255 -Removed files:131 -Software developers:14 -Software groups:6 -Megabytes of source:128 -.TE -.ce 100 -.LG -\fBTable 1.\fP -.SM -\fBcvs\fP Statistics -.ce 0 -.sp .3 -.KE -Table 2 shows the history of files changed or added and the number -of source lines affected by the change at Prisma. -Only changes made to the kernel sources are included. -.KF -.TS -box center tab(:); -c s s s s -c s s s s -c || c | c || c | c -c || c | c || c | c -l || n | n || n | n. -\fB\s+2Prisma Kernel Source File Changes -By Month, 1988-1989\fP\s-2 -_ -Month:# Changed:# Lines:# Added:# Lines -\^:Files:Changed:Files:Added -= -Dec:87:3619:68:9266 -Jan:39:4324:0:0 -Feb:73:1578:5:3550 -Mar:99:5301:18:11461 -Apr:112:7333:11:5759 -May:138:5371:17:13986 -Jun:65:2261:27:12875 -Jul:34:2000:1:58 -Aug:65:6378:8:4724 -Sep:266:23410:113:39965 -Oct:22:621:1:155 -Total:1000:62196:269:101799 -.TE -.ce 100 -.LG -\fBTable 2.\fP -.SM -\fBcvs\fP Usage History for the Kernel -.ce 0 -.sp -.KE -The large number of source file changes made in September are the result of -merging the SunOS 4.0.3 sources into the kernel. -This merge process is described in section 3.3. -.NH 2 -Performance -.PP -The performance of \fBcvs\fP is currently quite reasonable. -Little effort has been expended on tuning \fBcvs\fP, although performance -related decisions were made during the \fBcvs\fP design. -For example, \fBcvs\fP parses the -.SM -RCS -.LG -\*Q,v\*U files directly instead of running an -.SM -RCS -.LG -process. -This includes following branches as well as integrating with the vendor -source branches and the main trunk when checking out files based on a date. -.PP -Checking out the entire kernel source tree (1223 files/59 directories) -currently takes 16 wall clock minutes on a Sun-4/280. -However, bringing the tree up-to-date with the current kernel sources, once -it has been checked out, takes only 1.5 wall clock minutes. -Updating the \fIcomplete\fP 128 MByte source tree under \fBcvs\fP control -(17243 files/1005 directories) takes roughly 28 wall clock minutes and -utilizes one-third of the machine. -For now this is entirely acceptable; improvements on these numbers will -possibly be made in the future. -.NH 2 -The SunOS 4.0.3 Merge -.PP -The true test of the \fBcvs\fP vendor branch support came with the arrival -of the SunOS 4.0.3 source upgrade tape. -As described above, the \fBcheckin\fP program was used to install the new -sources and the resulting output file listed the files that had been -locally modified, needing to be merged manually. -For the kernel, there were 94 files in conflict. -The \fBcvs\fP \*Qjoin\*U command was used on each of the 94 conflicting -files, and the remaining conflicts were resolved. -.PP -The \*Qjoin\*U command performs an \fBrcsmerge\fP operation. -This in turn uses \fI/usr/lib/diff3\fP to produce a three-way diff file. -As it happens, the \fBdiff3\fP program has a hard-coded limit of 200 -source-file changes maximum. -This proved to be too small for a few of the kernel files that needed -merging by hand, due to the large number of local changes that Prisma had -made. -The \fBdiff3\fP problem was solved by increasing the hard-coded limit by an -order of magnitude. -.PP -The SunOS 4.0.3 kernel source upgrade distribution contained -346 files, 233 of which were modifications to previously released files, -and 113 of which were newly added files. -\fBcheckin\fP added the 113 new files to the source repository -without intervention. -Of the 233 modified files, 139 dropped in cleanly by \fBcheckin\fP, since -Prisma had not made any local changes to them, and 94 required manual -merging due to local modifications. -The 233 modified files consisted of 20,766 lines of differences. -It took one developer two days to manually merge the 94 files using the -\*Qjoin\*U command and resolving conflicts manually. -An additional day was required for kernel debugging. -The entire process of merging over 20,000 lines of differences was -completed in less than a week. -This one time-savings alone was justification enough for the \fBcvs\fP -development effort; we expect to gain even more when tracking future SunOS -releases. -.NH -Future Enhancements and Current Bugs -.PP -Since \fBcvs\fP was designed to be incomplete, for reasons of design -simplicity, there are naturally a good -number of enhancements that can be made to make it more useful. -As well, some nuisances exist in the current implementation. -.RS -.IP \(bu 3 -\fBcvs\fP does not currently \*Qremember\*U who has a checked out a copy of a -module. -As a result, it is impossible to know who might be working on the same -module that you are. -A simple-minded database that is updated nightly would likely suffice. -.IP \(bu 3 -Signal processing, keyboard interrupt handling in particular, is currently -somewhat weak. -This is due to the heavy use of the \fBsystem\fP\|(3) library -function to execute -.SM -RCS -.LG -programs like \fBco\fP and \fBci\fP. -It sometimes takes multiple interrupts to make \fBcvs\fP quit. -This can be fixed by using a home-grown \fBsystem\fP\|() replacement. -.IP \(bu 3 -Security of the source repository is currently not dealt with directly. -The usual UNIX approach of user-group-other security permissions through -the file system is utilized, but nothing else. -\fBcvs\fP could likely be a set-group-id executable that checks a -protected database to verify user access permissions for particular objects -before allowing any operations to affect those objects. -.IP \(bu 3 -With every checked-out directory, \fBcvs\fP maintains some administrative -files that record the current revision numbers of the checked-out files as -well as the location of the respective source repository. -\fBcvs\fP does not recover nicely at all if these administrative files are -removed. -.IP \(bu 3 -The source code for \fBcvs\fP has been tested extensively on Sun-3 and -Sun-4 systems, all running SunOS 4.0 or later versions of the operating -system. -Since the code has not yet been compiled under other platforms, the overall -portability of the code is still questionable. -.IP \(bu 3 -As witnessed in the previous section, the \fBcvs\fP method for tracking -third party vendor source distributions can work quite nicely. -However, if the vendor changes the directory structure or the file names -within the source distribution, \fBcvs\fP has no way of matching the old -release with the new one. -It is currently unclear as to how to solve this, though it is certain to -happen in practice. -.RE -.NH -Availability -.PP -The \fBcvs\fP program sources can be found in a recent posting to the -\fBcomp.sources.unix\fP newsgroup. -It is also currently available via anonymous ftp from \*Qprisma.com\*U. -Copying rights for \fBcvs\fP will be covered by the GNU General Public -License. -.NH -Summary -.PP -Prisma has used \fBcvs\fP since December, 1988. -It has evolved to meet our specific needs of revision and release control. -We will make our code freely available so that others can -benefit from our work, and can enhance \fBcvs\fP to meet broader needs yet. -.PP -Many of the other software release and revision control systems, like the -one described in [Glew], appear to use a collection of tools that are -geared toward specific environments \(em one set of tools for the kernel, -one set for \*Qgeneric\*U software, one set for utilities, and one set for -kernel and utilities. -Each of these tool sets apparently handle some specific aspect of the -problem uniquely. -\fBcvs\fP took a somewhat different approach. -File sharing through symbolic or hard links is not addressed; instead, the -disk space is simply burned since it is \*Qcheap.\*U -Support for producing objects for multiple architectures is not addressed; -instead, a parallel checked-out source tree must be used for each -architecture, again wasting disk space to simplify complexity and ease of -use \(em punting on this issue allowed \fIMakefile\fPs to remain -unchanged, unlike the approach taken in [Mahler], thereby maintaining closer -compatibility with the third-party vendor sources. -\fBcvs\fP is essentially a source-file server, making no assumptions or -special handling of the sources that it controls. -To \fBcvs\fP: -.QP -A source is a source, of course, of course, unless of course the source is -Mr. Ed.\** -.FS -\fBcvs\fP, of course, does not really discriminate against Mr. Ed.\** -.FE -.FS -Yet. -.FE -.LP -Sources are maintained, saved, and retrievable at any time based on -symbolic or numeric revision or date in the past. -It is entirely up to \fBcvs\fP wrapper programs to provide for release -environments and such. -.PP -The major advantage of \fBcvs\fP over the -many other similar systems that have already been designed is the -simplicity of \fBcvs\fP. -\fBcvs\fP contains only three programs that do all the work of release -and revision control, and two manually-maintained administrative -files for each source repository. -Of course, the deciding factor of any tool is whether people use it, and if -they even \fIlike\fP to use it. -At Prisma, \fBcvs\fP prevented members of the kernel -group from killing each other. -.NH -Acknowledgements -.PP -Many thanks to Dick Grune at Vrije Universiteit in Amsterdam for his work -on the original version of \fBcvs\fP and for making it available to the -world. -Thanks to Jeff Polk of Prisma for helping with the design of the module -database, vendor branch support, and for writing the \fBcheckin\fP shell -script. -Thanks also to the entire software group at Prisma for taking the -time to review the paper and correct my grammar. -.NH -References -.IP [Bell] 12 -Bell Telephone Laboratories. -\*QSource Code Control System User's Guide.\*U -\fIUNIX System III Programmer's Manual\fP, October 1981. -.IP [Courington] 12 -Courington, W. -\fIThe Network Software Environment\fP, -Sun Technical Report FE197-0, Sun Microsystems Inc, February 1989. -.IP [Essick] 12 -Essick, Raymond B. and Robert Bruce Kolstad. -\fINotesfile Reference Manual\fP, -Department of Computer Science Technical Report #1081, -University of Illinois at Urbana-Champaign, Urbana, Illinois, -1982, p. 26. -.IP [Glew] 12 -Glew, Andy. -\*QBoxes, Links, and Parallel Trees: -Elements of a Configuration Management System.\*U -\fIWorkshop Proceedings of the Software Management Conference\fP, USENIX, -New Orleans, April 1989. -.IP [Grune] 12 -Grune, Dick. -Distributed the original shell script version of \fBcvs\fP in the -\fBcomp.sources.unix\fP volume 6 release in 1986. -.IP [Honda] 12 -Honda, Masahiro and Terrence Miller. -\*QSoftware Management Using a CASE Environment.\*U -\fIWorkshop Proceedings of the Software Management Conference\fP, USENIX, -New Orleans, April 1989. -.IP [Mahler] 12 -Mahler, Alex and Andreas Lampen. -\*QAn Integrated Toolset for Engineering Software Configurations.\*U -\fIProceedings of the ACM SIGSOFT/SIGPLAN Software Engineering Symposium on -Practical Software Development Environments\fP, ACM, Boston, November 1988. -Described is the \fBshape\fP toolkit posted to the -\fBcomp.sources.unix\fP newsgroup in the volume 19 release. -.IP [Tichy] 12 -Tichy, Walter F. -\*QDesign, Implementation, and Evaluation of a Revision Control System.\*U -\fIProceedings of the 6th International Conference on Software -Engineering\fP, IEEE, Tokyo, September 1982. -.IP [Wall] 12 -Wall, Larry. -The \fBpatch\fP program is an indispensable tool for applying a diff file -to an original. -Can be found on uunet.uu.net in ~ftp/pub/patch.tar. diff --git a/gnu/usr.bin/cvs/lib/Makefile b/gnu/usr.bin/cvs/lib/Makefile deleted file mode 100644 index cf3f20fd2802..000000000000 --- a/gnu/usr.bin/cvs/lib/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -LIB = cvs - -CFLAGS += -I${.CURDIR} -I${.CURDIR}/../cvs -DFTIME_MISSING -DHAVE_TIMEZONE - -SRCS = argmatch.c error.c getopt.c sighandle.c strippath.c stripslash.c yesno.c \ - getdate.y fnmatch.c regex.c subr.c myndbm.c hash.c - -.include <bsd.lib.mk> diff --git a/gnu/usr.bin/cvs/lib/Makefile.in b/gnu/usr.bin/cvs/lib/Makefile.in deleted file mode 100644 index a8309f2fc00d..000000000000 --- a/gnu/usr.bin/cvs/lib/Makefile.in +++ /dev/null @@ -1,91 +0,0 @@ -# Makefile for library files used by GNU CVS. -# Do not use this makefile directly, but only from `../Makefile'. -# Copyright (C) 1986, 1988-1992 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -# @(#)Makefile.in 1.12 92/03/31 - -SHELL = /bin/sh - -srcdir = @srcdir@ -@VPATH@ - -SOURCES = argmatch.c \ -error.c getopt.c getopt1.c \ -sighandle.c \ -strippath.c stripslash.c yesno.c \ -getdate.y \ -hostname.c fnmatch.c ftruncate.c mkdir.c rename.c regex.c \ -strdup.c getwd.c alloca.c - -OBJECTS = argmatch.o \ -error.o getopt.o getopt1.o \ -sighandle.o \ -strippath.o stripslash.o yesno.o \ -getdate.o \ -@LIBOBJS@ - -DISTFILES = Makefile.in getopt.h \ -fnmatch.h regex.h system.h wait.h $(SOURCES) - -xxx: - @cd ..; $(MAKE) all SUBDIRS=lib - -all: libcvs.a -.PHONY: all - -install: all -.PHONY: install - -tags: $(DISTFILES) - ctags $(DISTFILES) - -TAGS: $(DISTFILES) - etags $(DISTFILES) - -ls: - @echo $(DISTFILES) -.PHONY: ls - -clean: - rm -f *.a *.o *.tab.c getdate.c -.PHONY: clean - -distclean: clean - rm -f tags TAGS Makefile -.PHONY: distclean - -realclean: distclean -.PHONY: realclean - -dist: - ln $(DISTFILES) ../`cat ../.fname`/lib -.PHONY: dist - -libcvs.a: $(OBJECTS) - $(AR) cr $@ $(OBJECTS) - -$(RANLIB) $@ - -getdate.c: getdate.y - @echo expect 8 shift/reduce conflicts - $(YACC) $(srcdir)/getdate.y - -if test -f y.tab.c ; then mv y.tab.c getdate.c ; fi - -if test -f getdate.tab.c ; then mv getdate.tab.c getdate.c ; fi - -fnmatch.o: fnmatch.h -getopt1.o: getopt.h -regex.o: regex.h -getwd.o: system.h diff --git a/gnu/usr.bin/cvs/lib/alloca.c b/gnu/usr.bin/cvs/lib/alloca.c deleted file mode 100644 index b57659e418c4..000000000000 --- a/gnu/usr.bin/cvs/lib/alloca.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - alloca -- (mostly) portable public-domain implementation -- D A Gwyn - - last edit: 86/05/30 rms - include config.h, since on VMS it renames some symbols. - Use xmalloc instead of malloc. - - This implementation of the PWB library alloca() function, - which is used to allocate space off the run-time stack so - that it is automatically reclaimed upon procedure exit, - was inspired by discussions with J. Q. Johnson of Cornell. - - It should work under any C implementation that uses an - actual procedure stack (as opposed to a linked list of - frames). There are some preprocessor constants that can - be defined when compiling for your specific system, for - improved efficiency; however, the defaults should be okay. - - The general concept of this implementation is to keep - track of all alloca()-allocated blocks, and reclaim any - that are found to be deeper in the stack than the current - invocation. This heuristic does not reclaim storage as - soon as it becomes invalid, but it will do so eventually. - - As a special case, alloca(0) reclaims storage without - allocating any. It is a good idea to use alloca(0) in - your main control loop, etc. to force garbage collection. -*/ -#ifndef lint -static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */ -#endif - -#if defined(emacs) || defined(HAVE_CONFIG_H) -#include "config.h" -#ifdef static -/* actually, only want this if static is defined as "" - -- this is for usg, in which emacs must undefine static - in order to make unexec workable - */ -#ifndef STACK_DIRECTION -you -lose --- must know STACK_DIRECTION at compile-time -#endif /* STACK_DIRECTION undefined */ -#endif /* static */ -#endif /* emacs || HAVE_CONFIG_H*/ - -#if __STDC__ -typedef void *pointer; /* generic pointer type */ -#else -typedef char *pointer; /* generic pointer type */ -#endif - -#define NULL 0 /* null pointer constant */ - -extern void free(); -extern pointer xmalloc(); - -/* - Define STACK_DIRECTION if you know the direction of stack - growth for your system; otherwise it will be automatically - deduced at run-time. - - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown -*/ - -#ifndef STACK_DIRECTION -#define STACK_DIRECTION 0 /* direction unknown */ -#endif - -#if STACK_DIRECTION != 0 - -#define STACK_DIR STACK_DIRECTION /* known at compile-time */ - -#else /* STACK_DIRECTION == 0; need run-time code */ - -static int stack_dir; /* 1 or -1 once known */ -#define STACK_DIR stack_dir - -static void -find_stack_direction (/* void */) -{ - static char *addr = NULL; /* address of first - `dummy', once known */ - auto char dummy; /* to get stack address */ - - if (addr == NULL) - { /* initial entry */ - addr = &dummy; - - find_stack_direction (); /* recurse once */ - } - else /* second entry */ - if (&dummy > addr) - stack_dir = 1; /* stack grew upward */ - else - stack_dir = -1; /* stack grew downward */ -} - -#endif /* STACK_DIRECTION == 0 */ - -/* - An "alloca header" is used to: - (a) chain together all alloca()ed blocks; - (b) keep track of stack depth. - - It is very important that sizeof(header) agree with malloc() - alignment chunk size. The following default should work okay. -*/ - -#ifndef ALIGN_SIZE -#define ALIGN_SIZE sizeof(double) -#endif - -typedef union hdr -{ - char align[ALIGN_SIZE]; /* to force sizeof(header) */ - struct - { - union hdr *next; /* for chaining headers */ - char *deep; /* for stack depth measure */ - } h; -} header; - -/* - alloca( size ) returns a pointer to at least `size' bytes of - storage which will be automatically reclaimed upon exit from - the procedure that called alloca(). Originally, this space - was supposed to be taken from the current stack frame of the - caller, but that method cannot be made to work for some - implementations of C, for example under Gould's UTX/32. -*/ - -static header *last_alloca_header = NULL; /* -> last alloca header */ - -pointer -alloca (size) /* returns pointer to storage */ - unsigned size; /* # bytes to allocate */ -{ - auto char probe; /* probes stack depth: */ - register char *depth = &probe; - -#if STACK_DIRECTION == 0 - if (STACK_DIR == 0) /* unknown growth direction */ - find_stack_direction (); -#endif - - /* Reclaim garbage, defined as all alloca()ed storage that - was allocated from deeper in the stack than currently. */ - - { - register header *hp; /* traverses linked list */ - - for (hp = last_alloca_header; hp != NULL;) - if (STACK_DIR > 0 && hp->h.deep > depth - || STACK_DIR < 0 && hp->h.deep < depth) - { - register header *np = hp->h.next; - - free ((pointer) hp); /* collect garbage */ - - hp = np; /* -> next header */ - } - else - break; /* rest are not deeper */ - - last_alloca_header = hp; /* -> last valid storage */ - } - - if (size == 0) - return NULL; /* no allocation required */ - - /* Allocate combined header + user data storage. */ - - { - register pointer new = xmalloc (sizeof (header) + size); - /* address of header */ - - ((header *)new)->h.next = last_alloca_header; - ((header *)new)->h.deep = depth; - - last_alloca_header = (header *)new; - - /* User storage begins just after header. */ - - return (pointer)((char *)new + sizeof(header)); - } -} - diff --git a/gnu/usr.bin/cvs/lib/dup2.c b/gnu/usr.bin/cvs/lib/dup2.c deleted file mode 100644 index 19743830ca6e..000000000000 --- a/gnu/usr.bin/cvs/lib/dup2.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - dup2 -- 7th Edition UNIX system call emulation for UNIX System V - - last edit: 11-Feb-1987 D A Gwyn -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <errno.h> -#include <fcntl.h> - -extern int close(), fcntl(); - -int -dup2( oldfd, newfd ) - int oldfd; /* already-open file descriptor */ - int newfd; /* desired duplicate descriptor */ -{ - register int ret; /* for fcntl() return value */ - register int save; /* for saving entry errno */ - - if ( oldfd == newfd ) - return oldfd; /* be careful not to close() */ - - save = errno; /* save entry errno */ - (void) close( newfd ); /* in case newfd is open */ - /* (may have just clobbered the original errno value) */ - - ret = fcntl( oldfd, F_DUPFD, newfd ); /* dupe it */ - - if ( ret >= 0 ) - errno = save; /* restore entry errno */ - else /* fcntl() returned error */ - if ( errno == EINVAL ) - errno = EBADF; /* we think of everything */ - - return ret; /* return file descriptor */ -} diff --git a/gnu/usr.bin/cvs/lib/fnmatch.c b/gnu/usr.bin/cvs/lib/fnmatch.c deleted file mode 100644 index 2a0543072d4e..000000000000 --- a/gnu/usr.bin/cvs/lib/fnmatch.c +++ /dev/null @@ -1,183 +0,0 @@ -/* Copyright (C) 1992 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -/* Modified slightly by Brian Berliner <berliner@sun.com> for CVS use */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* IGNORE(@ */ -/* #include <ansidecl.h> */ -/* @) */ -#include <errno.h> -#include <fnmatch.h> - -#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) -extern int errno; -#endif - -/* Match STRING against the filename pattern PATTERN, returning zero if - it matches, nonzero if not. */ -int -#if __STDC__ -fnmatch (const char *pattern, const char *string, int flags) -#else -fnmatch (pattern, string, flags) - char *pattern; - char *string; - int flags; -#endif -{ - register const char *p = pattern, *n = string; - register char c; - - if ((flags & ~__FNM_FLAGS) != 0) - { - errno = EINVAL; - return -1; - } - - while ((c = *p++) != '\0') - { - switch (c) - { - case '?': - if (*n == '\0') - return FNM_NOMATCH; - else if ((flags & FNM_PATHNAME) && *n == '/') - return FNM_NOMATCH; - else if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) - return FNM_NOMATCH; - break; - - case '\\': - if (!(flags & FNM_NOESCAPE)) - c = *p++; - if (*n != c) - return FNM_NOMATCH; - break; - - case '*': - if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) - return FNM_NOMATCH; - - for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) - if (((flags & FNM_PATHNAME) && *n == '/') || - (c == '?' && *n == '\0')) - return FNM_NOMATCH; - - if (c == '\0') - return 0; - - { - char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; - for (--p; *n != '\0'; ++n) - if ((c == '[' || *n == c1) && - fnmatch(p, n, flags & ~FNM_PERIOD) == 0) - return 0; - return FNM_NOMATCH; - } - - case '[': - { - /* Nonzero if the sense of the character class is inverted. */ - register int not; - - if (*n == '\0') - return FNM_NOMATCH; - - if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) - return FNM_NOMATCH; - - not = (*p == '!' || *p == '^'); - if (not) - ++p; - - c = *p++; - for (;;) - { - register char cstart = c, cend = c; - - if (!(flags & FNM_NOESCAPE) && c == '\\') - cstart = cend = *p++; - - if (c == '\0') - /* [ (unterminated) loses. */ - return FNM_NOMATCH; - - c = *p++; - - if ((flags & FNM_PATHNAME) && c == '/') - /* [/] can never match. */ - return FNM_NOMATCH; - - if (c == '-' && *p != ']') - { - cend = *p++; - if (!(flags & FNM_NOESCAPE) && cend == '\\') - cend = *p++; - if (cend == '\0') - return FNM_NOMATCH; - c = *p++; - } - - if (*n >= cstart && *n <= cend) - goto matched; - - if (c == ']') - break; - } - if (!not) - return FNM_NOMATCH; - break; - - matched:; - /* Skip the rest of the [...] that already matched. */ - while (c != ']') - { - if (c == '\0') - /* [... (unterminated) loses. */ - return FNM_NOMATCH; - - c = *p++; - if (!(flags & FNM_NOESCAPE) && c == '\\') - /* 1003.2d11 is unclear if this is right. %%% */ - ++p; - } - if (not) - return FNM_NOMATCH; - } - break; - - default: - if (c != *n) - return FNM_NOMATCH; - } - - ++n; - } - - if (*n == '\0') - return 0; - - return FNM_NOMATCH; -} diff --git a/gnu/usr.bin/cvs/lib/fnmatch.h b/gnu/usr.bin/cvs/lib/fnmatch.h deleted file mode 100644 index a1e4f8702185..000000000000 --- a/gnu/usr.bin/cvs/lib/fnmatch.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 1992 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#ifndef _FNMATCH_H - -#define _FNMATCH_H 1 - -/* Bits set in the FLAGS argument to `fnmatch'. */ -#undef FNM_PATHNAME -#define FNM_PATHNAME (1 << 0)/* No wildcard can ever match `/'. */ -#undef FNM_NOESCAPE -#define FNM_NOESCAPE (1 << 1)/* Backslashes don't quote special chars. */ -#undef FNM_PERIOD -#define FNM_PERIOD (1 << 2)/* Leading `.' is matched only explicitly. */ -#undef __FNM_FLAGS -#define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD) - -/* Value returned by `fnmatch' if STRING does not match PATTERN. */ -#undef FNM_NOMATCH -#define FNM_NOMATCH 1 - -/* Match STRING against the filename pattern PATTERN, - returning zero if it matches, FNM_NOMATCH if not. */ -#if __STDC__ -extern int fnmatch (const char *pattern, const char *string, int flags); -#else -extern int fnmatch (); -#endif - -#endif /* fnmatch.h */ diff --git a/gnu/usr.bin/cvs/lib/ftruncate.c b/gnu/usr.bin/cvs/lib/ftruncate.c deleted file mode 100644 index 13f20a382849..000000000000 --- a/gnu/usr.bin/cvs/lib/ftruncate.c +++ /dev/null @@ -1,76 +0,0 @@ -/* ftruncate emulations that work on some System V's. - This file is in the public domain. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> -#include <fcntl.h> - -#ifdef F_CHSIZE -int -ftruncate (fd, length) - int fd; - off_t length; -{ - return fcntl (fd, F_CHSIZE, length); -} -#else -#ifdef F_FREESP -/* The following function was written by - kucharsk@Solbourne.com (William Kucharski) */ - -#include <sys/stat.h> -#include <errno.h> -#include <unistd.h> - -int -ftruncate (fd, length) - int fd; - off_t length; -{ - struct flock fl; - struct stat filebuf; - - if (fstat (fd, &filebuf) < 0) - return -1; - - if (filebuf.st_size < length) - { - /* Extend file length. */ - if (lseek (fd, (length - 1), SEEK_SET) < 0) - return -1; - - /* Write a "0" byte. */ - if (write (fd, "", 1) != 1) - return -1; - } - else - { - /* Truncate length. */ - fl.l_whence = 0; - fl.l_len = 0; - fl.l_start = length; - fl.l_type = F_WRLCK; /* Write lock on file space. */ - - /* This relies on the UNDOCUMENTED F_FREESP argument to - fcntl, which truncates the file so that it ends at the - position indicated by fl.l_start. - Will minor miracles never cease? */ - if (fcntl (fd, F_FREESP, &fl) < 0) - return -1; - } - - return 0; -} -#else -int -ftruncate (fd, length) - int fd; - off_t length; -{ - return chsize (fd, length); -} -#endif -#endif diff --git a/gnu/usr.bin/cvs/lib/getwd.c b/gnu/usr.bin/cvs/lib/getwd.c deleted file mode 100644 index 573a7889244d..000000000000 --- a/gnu/usr.bin/cvs/lib/getwd.c +++ /dev/null @@ -1,35 +0,0 @@ -/* getwd.c -- get current working directory pathname - Copyright (C) 1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Some systems which include both getwd() and getcwd() have an implementation - of getwd() which is much faster than getcwd(). As a result, we use the - system's getwd() if it is available */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "system.h" - -/* Get the current working directory into PATHNAME */ - -char * -getwd (pathname) - char *pathname; -{ - return (getcwd(pathname, PATH_MAX)); -} diff --git a/gnu/usr.bin/cvs/lib/hostname.c b/gnu/usr.bin/cvs/lib/hostname.c deleted file mode 100644 index 34be15e8b619..000000000000 --- a/gnu/usr.bin/cvs/lib/hostname.c +++ /dev/null @@ -1,49 +0,0 @@ -/* hostname.c -- use uname() to get the name of the host - Copyright (C) 1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined(STDC_HEADERS) || defined(USG) -#include <string.h> -#ifndef index -#define index strchr -#endif -#else -#include <strings.h> -#endif - -#include <sys/utsname.h> - -/* Put this host's name into NAME, using at most NAMELEN characters */ - -int -gethostname(name, namelen) - char *name; - int namelen; -{ - struct utsname ugnm; - - if (uname(&ugnm) < 0) - return (-1); - - (void) strncpy(name, ugnm.nodename, namelen-1); - name[namelen-1] = '\0'; - - return (0); -} diff --git a/gnu/usr.bin/cvs/lib/memmove.c b/gnu/usr.bin/cvs/lib/memmove.c deleted file mode 100644 index 8818d46544c0..000000000000 --- a/gnu/usr.bin/cvs/lib/memmove.c +++ /dev/null @@ -1,57 +0,0 @@ -/* memmove -- copy memory regions of arbitary length - Copyright (C) 1991 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - - -/* - -NAME - - memmove -- copy memory regions of arbitary length - -SYNOPSIS - - void memmove (void *out, const void *in, size_t n); - -DESCRIPTION - - Copy LENGTH bytes from memory region pointed to by IN to memory - region pointed to by OUT. - - Regions can be overlapping. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef __STDC__ -#include <stddef.h> -#else -#define size_t unsigned long -#endif - -void * -memmove (out, in, length) - void *out; - const void* in; - size_t length; -{ - bcopy(in, out, length); - return out; -} diff --git a/gnu/usr.bin/cvs/lib/mkdir.c b/gnu/usr.bin/cvs/lib/mkdir.c deleted file mode 100644 index a70c1d866199..000000000000 --- a/gnu/usr.bin/cvs/lib/mkdir.c +++ /dev/null @@ -1,129 +0,0 @@ -/* mkrmdir.c -- BSD compatible directory functions for System V - Copyright (C) 1988, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> -#ifndef STDC_HEADERS -extern int errno; -#endif - -/* mkdir and rmdir adapted from GNU tar. */ - -/* Make directory DPATH, with permission mode DMODE. - - Written by Robert Rother, Mariah Corporation, August 1985 - (sdcsvax!rmr or rmr@uscd). If you want it, it's yours. - - Severely hacked over by John Gilmore to make a 4.2BSD compatible - subroutine. 11Mar86; hoptoad!gnu - - Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir, - subroutine didn't return EEXIST. It does now. */ - -int -mkdir (dpath, dmode) - char *dpath; - int dmode; -{ - int cpid, status; - struct stat statbuf; - - if (stat (dpath, &statbuf) == 0) - { - errno = EEXIST; /* stat worked, so it already exists. */ - return -1; - } - - /* If stat fails for a reason other than non-existence, return error. */ - if (errno != ENOENT) - return -1; - - cpid = fork (); - switch (cpid) - { - case -1: /* Cannot fork. */ - return -1; /* errno is set already. */ - - case 0: /* Child process. */ - /* Cheap hack to set mode of new directory. Since this child - process is going away anyway, we zap its umask. - This won't suffice to set SUID, SGID, etc. on this - directory, so the parent process calls chmod afterward. */ - status = umask (0); /* Get current umask. */ - umask (status | (0777 & ~dmode)); /* Set for mkdir. */ - execl ("/bin/mkdir", "mkdir", dpath, (char *) 0); - _exit (1); - - default: /* Parent process. */ - while (wait (&status) != cpid) /* Wait for kid to finish. */ - /* Do nothing. */ ; - - if (status & 0xFFFF) - { - errno = EIO; /* /bin/mkdir failed. */ - return -1; - } - return chmod (dpath, dmode); - } -} - -/* Remove directory DPATH. - Return 0 if successful, -1 if not. */ - -int -rmdir (dpath) - char *dpath; -{ - int cpid, status; - struct stat statbuf; - - if (stat (dpath, &statbuf) != 0) - return -1; /* stat set errno. */ - - if ((statbuf.st_mode & S_IFMT) != S_IFDIR) - { - errno = ENOTDIR; - return -1; - } - - cpid = fork (); - switch (cpid) - { - case -1: /* Cannot fork. */ - return -1; /* errno is set already. */ - - case 0: /* Child process. */ - execl ("/bin/rmdir", "rmdir", dpath, (char *) 0); - _exit (1); - - default: /* Parent process. */ - while (wait (&status) != cpid) /* Wait for kid to finish. */ - /* Do nothing. */ ; - - if (status & 0xFFFF) - { - errno = EIO; /* /bin/rmdir failed. */ - return -1; - } - return 0; - } -} diff --git a/gnu/usr.bin/cvs/lib/regex.c b/gnu/usr.bin/cvs/lib/regex.c deleted file mode 100644 index 8169880d7e4f..000000000000 --- a/gnu/usr.bin/cvs/lib/regex.c +++ /dev/null @@ -1,4948 +0,0 @@ -/* Extended regular expression matching and search library, - version 0.12. - (Implements POSIX draft P10003.2/D11.2, except for - internationalization features.) - - Copyright (C) 1993 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* AIX requires this to be the first thing in the file. */ -#if defined (_AIX) && !defined (REGEX_MALLOC) - #pragma alloca -#endif - -#define _GNU_SOURCE - -/* We need this for `regex.h', and perhaps for the Emacs include files. */ -#include <sys/types.h> - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* The `emacs' switch turns on certain matching commands - that make sense only in Emacs. */ -#ifdef emacs - -#include "lisp.h" -#include "buffer.h" -#include "syntax.h" - -/* Emacs uses `NULL' as a predicate. */ -#undef NULL - -#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 -#include <string.h> -#ifndef bcmp -#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) -#endif -#ifndef bcopy -#define bcopy(s, d, n) memcpy ((d), (s), (n)) -#endif -#ifndef bzero -#define bzero(s, n) memset ((s), 0, (n)) -#endif -#else -#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 - commands in re_match_2. */ -#ifndef Sword -#define Sword 1 -#endif - -#ifdef SYNTAX_TABLE - -extern char *re_syntax_table; - -#else /* not SYNTAX_TABLE */ - -/* How many characters in the character set. */ -#define CHAR_SET_SIZE 256 - -static char re_syntax_table[CHAR_SET_SIZE]; - -static void -init_syntax_once () -{ - register int c; - static int done = 0; - - if (done) - return; - - bzero (re_syntax_table, sizeof re_syntax_table); - - for (c = 'a'; c <= 'z'; c++) - re_syntax_table[c] = Sword; - - for (c = 'A'; c <= 'Z'; c++) - re_syntax_table[c] = Sword; - - for (c = '0'; c <= '9'; c++) - re_syntax_table[c] = Sword; - - re_syntax_table['_'] = Sword; - - done = 1; -} - -#endif /* not SYNTAX_TABLE */ - -#define SYNTAX(c) re_syntax_table[c] - -#endif /* not emacs */ - -/* Get the interface, including the syntax bits. */ -#include "regex.h" - -/* isalpha etc. are used for the character classes. */ -#include <ctype.h> - -#ifndef isascii -#define isascii(c) 1 -#endif - -#ifdef isblank -#define ISBLANK(c) (isascii (c) && isblank (c)) -#else -#define ISBLANK(c) ((c) == ' ' || (c) == '\t') -#endif -#ifdef isgraph -#define ISGRAPH(c) (isascii (c) && isgraph (c)) -#else -#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)) - -#ifndef NULL -#define NULL 0 -#endif - -/* We remove any previous definition of `SIGN_EXTEND_CHAR', - since ours (we hope) works properly with all combinations of - machines, compilers, `char' and `unsigned char' argument types. - (Per Bothner suggested the basic approach.) */ -#undef SIGN_EXTEND_CHAR -#if __STDC__ -#define SIGN_EXTEND_CHAR(c) ((signed char) (c)) -#else /* not __STDC__ */ -/* As in Harbison and Steele. */ -#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) -#endif - -/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we - use `alloca' instead of `malloc'. This is because using malloc in - re_search* or re_match* could cause memory leaks when C-g is used in - Emacs; also, malloc is slower and causes storage fragmentation. On - the other hand, malloc is more portable, and easier to debug. - - Because we sometimes use alloca, some routines have to be macros, - not functions -- `alloca'-allocated space disappears at the end of the - function it is called in. */ - -#ifdef REGEX_MALLOC - -#define REGEX_ALLOCATE malloc -#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) - -#else /* not REGEX_MALLOC */ - -/* Emacs already defines alloca, sometimes. */ -#ifndef alloca - -/* Make alloca work the best possible way. */ -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not __GNUC__ */ -#if HAVE_ALLOCA_H -#include <alloca.h> -#else /* not __GNUC__ or HAVE_ALLOCA_H */ -#ifndef _AIX /* Already did AIX, up at the top. */ -char *alloca (); -#endif /* not _AIX */ -#endif /* not HAVE_ALLOCA_H */ -#endif /* not __GNUC__ */ - -#endif /* not alloca */ - -#define REGEX_ALLOCATE alloca - -/* Assumes a `char *destination' variable. */ -#define REGEX_REALLOCATE(source, osize, nsize) \ - (destination = (char *) alloca (nsize), \ - bcopy (source, destination, osize), \ - destination) - -#endif /* not REGEX_MALLOC */ - - -/* 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) \ - (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 REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) - -#define BYTEWIDTH 8 /* In bits. */ - -#define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -typedef char boolean; -#define false 0 -#define true 1 - -/* These are the command codes that appear in compiled regular - 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. */ - -typedef enum -{ - no_op = 0, - - /* Followed by one byte giving n, then by n literal bytes. */ - exactn = 1, - - /* 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. */ - charset, - - /* 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_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. */ - duplicate, - - /* Fail unless at beginning of line. */ - begline, - - /* 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). */ - begbuf, - - /* Analogously, for end of buffer/string. */ - endbuf, - - /* 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. */ - on_failure_jump, - - /* 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. */ - 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. */ - 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. */ - 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. */ - succeed_n, - - /* 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_number_at, - - wordchar, /* Matches any word-constituent character. */ - notwordchar, /* Matches any char that is not a word-constituent. */ - - wordbeg, /* Succeeds if at word beginning. */ - wordend, /* Succeeds if at word end. */ - - wordbound, /* Succeeds if at a word boundary. */ - notwordbound /* Succeeds if not at a word boundary. */ - -#ifdef emacs - ,before_dot, /* Succeeds if before point. */ - at_dot, /* Succeeds if at point. */ - 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. */ - syntaxspec, - - /* Matches any character whose syntax is not that specified. */ - notsyntaxspec -#endif /* emacs */ -} re_opcode_t; - -/* Common operations on the compiled pattern. */ - -/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ - -#define STORE_NUMBER(destination, number) \ - do { \ - (destination)[0] = (number) & 0377; \ - (destination)[1] = (number) >> 8; \ - } while (0) - -/* Same as STORE_NUMBER, except increment DESTINATION to - the byte after where the number is stored. Therefore, DESTINATION - must be an lvalue. */ - -#define STORE_NUMBER_AND_INCR(destination, number) \ - do { \ - STORE_NUMBER (destination, number); \ - (destination) += 2; \ - } while (0) - -/* Put into DESTINATION a number stored in two contiguous bytes starting - at SOURCE. */ - -#define EXTRACT_NUMBER(destination, source) \ - do { \ - (destination) = *(source) & 0377; \ - (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ - } while (0) - -#ifdef DEBUG -static void -extract_number (dest, source) - int *dest; - unsigned char *source; -{ - int temp = SIGN_EXTEND_CHAR (*(source + 1)); - *dest = *source & 0377; - *dest += temp << 8; -} - -#ifndef EXTRACT_MACROS /* To debug the macros. */ -#undef EXTRACT_NUMBER -#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) -#endif /* not EXTRACT_MACROS */ - -#endif /* DEBUG */ - -/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. - SOURCE must be an lvalue. */ - -#define EXTRACT_NUMBER_AND_INCR(destination, source) \ - do { \ - EXTRACT_NUMBER (destination, source); \ - (source) += 2; \ - } while (0) - -#ifdef DEBUG -static void -extract_number_and_incr (destination, source) - int *destination; - unsigned char **source; -{ - extract_number (destination, *source); - *source += 2; -} - -#ifndef EXTRACT_MACROS -#undef EXTRACT_NUMBER_AND_INCR -#define EXTRACT_NUMBER_AND_INCR(dest, src) \ - extract_number_and_incr (&dest, &src) -#endif /* not EXTRACT_MACROS */ - -#endif /* DEBUG */ - -/* 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. */ - -#ifdef DEBUG - -/* We use standard I/O for debugging. */ -#include <stdio.h> - -/* It is useful to test things that ``must'' be true when debugging. */ -#include <assert.h> - -static int debug = 0; - -#define DEBUG_STATEMENT(e) e -#define DEBUG_PRINT1(x) if (debug) printf (x) -#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) \ - 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 -print_fastmap (fastmap) - char *fastmap; -{ - unsigned was_a_range = 0; - unsigned i = 0; - - while (i < (1 << BYTEWIDTH)) - { - if (fastmap[i++]) - { - was_a_range = 0; - printchar (i - 1); - while (i < (1 << BYTEWIDTH) && fastmap[i]) - { - was_a_range = 1; - i++; - } - if (was_a_range) - { - printf ("-"); - printchar (i - 1); - } - } - } - putchar ('\n'); -} - - -/* Print a compiled pattern string in human-readable form, starting at - the START pointer into it and ending just before the pointer END. */ - -void -print_partial_compiled_pattern (start, end) - unsigned char *start; - unsigned char *end; -{ - int mcnt, mcnt2; - unsigned char *p = start; - unsigned char *pend = end; - - if (start == NULL) - { - printf ("(null)\n"); - return; - } - - /* Loop over pattern commands. */ - while (p < pend) - { - switch ((re_opcode_t) *p++) - { - case no_op: - printf ("/no_op"); - break; - - case exactn: - mcnt = *p++; - printf ("/exactn/%d", mcnt); - do - { - putchar ('/'); - printchar (*p++); - } - while (--mcnt); - break; - - case start_memory: - mcnt = *p++; - printf ("/start_memory/%d/%d", mcnt, *p++); - break; - - case stop_memory: - mcnt = *p++; - printf ("/stop_memory/%d/%d", mcnt, *p++); - break; - - case duplicate: - printf ("/duplicate/%d", *p++); - break; - - case anychar: - printf ("/anychar"); - 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); - } - p += 1 + *p; - break; - } - - case begline: - printf ("/begline"); - break; - - case endline: - printf ("/endline"); - break; - - case on_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/on_failure_jump/0/%d", mcnt); - break; - - case on_failure_keep_string_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/on_failure_keep_string_jump/0/%d", mcnt); - break; - - case dummy_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/dummy_failure_jump/0/%d", mcnt); - 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); - break; - - case pop_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/pop_failure_jump/0/%d", mcnt); - break; - - case jump_past_alt: - extract_number_and_incr (&mcnt, &p); - printf ("/jump_past_alt/0/%d", mcnt); - break; - - case jump: - extract_number_and_incr (&mcnt, &p); - printf ("/jump/0/%d", mcnt); - 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_n: - extract_number_and_incr (&mcnt, &p); - extract_number_and_incr (&mcnt2, &p); - printf ("/jump_n/0/%d/0/%d", mcnt, 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 wordbound: - printf ("/wordbound"); - break; - - case notwordbound: - printf ("/notwordbound"); - break; - - case wordbeg: - printf ("/wordbeg"); - break; - - case wordend: - printf ("/wordend"); - -#ifdef emacs - case before_dot: - printf ("/before_dot"); - break; - - case at_dot: - printf ("/at_dot"); - break; - - case after_dot: - printf ("/after_dot"); - break; - - case syntaxspec: - printf ("/syntaxspec"); - mcnt = *p++; - printf ("/%d", mcnt); - break; - - case notsyntaxspec: - printf ("/notsyntaxspec"); - mcnt = *p++; - printf ("/%d", mcnt); - break; -#endif /* emacs */ - - case wordchar: - printf ("/wordchar"); - break; - - case notwordchar: - printf ("/notwordchar"); - break; - - case begbuf: - printf ("/begbuf"); - break; - - case endbuf: - printf ("/endbuf"); - break; - - default: - printf ("?%d", *(p-1)); - } - } - printf ("/\n"); -} - - -void -print_compiled_pattern (bufp) - struct re_pattern_buffer *bufp; -{ - unsigned char *buffer = bufp->buffer; - - print_partial_compiled_pattern (buffer, buffer + bufp->used); - printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated); - - if (bufp->fastmap_accurate && bufp->fastmap) - { - printf ("fastmap: "); - print_fastmap (bufp->fastmap); - } - - printf ("re_nsub: %d\t", bufp->re_nsub); - printf ("regs_alloc: %d\t", bufp->regs_allocated); - printf ("can_be_null: %d\t", bufp->can_be_null); - printf ("newline_anchor: %d\n", bufp->newline_anchor); - printf ("no_sub: %d\t", bufp->no_sub); - printf ("not_bol: %d\t", bufp->not_bol); - printf ("not_eol: %d\t", bufp->not_eol); - printf ("syntax: %d\n", bufp->syntax); - /* Perhaps we should print the translate table? */ -} - - -void -print_double_string (where, string1, size1, string2, size2) - const char *where; - const char *string1; - const char *string2; - int size1; - int size2; -{ - unsigned this_char; - - if (where == NULL) - printf ("(null)"); - else - { - if (FIRST_STRING_P (where)) - { - for (this_char = where - string1; this_char < size1; this_char++) - printchar (string1[this_char]); - - where = string2; - } - - for (this_char = where - string2; this_char < size2; this_char++) - printchar (string2[this_char]); - } -} - -#else /* not DEBUG */ - -#undef assert -#define assert(e) - -#define DEBUG_STATEMENT(e) -#define DEBUG_PRINT1(x) -#define DEBUG_PRINT2(x1, x2) -#define DEBUG_PRINT3(x1, x2, x3) -#define DEBUG_PRINT4(x1, x2, x3, x4) -#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) -#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) - -#endif /* not DEBUG */ - -/* 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; - - -/* Specify the precise syntax of regexps for compilation. This provides - for compatibility for various utilities which historically have - different, incompatible syntaxes. - - The argument SYNTAX is a bit mask comprised of the various bits - defined in regex.h. We return the old syntax. */ - -reg_syntax_t -re_set_syntax (syntax) - reg_syntax_t syntax; -{ - reg_syntax_t ret = re_syntax_options; - - re_syntax_options = syntax; - return ret; -} - -/* 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 */ - }; - -/* Subroutine declarations and macros for regex_compile. */ - -static void store_op1 (), store_op2 (); -static void insert_op1 (), insert_op2 (); -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 - if necessary. Also cast from a signed character in the constant - string passed to us by the user to an unsigned char that we can use - as an array index (in, e.g., `translate'). */ -#define PATFETCH(c) \ - do {if (p == pend) return REG_EEND; \ - c = (unsigned char) *p++; \ - if (translate) c = translate[c]; \ - } while (0) - -/* Fetch the next character in the uncompiled pattern, with no - translation. */ -#define PATFETCH_RAW(c) \ - do {if (p == pend) return REG_EEND; \ - c = (unsigned char) *p++; \ - } while (0) - -/* Go backwards one character in the pattern. */ -#define PATUNFETCH p-- - - -/* If `translate' is non-null, return translate[D], else just D. We - 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)) - - -/* Macros for outputting the compiled pattern into `buffer'. */ - -/* 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. */ -#define GET_BUFFER_SPACE(n) \ - while (b - bufp->buffer + (n) > bufp->allocated) \ - EXTEND_BUFFER () - -/* Make sure we have one more byte of buffer space and then add C to it. */ -#define BUF_PUSH(c) \ - do { \ - GET_BUFFER_SPACE (1); \ - *b++ = (unsigned char) (c); \ - } while (0) - - -/* Ensure we have two more bytes of buffer space and then append C1 and C2. */ -#define BUF_PUSH_2(c1, c2) \ - do { \ - GET_BUFFER_SPACE (2); \ - *b++ = (unsigned char) (c1); \ - *b++ = (unsigned char) (c2); \ - } while (0) - - -/* As with BUF_PUSH_2, except for three bytes. */ -#define BUF_PUSH_3(c1, c2, c3) \ - do { \ - GET_BUFFER_SPACE (3); \ - *b++ = (unsigned char) (c1); \ - *b++ = (unsigned char) (c2); \ - *b++ = (unsigned char) (c3); \ - } while (0) - - -/* 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. */ -#define STORE_JUMP(op, loc, to) \ - store_op1 (op, loc, (to) - (loc) - 3) - -/* Likewise, for a two-argument jump. */ -#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. */ -#define INSERT_JUMP(op, loc, to) \ - insert_op1 (op, loc, (to) - (loc) - 3, b) - -/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ -#define INSERT_JUMP2(op, loc, to, arg) \ - insert_op2 (op, loc, (to) - (loc) - 3, arg, b) - - -/* 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 - be too small, many things would have to change. */ -#define MAX_BUF_SIZE (1L << 16) - - -/* 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. */ -#define EXTEND_BUFFER() \ - do { \ - unsigned char *old_buffer = bufp->buffer; \ - if (bufp->allocated == MAX_BUF_SIZE) \ - return REG_ESIZE; \ - bufp->allocated <<= 1; \ - if (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; \ - } \ - } while (0) - - -/* Since we have one byte reserved for the register number argument to - {start,stop}_memory, the maximum number of groups we can report - things about is what fits in that byte. */ -#define MAX_REGNUM 255 - -/* But patterns can have more than `MAX_REGNUM' registers. We just - ignore the excess. */ -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. */ -typedef int pattern_offset_t; - -typedef struct -{ - pattern_offset_t begalt_offset; - pattern_offset_t fixup_alt_jump; - pattern_offset_t inner_group_offset; - pattern_offset_t laststart_offset; - regnum_t regnum; -} compile_stack_elt_t; - - -typedef struct -{ - compile_stack_elt_t *stack; - unsigned size; - unsigned avail; /* Offset of next open position. */ -} compile_stack_type; - - -#define INIT_COMPILE_STACK_SIZE 32 - -#define COMPILE_STACK_EMPTY (compile_stack.avail == 0) -#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) - -/* The next available element. */ -#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) - - -/* Set the bit for character C in a list. */ -#define SET_LIST_BIT(c) \ - (b[((unsigned char) (c)) / BYTEWIDTH] \ - |= 1 << (((unsigned char) c) % BYTEWIDTH)) - - -/* Get the next unsigned number in the uncompiled pattern. */ -#define GET_UNSIGNED_NUMBER(num) \ - { if (p != pend) \ - { \ - PATFETCH (c); \ - while (ISDIGIT (c)) \ - { \ - if (num < 0) \ - num = 0; \ - num = num * 10 + c - '0'; \ - if (p == pend) \ - break; \ - PATFETCH (c); \ - } \ - } \ - } - -#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ - -#define IS_CHAR_CLASS(string) \ - (STREQ (string, "alpha") || STREQ (string, "upper") \ - || STREQ (string, "lower") || STREQ (string, "digit") \ - || STREQ (string, "alnum") || STREQ (string, "xdigit") \ - || STREQ (string, "space") || STREQ (string, "print") \ - || STREQ (string, "punct") || STREQ (string, "graph") \ - || STREQ (string, "cntrl") || STREQ (string, "blank")) - -/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. - Returns one of error codes defined in `regex.h', or zero for success. - - Assumes the `allocated' (and perhaps `buffer') and `translate' - fields are set in BUFP on entry. - - If it succeeds, results are put in BUFP (if it returns an error, the - contents of BUFP are undefined): - `buffer' is the compiled pattern; - `syntax' is set to SYNTAX; - `used' is set to the length of the compiled pattern; - `fastmap_accurate' is zero; - `re_nsub' is the number of subexpressions in PATTERN; - `not_bol' and `not_eol' are zero; - - The `fastmap' and `newline_anchor' fields are neither - examined nor set. */ - -static reg_errcode_t -regex_compile (pattern, size, syntax, bufp) - const char *pattern; - int size; - reg_syntax_t syntax; - struct re_pattern_buffer *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; - - /* A random tempory spot in PATTERN. */ - const char *p1; - - /* Points to the end of the buffer, where we should append. */ - register unsigned char *b; - - /* Keeps track of unclosed groups. */ - compile_stack_type compile_stack; - - /* Points to the current (ending) position in the pattern. */ - const char *p = pattern; - const char *pend = pattern + size; - - /* How to translate the characters in the pattern. */ - char *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 - character can be added to that command or if the character requires - a new `exactn' command. */ - unsigned char *pending_exact = 0; - - /* Address of start of the most recently finished expression. - This tells, e.g., postfix * where to find the start of its - operand. Reset at the beginning of groups and alternatives. */ - unsigned char *laststart = 0; - - /* Address of beginning of regexp, or inside of last group. */ - unsigned char *begalt; - - /* Place in the uncompiled pattern (i.e., the {) to - which to go back if the interval is invalid. */ - 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 - last -- ends with a forward jump of this sort. */ - unsigned char *fixup_alt_jump = 0; - - /* Counts open-groups as they are encountered. Remembered for the - matching close-group on the compile stack, so the same register - number is put in the stop_memory as the start_memory. */ - regnum_t regnum = 0; - -#ifdef DEBUG - DEBUG_PRINT1 ("\nCompiling pattern: "); - if (debug) - { - unsigned debug_count; - - for (debug_count = 0; debug_count < size; debug_count++) - printchar (pattern[debug_count]); - putchar ('\n'); - } -#endif /* DEBUG */ - - /* Initialize the compile stack. */ - compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); - if (compile_stack.stack == NULL) - return REG_ESPACE; - - compile_stack.size = INIT_COMPILE_STACK_SIZE; - compile_stack.avail = 0; - - /* Initialize the pattern buffer. */ - bufp->syntax = syntax; - bufp->fastmap_accurate = 0; - bufp->not_bol = bufp->not_eol = 0; - - /* Set `used' to zero, so that if we return an error, the pattern - printer (for debugging) will think there's no pattern. We reset it - at the end. */ - bufp->used = 0; - - /* Always count groups, whether or not bufp->no_sub is set. */ - bufp->re_nsub = 0; - -#if !defined (emacs) && !defined (SYNTAX_TABLE) - /* Initialize the syntax table. */ - init_syntax_once (); -#endif - - if (bufp->allocated == 0) - { - 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); - } - 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; - - bufp->allocated = INIT_BUF_SIZE; - } - - begalt = b = bufp->buffer; - - /* Loop through the uncompiled pattern until we're at the end. */ - while (p != pend) - { - PATFETCH (c); - - switch (c) - { - case '^': - { - if ( /* If at start of pattern, it's an operator. */ - p == pattern + 1 - /* If context independent, it's an operator. */ - || syntax & RE_CONTEXT_INDEP_ANCHORS - /* Otherwise, depends on what's come before. */ - || at_begline_loc_p (pattern, p, syntax)) - 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 '+': - 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; - } - - { - /* 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; - - /* If there is a sequence of repetition chars, collapse it - down to just one (the right one). We can't combine - interval operators with these because of, e.g., `a{2}*', - which should only match an even number of `a's. */ - - for (;;) - { - zero_times_ok |= c != '+'; - many_times_ok |= c != '?'; - - if (p == pend) - break; - - PATFETCH (c); - - if (c == '*' - || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) - ; - - else if (syntax & RE_BK_PLUS_QM && c == '\\') - { - if (p == pend) return REG_EESCAPE; - - PATFETCH (c1); - if (!(c1 == '+' || c1 == '?')) - { - PATUNFETCH; - PATUNFETCH; - break; - } - - c = c1; - } - else - { - PATUNFETCH; - break; - } - - /* If we get here, we found another repeat character. */ - } - - /* Star, etc. applied to an empty pattern is equivalent - to an empty pattern. */ - if (!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 ('.') - && 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; - } - } - break; - - - case '.': - laststart = b; - BUF_PUSH (anychar); - break; - - - case '[': - { - boolean had_char_class = false; - - if (p == pend) 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. */ - GET_BUFFER_SPACE (34); - - 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++; - - /* Remember the first position in the bracket expression. */ - p1 = p; - - /* Push the number of bytes in the bitmap. */ - BUF_PUSH ((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'); - - /* Read in characters and ranges, setting map bits. */ - for (;;) - { - if (p == pend) return REG_EBRACK; - - PATFETCH (c); - - /* \ might escape characters inside [...] and [^...]. */ - if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') - { - if (p == pend) return REG_EESCAPE; - - PATFETCH (c1); - SET_LIST_BIT (c1); - continue; - } - - /* 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; - - - case '(': - 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 '\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; - - - case '{': - if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) - goto handle_interval; - else - goto normal_char; - - - case '\\': - if (p == pend) 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); - - switch (c) - { - case '(': - if (syntax & RE_NO_BK_PARENS) - goto normal_backslash; - - 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; - - 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); - } - - compile_stack.avail++; - - 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; - - - 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; - - 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); - } - - /* 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; - /* 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> <succed_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; -#endif /* emacs */ - - - case 'w': - laststart = b; - BUF_PUSH (wordchar); - break; - - - case 'W': - laststart = b; - BUF_PUSH (notwordchar); - break; - - - case '<': - BUF_PUSH (wordbeg); - break; - - case '>': - BUF_PUSH (wordend); - break; - - case 'b': - BUF_PUSH (wordbound); - break; - - case 'B': - BUF_PUSH (notwordbound); - break; - - case '`': - BUF_PUSH (begbuf); - break; - - case '\'': - BUF_PUSH (endbuf); - 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; - - c1 = c - '0'; - - if (c1 > regnum) - return REG_ESUBREG; - - /* 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; - - - default: - /* Expects the character in `c'. */ - normal_char: - /* If no exactn currently being built. */ - if (!pending_exact - - /* 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 - - /* If followed by a repetition operator. */ - || *p == '*' || *p == '^' - || ((syntax & RE_BK_PLUS_QM) - ? *p == '\\' && (p[1] == '+' || p[1] == '?') - : (*p == '+' || *p == '?')) - || ((syntax & RE_INTERVALS) - && ((syntax & RE_NO_BK_BRACES) - ? *p == '{' - : (p[0] == '\\' && p[1] == '{')))) - { - /* Start building a new exactn. */ - - laststart = b; - - BUF_PUSH_2 (exactn, 0); - pending_exact = b - 1; - } - - BUF_PUSH (c); - (*pending_exact)++; - break; - } /* switch (c) */ - } /* while p != pend */ - - - /* Through the pattern now. */ - - if (fixup_alt_jump) - STORE_JUMP (jump_past_alt, fixup_alt_jump, b); - - if (!COMPILE_STACK_EMPTY) - return REG_EPAREN; - - free (compile_stack.stack); - - /* We have succeeded; set the length of the buffer. */ - bufp->used = b - bufp->buffer; - -#ifdef DEBUG - if (debug) - { - DEBUG_PRINT1 ("\nCompiled pattern: "); - print_compiled_pattern (bufp); - } -#endif /* DEBUG */ - - return REG_NOERROR; -} /* regex_compile */ - -/* Subroutines for `regex_compile'. */ - -/* Store OP at LOC followed by two-byte integer parameter ARG. */ - -static void -store_op1 (op, loc, arg) - re_opcode_t op; - unsigned char *loc; - int arg; -{ - *loc = (unsigned char) op; - STORE_NUMBER (loc + 1, arg); -} - - -/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ - -static void -store_op2 (op, loc, arg1, arg2) - re_opcode_t op; - unsigned char *loc; - int arg1, arg2; -{ - *loc = (unsigned char) op; - STORE_NUMBER (loc + 1, arg1); - STORE_NUMBER (loc + 3, arg2); -} - - -/* Copy the bytes from LOC to END to open up three bytes of space at LOC - for OP followed by two-byte integer parameter ARG. */ - -static void -insert_op1 (op, loc, arg, end) - re_opcode_t op; - unsigned char *loc; - int arg; - unsigned char *end; -{ - register unsigned char *pfrom = end; - register unsigned char *pto = end + 3; - - while (pfrom != loc) - *--pto = *--pfrom; - - store_op1 (op, loc, arg); -} - - -/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ - -static void -insert_op2 (op, loc, arg1, arg2, end) - re_opcode_t op; - unsigned char *loc; - int arg1, arg2; - unsigned char *end; -{ - register unsigned char *pfrom = end; - register unsigned char *pto = end + 5; - - while (pfrom != loc) - *--pto = *--pfrom; - - store_op2 (op, loc, arg1, arg2); -} - - -/* P points to just after a ^ in PATTERN. Return true if that ^ comes - after an alternative or a begin-subexpression. We assume there is at - least one character before the ^. */ - -static boolean -at_begline_loc_p (pattern, p, syntax) - const char *pattern, *p; - reg_syntax_t syntax; -{ - const char *prev = p - 2; - boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; - - return - /* After a subexpression? */ - (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) - /* After an alternative? */ - || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); -} - - -/* The dual of at_begline_loc_p. This one is for $. We assume there is - at least one character after the $, i.e., `P < PEND'. */ - -static boolean -at_endline_loc_p (p, pend, syntax) - const char *p, *pend; - int syntax; -{ - const char *next = p; - boolean next_backslash = *next == '\\'; - const char *next_next = p + 1 < pend ? p + 1 : NULL; - - return - /* Before a subexpression? */ - (syntax & RE_NO_BK_PARENS ? *next == ')' - : next_backslash && next_next && *next_next == ')') - /* Before an alternative? */ - || (syntax & RE_NO_BK_VBAR ? *next == '|' - : next_backslash && next_next && *next_next == '|'); -} - - -/* Returns true if REGNUM is in one of COMPILE_STACK's elements and - false if it's not. */ - -static boolean -group_in_compile_stack (compile_stack, regnum) - compile_stack_type compile_stack; - regnum_t regnum; -{ - int this_element; - - for (this_element = compile_stack.avail - 1; - this_element >= 0; - this_element--) - if (compile_stack.stack[this_element].regnum == regnum) - return true; - - return false; -} - - -/* Read the ending character of a range (in a bracket expression) from the - uncompiled pattern *P_PTR (which ends at PEND). We assume the - starting character is in `P[-2]'. (`P[-1]' is the character `-'.) - Then we set the translation of all bits between the starting and - ending characters (inclusive) in the compiled pattern B. - - Return an error code. - - We use these short variable names so we can use the same macros as - `regex_compile' itself. */ - -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; - -typedef const unsigned char *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(pattern_op, fail_stack) \ - ((FAIL_STACK_FULL () \ - && !DOUBLE_FAIL_STACK (fail_stack)) \ - ? 0 \ - : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \ - 1)) - -/* This pushes an item onto the failure stack. Must be a four-byte - value. Assumes the variable `fail_stack'. Probably should only - be called from within `PUSH_FAILURE_POINT'. */ -#define PUSH_FAILURE_ITEM(item) \ - fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item - -/* The complement operation. Assumes `fail_stack' is nonempty. */ -#define POP_FAILURE_ITEM() 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_ITEM -#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM () -#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"); \ - \ - 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_ITEM (regstart[this_reg]); \ - \ - DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ - PUSH_FAILURE_ITEM (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_ITEM (reg_info[this_reg].word); \ - } \ - \ - DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\ - PUSH_FAILURE_ITEM (lowest_active_reg); \ - \ - DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\ - PUSH_FAILURE_ITEM (highest_active_reg); \ - \ - DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \ - DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ - PUSH_FAILURE_ITEM (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_ITEM (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_ITEM (); \ - 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_ITEM (); \ - DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \ - DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ - \ - /* Restore register info. */ \ - high_reg = (unsigned) POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \ - \ - low_reg = (unsigned) POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \ - \ - 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_ITEM (); \ - DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \ - \ - regend[this_reg] = (const char *) POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ - \ - regstart[this_reg] = (const char *) POP_FAILURE_ITEM (); \ - DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_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 - characters can start a string that matches the pattern. This fastmap - is used by re_search to skip quickly over impossible starting points. - - The caller must supply the address of a (1 << BYTEWIDTH)-byte data - area as BUFP->fastmap. - - We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in - the pattern buffer. - - Returns 0 if we succeed, -2 if an internal error. */ - -int -re_compile_fastmap (bufp) - struct re_pattern_buffer *bufp; -{ - int j, k; - fail_stack_type fail_stack; -#ifndef REGEX_MALLOC - char *destination; -#endif - /* We don't push any register information onto the failure stack. */ - unsigned num_regs = 0; - - register char *fastmap = bufp->fastmap; - unsigned char *pattern = bufp->buffer; - unsigned long size = bufp->used; - const unsigned char *p = pattern; - register unsigned char *pend = pattern + size; - - /* Assume that each path through the pattern can be null until - 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; - - /* We aren't doing a `succeed_n' to begin with. */ - boolean succeed_n_p = false; - - assert (fastmap != NULL && p != NULL); - - INIT_FAIL_STACK (); - 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 ()) - { - 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]; - } - - /* 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 - { - - /* 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; - - - /* Following are the cases which match a character. These end - with `break'. */ - - case exactn: - fastmap[p[1]] = 1; - break; - - - case charset: - for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) - if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) - 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; - - for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) - if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) - fastmap[j] = 1; - break; - - - case wordchar: - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) == Sword) - fastmap[j] = 1; - break; - - - case notwordchar: - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) != Sword) - fastmap[j] = 1; - break; - - - case anychar: - /* `.' matches anything ... */ - for (j = 0; j < (1 << BYTEWIDTH); j++) - fastmap[j] = 1; - - /* ... 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; - - /* Otherwise, have to check alternative paths. */ - break; - - -#ifdef emacs - case syntaxspec: - k = *p++; - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) == (enum syntaxcode) k) - fastmap[j] = 1; - break; - - - case notsyntaxspec: - k = *p++; - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) != (enum syntaxcode) k) - fastmap[j] = 1; - break; - - - /* All cases after this match the empty string. These end with - `continue'. */ - - - case before_dot: - case at_dot: - case after_dot: - continue; -#endif /* not emacs */ - - - case no_op: - case begline: - case endline: - case begbuf: - case endbuf: - case wordbound: - case notwordbound: - case wordbeg: - case wordend: - case push_dummy_failure: - continue; - - - case jump_n: - case pop_failure_jump: - case maybe_pop_jump: - case jump: - case jump_past_alt: - case dummy_failure_jump: - 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 - && (re_opcode_t) *p != succeed_n) - continue; - - 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 () - && fail_stack.stack[fail_stack.avail - 1] == p) - fail_stack.avail--; - - continue; - - - 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; - - if (succeed_n_p) - { - EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ - succeed_n_p = false; - } - - continue; - - - case succeed_n: - /* Get to the number of times to succeed. */ - p += 2; - - /* Increment p past the n for when k != 0. */ - EXTRACT_NUMBER_AND_INCR (k, p); - if (k == 0) - { - p -= 4; - succeed_n_p = true; /* Spaghetti code alert. */ - goto handle_on_failure_jump; - } - continue; - - - case set_number_at: - p += 4; - continue; - - - case start_memory: - case stop_memory: - p += 2; - continue; - - - default: - 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. */ - 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). */ - bufp->can_be_null |= path_can_be_null; - return 0; -} /* re_compile_fastmap */ - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use - this memory for recording register information. STARTS and ENDS - must be allocated using the malloc library routine, and must each - be at least NUM_REGS * sizeof (regoff_t) bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ - -void -re_set_registers (bufp, regs, num_regs, starts, ends) - struct re_pattern_buffer *bufp; - struct re_registers *regs; - unsigned num_regs; - regoff_t *starts, *ends; -{ - if (num_regs) - { - bufp->regs_allocated = REGS_REALLOCATE; - regs->num_regs = num_regs; - regs->start = starts; - regs->end = ends; - } - else - { - bufp->regs_allocated = REGS_UNALLOCATED; - regs->num_regs = 0; - regs->start = regs->end = (regoff_t) 0; - } -} - -/* Searching routines. */ - -/* Like re_search_2, below, but only one string is specified, and - doesn't let you say where to stop matching. */ - -int -re_search (bufp, string, size, startpos, range, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, startpos, range; - struct re_registers *regs; -{ - return re_search_2 (bufp, NULL, 0, string, size, startpos, range, - regs, size); -} - - -/* Using the compiled pattern in BUFP->buffer, first tries to match the - virtual concatenation of STRING1 and STRING2, starting first at index - STARTPOS, then at STARTPOS + 1, and so on. - - STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. - - RANGE is how far to scan while trying to match. RANGE = 0 means try - only at STARTPOS; in general, the last start tried is STARTPOS + - RANGE. - - In REGS, return the indices of the virtual concatenation of STRING1 - and STRING2 that matched the entire BUFP->buffer and its contained - subexpressions. - - Do not consider matching one past the index STOP in the virtual - concatenation of STRING1 and STRING2. - - We return either the position in the strings at which the match was - found, -1 if no match, or -2 if error (such as failure - stack overflow). */ - -int -re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int startpos; - int range; - struct re_registers *regs; - int stop; -{ - int val; - register char *fastmap = bufp->fastmap; - register char *translate = bufp->translate; - int total_size = size1 + size2; - int endpos = startpos + range; - - /* 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; - 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. */ - if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0) - { - if (startpos > 0) - return -1; - else - range = 1; - } - - /* Update the fastmap now if not correct already. */ - if (fastmap && !bufp->fastmap_accurate) - if (re_compile_fastmap (bufp) == -2) - return -2; - - /* Loop through the string, looking for a place to start matching. */ - for (;;) - { - /* 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. */ - if (fastmap && startpos < total_size && !bufp->can_be_null) - { - 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; - - /* 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--; - else - while (range > lim && !fastmap[(unsigned char) *d++]) - range--; - - startpos += irange - range; - } - else /* Searching backwards. */ - { - register char c = (size1 == 0 || startpos >= size1 - ? string2[startpos - size1] - : string1[startpos]); - - if (!fastmap[(unsigned char) TRANSLATE (c)]) - 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) - return -1; - - val = re_match_2 (bufp, string1, size1, string2, size2, - startpos, regs, stop); - if (val >= 0) - return startpos; - - if (val == -2) - return -2; - - advance: - if (!range) - break; - else if (range > 0) - { - range--; - startpos++; - } - else - { - range++; - startpos--; - } - } - return -1; -} /* re_search_2 */ - -/* Declarations and macros for re_match_2. */ - -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. - This must not be longer than one word, because we push this value - onto the failure stack. 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) - - -/* 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) - - -/* Macros for dealing with the split strings in re_match_2. */ - -#define MATCHING_IN_FIRST_STRING (dend == end_match_1) - -/* Call before fetching a character with *d. This switches over to - string2 if necessary. */ -#define PREFETCH() \ - while (d == dend) \ - { \ - /* End of string2 => fail. */ \ - if (dend == end_match_2) \ - goto fail; \ - /* End of string1 => advance to string2. */ \ - d = string2; \ - dend = end_match_2; \ - } - - -/* Test if at very beginning or at very end of the virtual concatenation - of `string1' and `string2'. If only one string, it's `string2'. */ -#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) -#define AT_STRINGS_END(d) ((d) == end2) - - -/* Test if D points to a character which is word-constituent. We have - two special cases to check for: if past the end of string1, look at - the first character in string2; and if before the beginning of - string2, look at the last character in string1. */ -#define WORDCHAR_P(d) \ - (SYNTAX ((d) == end1 ? *string2 \ - : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ - == Sword) - -/* 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)) - - -/* Free everything we malloc. */ -#ifdef REGEX_MALLOC -#define FREE_VAR(var) if (var) free (var); var = NULL -#define FREE_VARIABLES() \ - do { \ - FREE_VAR (fail_stack.stack); \ - FREE_VAR (regstart); \ - FREE_VAR (regend); \ - FREE_VAR (old_regstart); \ - FREE_VAR (old_regend); \ - FREE_VAR (best_regstart); \ - FREE_VAR (best_regend); \ - FREE_VAR (reg_info); \ - 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 */ - - -/* 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 - 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. */ -#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. */ -/* re_match is like re_match_2 except it takes only a single string. */ - -int -re_match (bufp, string, size, pos, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, pos; - struct re_registers *regs; - { - return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size); -} -#endif /* not emacs */ - - -/* re_match_2 matches the compiled pattern in BUFP against the - the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 - and SIZE2, respectively). We start matching at POS, and stop - 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 - 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 - matched substring. */ - -int -re_match_2 (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; - - /* Just past the end of the corresponding string. */ - const char *end1, *end2; - - /* Pointers into string1 and string2, just past the last characters in - 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. */ - const char *d, *dend; - - /* Where we are in the pattern, and the end of the pattern. */ - 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; - - /* Failure point stack. Each place that can handle a failure further - down the line pushes a failure point on this stack. It consists of - restart, regend, and reg_info for all registers corresponding to - the subexpressions we're currently inside, plus the number of such - registers, and, finally, two char *'s. The first char * is where - to resume scanning the pattern; the second one is where to resume - scanning the strings. If the latter is zero, the failure point is - a ``dummy''; if a failure happens and the failure point is a dummy, - it gets discarded and the next next one is tried. */ - fail_stack_type fail_stack; -#ifdef DEBUG - static unsigned failure_id = 0; - unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; -#endif - - /* We fill all the registers internally, independent of what we - return, for use in backreferences. The number here includes - an element for register zero. */ - unsigned num_regs = bufp->re_nsub + 1; - - /* The currently active registers. */ - unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG; - unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG; - - /* Information on the contents of registers. These are pointers into - the input strings; they record just what was matched (on this - attempt) by a subexpression part of the pattern, that is, the - regnum-th regstart pointer points to where in the pattern we began - matching and the regnum-th regend points to right after where we - stopped matching the regnum-th subexpression. (The zeroth register - keeps track of what the whole pattern matches.) */ - const char **regstart, **regend; - - /* 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. */ - const char **old_regstart, **old_regend; - - /* 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. */ - register_info_type *reg_info; - - /* 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; - const char **best_regstart, **best_regend; - - /* 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 - 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 - initialize this to NULL so that when we backtrack the first time - and need to test it, it's not garbage. */ - const char *match_end = NULL; - - /* Used when we pop values we don't care about. */ - const char **reg_dummy; - register_info_type *reg_info_dummy; - -#ifdef DEBUG - /* Counts the total number of registers pushed. */ - unsigned num_regs_pushed = 0; -#endif - - DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); - - INIT_FAIL_STACK (); - - /* 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 - pattern), even though we never use it, since it simplifies the - array indexing. We should fix this. */ - if (bufp->re_nsub) - { - regstart = REGEX_TALLOC (num_regs, const char *); - regend = REGEX_TALLOC (num_regs, const char *); - old_regstart = REGEX_TALLOC (num_regs, const char *); - old_regend = REGEX_TALLOC (num_regs, const char *); - best_regstart = REGEX_TALLOC (num_regs, const char *); - best_regend = REGEX_TALLOC (num_regs, const char *); - reg_info = REGEX_TALLOC (num_regs, register_info_type); - reg_dummy = REGEX_TALLOC (num_regs, const char *); - 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; - } - } -#ifdef REGEX_MALLOC - else - { - /* We must initialize all our variables to NULL, so that - `FREE_VARIABLES' doesn't try to free them. */ - regstart = regend = old_regstart = old_regend = best_regstart - = best_regend = reg_dummy = NULL; - reg_info = reg_info_dummy = (register_info_type *) NULL; - } -#endif /* REGEX_MALLOC */ - - /* The starting position is bogus. */ - if (pos < 0 || pos > size1 + size2) - { - FREE_VARIABLES (); - return -1; - } - - /* Initialize subexpression text positions to -1 to mark ones that no - start_memory/stop_memory has been seen for. Also initialize the - register information struct. */ - for (mcnt = 1; mcnt < num_regs; mcnt++) - { - regstart[mcnt] = regend[mcnt] - = 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; - MATCHED_SOMETHING (reg_info[mcnt]) = 0; - EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; - } - - /* We move `string1' into `string2' if the latter's empty -- but not if - `string1' is null. */ - if (size2 == 0 && string1 != NULL) - { - string2 = string1; - size2 = size1; - string1 = 0; - size1 = 0; - } - end1 = string1 + size1; - end2 = string2 + size2; - - /* Compute where to stop matching, within the two strings. */ - if (stop <= size1) - { - end_match_1 = string1 + stop; - end_match_2 = string2; - } - else - { - end_match_1 = end1; - end_match_2 = string2 + stop - size1; - } - - /* `p' scans through the pattern as `d' scans through the data. - `dend' is the end of the input string that `d' points within. `d' - is advanced into the following input string whenever necessary, but - this happens before fetching; therefore, at the beginning of the - loop, `d' can be pointing at the end of a string, but it cannot - equal `string2'. */ - if (size1 > 0 && pos <= size1) - { - d = string1 + pos; - dend = end_match_1; - } - else - { - d = string2 + pos - size1; - dend = end_match_2; - } - - DEBUG_PRINT1 ("The compiled pattern is: "); - DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); - DEBUG_PRINT1 ("The string to match is: `"); - DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); - DEBUG_PRINT1 ("'\n"); - - /* 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 (;;) - { - DEBUG_PRINT2 ("\n0x%x: ", p); - - if (p == pend) - { /* End of pattern means we might have succeeded. */ - 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) - { - DEBUG_PRINT1 ("backtracking.\n"); - - if (!FAIL_STACK_EMPTY ()) - { /* More failure points to try. */ - boolean same_str_p = (FIRST_STRING_P (match_end) - == MATCHING_IN_FIRST_STRING); - - /* 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; - - DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); - - 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. */ - 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++) - { - regstart[mcnt] = best_regstart[mcnt]; - regend[mcnt] = best_regend[mcnt]; - } - } - } /* d != end_match_2 */ - - DEBUG_PRINT1 ("Accepting match.\n"); - - /* 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 - 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); - } - - /* 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 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); - - mcnt = d - pos - (MATCHING_IN_FIRST_STRING - ? string1 - : string2 - size1); - - DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); - - return mcnt; - } - - /* Otherwise match next pattern command. */ -#ifdef SWITCH_ENUM_BUG - switch ((int) ((re_opcode_t) *p++)) -#else - switch ((re_opcode_t) *p++) -#endif - { - /* 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; - - - /* 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); - - /* This is written out as an if-else so we don't waste time - testing `translate' inside the loop. */ - if (translate) - { - do - { - PREFETCH (); - if (translate[(unsigned char) *d++] != (char) *p++) - goto fail; - } - while (--mcnt); - } - else - { - do - { - PREFETCH (); - if (*d++ != (char) *p++) goto fail; - } - while (--mcnt); - } - SET_REGS_MATCHED (); - break; - - - /* Match any character except possibly a newline or a null. */ - case anychar: - DEBUG_PRINT1 ("EXECUTING anychar.\n"); - - PREFETCH (); - - if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') - || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) - goto fail; - - SET_REGS_MATCHED (); - DEBUG_PRINT2 (" Matched `%d'.\n", *d); - d++; - break; - - - case charset: - case charset_not: - { - register unsigned char c; - boolean not = (re_opcode_t) *(p - 1) == charset_not; - - DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); - - PREFETCH (); - c = TRANSLATE (*d); /* The character to match. */ - - /* Cast to `unsigned' instead of `unsigned char' in case the - bit list is a full 32 bytes long. */ - if (c < (unsigned) (*p * BYTEWIDTH) - && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; - - p += 1 + *p; - - if (!not) goto fail; - - SET_REGS_MATCHED (); - d++; - 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: - DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); - - /* 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]; - DEBUG_PRINT2 (" old_regstart: %d\n", - POINTER_TO_OFFSET (old_regstart[*p])); - - 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; - - /* This is the new highest active register. */ - highest_active_reg = *p; - - /* 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; - 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. */ - 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] - : regend[*p]; - DEBUG_PRINT2 (" old_regend: %d\n", - POINTER_TO_OFFSET (old_regend[*p])); - - 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; - - /* 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; - } - - /* 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; - - p1 = p + 2; - mcnt = 0; - switch ((re_opcode_t) *p1++) - { - case jump_n: - is_a_jump_n = true; - case pop_failure_jump: - case maybe_pop_jump: - case jump: - case dummy_failure_jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if (is_a_jump_n) - p1 += 2; - break; - - 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 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). */ - - if (EVER_MATCHED_SOMETHING (reg_info[*p])) - { - unsigned r; - - EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; - - /* Restore this and inner groups' (if any) registers. */ - for (r = *p; r < *p + *(p + 1); r++) - { - regstart[r] = old_regstart[r]; - - /* xx why this test? */ - if ((int) old_regend[r] >= (int) regstart[r]) - regend[r] = old_regend[r]; - } - } - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - PUSH_FAILURE_POINT (p1 + mcnt, d, -2); - - goto fail; - } - } - - /* 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: - { - register const char *d2, *dend2; - 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; - - /* Where in input to try to start matching. */ - d2 = regstart[regno]; - - /* Where to stop matching; if both the place to start and - the place to stop matching are in the same string, then - set to the place to stop, otherwise, for now have to use - the end of the first string. */ - - dend2 = ((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. */ - 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]; - } - /* At end of register contents => success */ - if (d2 == dend2) break; - - /* If necessary, advance to next segment in data. */ - PREFETCH (); - - /* How many characters left in this segment to match. */ - mcnt = dend - d; - - /* Want how many consecutive characters we can match in - one shot, so, if necessary, adjust the count. */ - if (mcnt > dend2 - d2) - mcnt = dend2 - d2; - - /* Compare that many; failure if mismatch, else move - past them. */ - if (translate - ? bcmp_translate (d, d2, mcnt, translate) - : bcmp (d, d2, mcnt)) - goto fail; - d += mcnt, d2 += mcnt; - } - } - 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. */ - case begline: - 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; - - - /* endline is the dual of begline. */ - case endline: - DEBUG_PRINT1 ("EXECUTING endline.\n"); - - 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; - - - /* Match at the very beginning of the data. */ - 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"); - 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; - - - /* 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.) - - 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); - } - - 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: - 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) - { - /* 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"); - } - - 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]); - } - - 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) - && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; - - /* `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 -= 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"); - goto unconditional_jump; - } - /* 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: - unconditional_jump: - 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); - 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; - - /* 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); - } - else if (mcnt == 0) - { - 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; - - 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); - goto unconditional_jump; - } - /* If don't have to jump any more, skip over the rest of command. */ - else - p += 4; - break; - - case set_number_at: - { - 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); - STORE_NUMBER (p1, mcnt); - break; - } - - case wordbound: - DEBUG_PRINT1 ("EXECUTING wordbound.\n"); - if (AT_WORD_BOUNDARY (d)) - break; - goto fail; - - case notwordbound: - DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); - if (AT_WORD_BOUNDARY (d)) - 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; - - 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; - -#ifdef emacs -#ifdef emacs19 - 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; -#else /* not emacs19 */ - case at_dot: - DEBUG_PRINT1 ("EXECUTING at_dot.\n"); - if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point) - goto fail; - break; -#endif /* not emacs19 */ - - case syntaxspec: - DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); - mcnt = *p++; - goto matchsyntax; - - case wordchar: - DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); - mcnt = (int) Sword; - matchsyntax: - PREFETCH (); - if (SYNTAX (*d++) != (enum syntaxcode) mcnt) - goto fail; - SET_REGS_MATCHED (); - break; - - case notsyntaxspec: - DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); - mcnt = *p++; - goto matchnotsyntax; - - case notwordchar: - DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); - mcnt = (int) Sword; - matchnotsyntax: - PREFETCH (); - if (SYNTAX (*d++) == (enum syntaxcode) mcnt) - goto fail; - SET_REGS_MATCHED (); - break; - -#else /* not emacs */ - case wordchar: - DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); - PREFETCH (); - if (!WORDCHAR_P (d)) - goto fail; - SET_REGS_MATCHED (); - d++; - break; - - case notwordchar: - DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); - PREFETCH (); - if (WORDCHAR_P (d)) - goto fail; - SET_REGS_MATCHED (); - d++; - break; -#endif /* not emacs */ - - default: - abort (); - } - continue; /* Successfully executed one pattern command; keep going. */ - - - /* We goto here if a matching operation fails. */ - fail: - if (!FAIL_STACK_EMPTY ()) - { /* A restart point is known. Restore to that state. */ - DEBUG_PRINT1 ("\nFAIL:\n"); - POP_FAILURE_POINT (d, p, - lowest_active_reg, highest_active_reg, - regstart, regend, reg_info); - - /* If this failure point is a dummy, try the next one. */ - if (!p) - goto fail; - - /* If we failed to the end of the pattern, don't examine *p. */ - assert (p <= pend); - if (p < pend) - { - boolean is_a_jump_n = false; - - /* If failed to a backwards jump that's part of a repetition - loop, need to pop this failure point and use the next one. */ - switch ((re_opcode_t) *p) - { - case jump_n: - is_a_jump_n = true; - case maybe_pop_jump: - case pop_failure_jump: - case jump: - p1 = p + 1; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - - if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) - || (!is_a_jump_n - && (re_opcode_t) *p1 == on_failure_jump)) - goto fail; - break; - default: - /* do nothing */ ; - } - } - - if (d >= string1 && d <= end1) - dend = end_match_1; - } - else - break; /* Matching at this starting point really fails. */ - } /* for (;;) */ - - if (best_regs_set) - goto restore_best_regs; - - FREE_VARIABLES (); - - return -1; /* Failure to match. */ -} /* re_match_2 */ - -/* Subroutine definitions for re_match_2. */ - - -/* We are passed P pointing to a register number after a start_memory. - - Return true if the pattern up to the corresponding stop_memory can - match the empty string, and false otherwise. - - If we find the matching stop_memory, sets P to point to one past its number. - Otherwise, sets P to an undefined byte less than or equal to END. - - We don't handle duplicates properly (yet). */ - -static boolean -group_match_null_string_p (p, end, reg_info) - unsigned char **p, *end; - register_info_type *reg_info; -{ - int mcnt; - /* Point to after the args to the start_memory. */ - unsigned char *p1 = *p + 2; - - while (p1 < end) - { - /* Skip over opcodes that can match nothing, and return true or - false, as appropriate, when we get to one that can't, or to the - matching stop_memory. */ - - switch ((re_opcode_t) *p1) - { - /* Could be either a loop or a series of alternatives. */ - case on_failure_jump: - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - - /* If the next operation is not a jump backwards in the - pattern. */ - - if (mcnt >= 0) - { - /* Go through the on_failure_jumps of the alternatives, - seeing if any of the alternatives cannot match nothing. - The last alternative starts with only a jump, - whereas the rest start with on_failure_jump and end - with a jump, e.g., here is the pattern for `a|b|c': - - /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 - /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 - /exactn/1/c - - So, we have to first go through the first (n-1) - alternatives and then deal with the last one separately. */ - - - /* Deal with the first (n-1) alternatives, which start - with an on_failure_jump (see above) that jumps to right - past a jump_past_alt. */ - - while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) - { - /* `mcnt' holds how many bytes long the alternative - is, including the ending `jump_past_alt' and - its number. */ - - if (!alt_match_null_string_p (p1, p1 + mcnt - 3, - reg_info)) - return false; - - /* Move to right after this alternative, including the - jump_past_alt. */ - p1 += mcnt; - - /* Break if it's the beginning of an n-th alternative - that doesn't begin with an on_failure_jump. */ - if ((re_opcode_t) *p1 != on_failure_jump) - break; - - /* Still have to check that it's not an n-th - alternative that starts with an on_failure_jump. */ - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) - { - /* Get to the beginning of the n-th alternative. */ - p1 -= 3; - break; - } - } - - /* Deal with the last alternative: go back and get number - of the `jump_past_alt' just before it. `mcnt' contains - the length of the alternative. */ - EXTRACT_NUMBER (mcnt, p1 - 2); - - if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) - return false; - - p1 += mcnt; /* Get past the n-th alternative. */ - } /* if mcnt > 0 */ - break; - - - case stop_memory: - assert (p1[1] == **p); - *p = p1 + 2; - return true; - - - default: - if (!common_op_match_null_string_p (&p1, end, reg_info)) - return false; - } - } /* while p1 < end */ - - return false; -} /* group_match_null_string_p */ - - -/* Similar to group_match_null_string_p, but doesn't deal with alternatives: - It expects P to be the first byte of a single alternative and END one - byte past the last. The alternative can contain groups. */ - -static boolean -alt_match_null_string_p (p, end, reg_info) - unsigned char *p, *end; - register_info_type *reg_info; -{ - int mcnt; - unsigned char *p1 = p; - - while (p1 < end) - { - /* Skip over opcodes that can match nothing, and break when we get - to one that can't. */ - - switch ((re_opcode_t) *p1) - { - /* It's a loop. */ - case on_failure_jump: - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - break; - - default: - if (!common_op_match_null_string_p (&p1, end, reg_info)) - return false; - } - } /* while p1 < end */ - - return true; -} /* alt_match_null_string_p */ - - -/* Deals with the ops common to group_match_null_string_p and - alt_match_null_string_p. - - Sets P to one after the op and its arguments, if any. */ - -static boolean -common_op_match_null_string_p (p, end, reg_info) - unsigned char **p, *end; - register_info_type *reg_info; -{ - int mcnt; - boolean ret; - int reg_no; - unsigned char *p1 = *p; - - switch ((re_opcode_t) *p1++) - { - case no_op: - case begline: - case endline: - case begbuf: - case endbuf: - case wordbeg: - case wordend: - case wordbound: - case notwordbound: -#ifdef emacs - case before_dot: - case at_dot: - case after_dot: -#endif - break; - - case start_memory: - reg_no = *p1; - assert (reg_no > 0 && reg_no <= MAX_REGNUM); - ret = group_match_null_string_p (&p1, end, reg_info); - - /* Have to set this here in case we're checking a group which - contains a group and a back reference to it. */ - - if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) - REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; - - if (!ret) - return false; - break; - - /* If this is an optimized succeed_n for zero times, make the jump. */ - case jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if (mcnt >= 0) - p1 += mcnt; - else - return false; - break; - - case succeed_n: - /* Get to the number of times to succeed. */ - p1 += 2; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - - if (mcnt == 0) - { - p1 -= 4; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - } - else - return false; - break; - - case duplicate: - if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) - return false; - break; - - case set_number_at: - p1 += 4; - - default: - /* All other opcodes mean we cannot match the empty string. */ - return false; - } - - *p = p1; - return true; -} /* common_op_match_null_string_p */ - - -/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN - bytes; nonzero otherwise. */ - -static int -bcmp_translate (s1, s2, len, translate) - unsigned char *s1, *s2; - register int len; - char *translate; -{ - register unsigned char *p1 = s1, *p2 = s2; - while (len) - { - if (translate[*p1++] != translate[*p2++]) return 1; - len--; - } - return 0; -} - -/* Entry points for GNU code. */ - -/* re_compile_pattern is the GNU regular expression compiler: it - compiles PATTERN (of length SIZE) and puts the result in BUFP. - Returns 0 if the pattern was valid, otherwise an error string. - - Assumes the `allocated' (and perhaps `buffer') and `translate' fields - are set in BUFP on entry. - - We call regex_compile to do the actual compilation. */ - -const char * -re_compile_pattern (pattern, length, bufp) - const char *pattern; - int length; - struct re_pattern_buffer *bufp; -{ - reg_errcode_t ret; - - /* GNU code is written to assume at least RE_NREGS registers will be set - (and at least one extra will be -1). */ - bufp->regs_allocated = REGS_UNALLOCATED; - - /* And GNU code determines whether or not to get register information - by passing null for the REGS argument to re_match, etc., not by - setting no_sub. */ - bufp->no_sub = 0; - - /* Match anchors at newline. */ - bufp->newline_anchor = 1; - - ret = regex_compile (pattern, length, re_syntax_options, bufp); - - return re_error_msg[(int) ret]; -} - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them if this is an Emacs or POSIX compilation. */ - -#if !defined (emacs) && !defined (_POSIX_SOURCE) - -/* BSD has one and only one pattern buffer. */ -static struct re_pattern_buffer re_comp_buf; - -char * -re_comp (s) - const char *s; -{ - reg_errcode_t ret; - - if (!s) - { - if (!re_comp_buf.buffer) - return "No previous regular expression"; - return 0; - } - - if (!re_comp_buf.buffer) - { - re_comp_buf.buffer = (unsigned char *) malloc (200); - if (re_comp_buf.buffer == NULL) - return "Memory exhausted"; - re_comp_buf.allocated = 200; - - re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); - if (re_comp_buf.fastmap == NULL) - return "Memory exhausted"; - } - - /* Since `re_exec' always passes NULL for the `regs' argument, we - don't need to initialize the pattern buffer fields which affect it. */ - - /* Match anchors at newlines. */ - 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]; -} - - -int -re_exec (s) - const char *s; -{ - const int len = strlen (s); - return - 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); -} -#endif /* not emacs and not _POSIX_SOURCE */ - -/* POSIX.2 functions. Don't define these for Emacs. */ - -#ifndef emacs - -/* regcomp takes a regular expression as a string and compiles it. - - PREG is a regex_t *. We do not expect any fields to be initialized, - since POSIX says we shouldn't. Thus, we set - - `buffer' to the compiled pattern; - `used' to the length of the compiled pattern; - `syntax' to RE_SYNTAX_POSIX_EXTENDED if the - REG_EXTENDED bit in CFLAGS is set; otherwise, to - RE_SYNTAX_POSIX_BASIC; - `newline_anchor' to REG_NEWLINE being set in CFLAGS; - `fastmap' and `fastmap_accurate' to zero; - `re_nsub' to the number of subexpressions in PATTERN. - - PATTERN is the address of the pattern string. - - CFLAGS is a series of bits which affect compilation. - - If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we - use POSIX basic syntax. - - If REG_NEWLINE is set, then . and [^...] don't match newline. - Also, regexec will try a match beginning after every newline. - - If REG_ICASE is set, then we considers upper- and lowercase - versions of letters to be equivalent when matching. - - If REG_NOSUB is set, then when PREG is passed to regexec, that - routine will report only success or failure, and nothing about the - registers. - - It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for - the return codes and their meanings.) */ - -int -regcomp (preg, pattern, cflags) - regex_t *preg; - const char *pattern; - int cflags; -{ - reg_errcode_t ret; - unsigned syntax - = (cflags & REG_EXTENDED) ? - RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; - - /* regex_compile will allocate the space for the compiled pattern. */ - preg->buffer = 0; - preg->allocated = 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 - characters after newlines into the fastmap. This way, we just try - every character. */ - preg->fastmap = 0; - - if (cflags & REG_ICASE) - { - unsigned i; - - preg->translate = (char *) malloc (CHAR_SET_SIZE); - if (preg->translate == NULL) - return (int) REG_ESPACE; - - /* Map uppercase characters to corresponding lowercase ones. */ - for (i = 0; i < CHAR_SET_SIZE; i++) - preg->translate[i] = ISUPPER (i) ? tolower (i) : i; - } - else - preg->translate = NULL; - - /* If REG_NEWLINE is set, newlines are treated differently. */ - if (cflags & REG_NEWLINE) - { /* REG_NEWLINE implies neither . nor [^...] match newline. */ - syntax &= ~RE_DOT_NEWLINE; - syntax |= RE_HAT_LISTS_NOT_NEWLINE; - /* It also changes the matching behavior. */ - preg->newline_anchor = 1; - } - else - preg->newline_anchor = 0; - - preg->no_sub = !!(cflags & REG_NOSUB); - - /* POSIX says a null character in the pattern terminates it, so we - can use strlen here in compiling the pattern. */ - ret = regex_compile (pattern, strlen (pattern), syntax, preg); - - /* POSIX doesn't distinguish between an unmatched open-group and an - unmatched close-group: both are REG_EPAREN. */ - if (ret == REG_ERPAREN) ret = REG_EPAREN; - - return (int) ret; -} - - -/* regexec searches for a given pattern, specified by PREG, in the - string STRING. - - If NMATCH is zero or REG_NOSUB was set in the cflags argument to - `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at - least NMATCH elements, and we set them to the offsets of the - corresponding matched substrings. - - EFLAGS specifies `execution flags' which affect matching: if - REG_NOTBOL is set, then ^ does not match at the beginning of the - string; if REG_NOTEOL is set, then $ does not match at the end. - - We return 0 if we find a match and REG_NOMATCH if not. */ - -int -regexec (preg, string, nmatch, pmatch, eflags) - const regex_t *preg; - const char *string; - size_t nmatch; - regmatch_t pmatch[]; - int eflags; -{ - int ret; - struct re_registers regs; - regex_t private_preg; - int len = strlen (string); - boolean want_reg_info = !preg->no_sub && nmatch > 0; - - private_preg = *preg; - - private_preg.not_bol = !!(eflags & REG_NOTBOL); - private_preg.not_eol = !!(eflags & REG_NOTEOL); - - /* The user has told us exactly how many registers to return - information about, via `nmatch'. We have to pass that on to the - matching routines. */ - private_preg.regs_allocated = REGS_FIXED; - - if (want_reg_info) - { - regs.num_regs = nmatch; - regs.start = TALLOC (nmatch, regoff_t); - regs.end = TALLOC (nmatch, regoff_t); - if (regs.start == NULL || regs.end == NULL) - return (int) REG_NOMATCH; - } - - /* Perform the searching operation. */ - ret = re_search (&private_preg, string, len, - /* start: */ 0, /* range: */ len, - want_reg_info ? ®s : (struct re_registers *) 0); - - /* Copy the register information to the POSIX structure. */ - if (want_reg_info) - { - if (ret >= 0) - { - unsigned r; - - for (r = 0; r < nmatch; r++) - { - pmatch[r].rm_so = regs.start[r]; - pmatch[r].rm_eo = regs.end[r]; - } - } - - /* If we needed the temporary register info, free the space now. */ - free (regs.start); - free (regs.end); - } - - /* We want zero return to mean success, unlike `re_search'. */ - return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; -} - - -/* Returns a message corresponding to an error code, ERRCODE, returned - from either regcomp or regexec. We don't use PREG here. */ - -size_t -regerror (errcode, preg, errbuf, errbuf_size) - int errcode; - const regex_t *preg; - char *errbuf; - size_t errbuf_size; -{ - const char *msg; - size_t msg_size; - - if (errcode < 0 - || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[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_size = strlen (msg) + 1; /* Includes the null. */ - - if (errbuf_size != 0) - { - if (msg_size > errbuf_size) - { - strncpy (errbuf, msg, errbuf_size - 1); - errbuf[errbuf_size - 1] = 0; - } - else - strcpy (errbuf, msg); - } - - return msg_size; -} - - -/* Free dynamically allocated space used by PREG. */ - -void -regfree (preg) - regex_t *preg; -{ - if (preg->buffer != NULL) - free (preg->buffer); - preg->buffer = NULL; - - preg->allocated = 0; - preg->used = 0; - - if (preg->fastmap != NULL) - free (preg->fastmap); - preg->fastmap = NULL; - preg->fastmap_accurate = 0; - - if (preg->translate != NULL) - free (preg->translate); - preg->translate = NULL; -} - -#endif /* not emacs */ - -/* -Local variables: -make-backup-files: t -version-control: t -trim-versions-without-asking: nil -End: -*/ diff --git a/gnu/usr.bin/cvs/lib/regex.h b/gnu/usr.bin/cvs/lib/regex.h deleted file mode 100644 index 408dd210348f..000000000000 --- a/gnu/usr.bin/cvs/lib/regex.h +++ /dev/null @@ -1,490 +0,0 @@ -/* 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. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef __REGEXP_LIBRARY_H__ -#define __REGEXP_LIBRARY_H__ - -/* POSIX says that <sys/types.h> must be included (by the caller) before - <regex.h>. */ - -#ifdef VMS -/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it - should be there. */ -#include <stddef.h> -#endif - - -/* The following bits are used to determine the regexp syntax we - recognize. The set/not-set meanings are chosen so that Emacs syntax - remains the value 0. The bits are given in alphabetical order, and - the definitions shifted by one from the previous bit; thus, when we - add or remove a bit, only one other definition need change. */ -typedef unsigned reg_syntax_t; - -/* If this bit is not set, then \ inside a bracket expression is literal. - If set, then such a \ quotes the following character. */ -#define RE_BACKSLASH_ESCAPE_IN_LISTS (1) - -/* If this bit is not set, then + and ? are operators, and \+ and \? are - literals. - If set, then \+ and \? are operators and + and ? are literals. */ -#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) - -/* If this bit is set, then character classes are supported. They are: - [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], - [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. - If not set, then character classes are not supported. */ -#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) - -/* If this bit is set, then ^ and $ are always anchors (outside bracket - expressions, of course). - If this bit is not set, then it depends: - ^ is an anchor if it is at the beginning of a regular - expression or after an open-group or an alternation operator; - $ is an anchor if it is at the end of a regular expression, or - before a close-group or an alternation operator. - - This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because - POSIX draft 11.2 says that * etc. in leading positions is undefined. - We already implemented a previous draft which made those constructs - invalid, though, so we haven't changed the code back. */ -#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) - -/* If this bit is set, then special characters are always special - regardless of where they are in the pattern. - If this bit is not set, then special characters are special only in - some contexts; otherwise they are ordinary. Specifically, - * + ? and intervals are only special when not after the beginning, - open-group, or alternation operator. */ -#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) - -/* If this bit is set, then *, +, ?, and { cannot be first in an re or - immediately after an alternation or begin-group operator. */ -#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) - -/* If this bit is set, then . matches newline. - If not set, then it doesn't. */ -#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) - -/* If this bit is set, then . doesn't match NUL. - If not set, then it does. */ -#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) - -/* If this bit is set, nonmatching lists [^...] do not match newline. - If not set, they do. */ -#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) - -/* If this bit is set, either \{...\} or {...} defines an - interval, depending on RE_NO_BK_BRACES. - If not set, \{, \}, {, and } are literals. */ -#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) - -/* If this bit is set, +, ? and | aren't recognized as operators. - If not set, they are. */ -#define RE_LIMITED_OPS (RE_INTERVALS << 1) - -/* If this bit is set, newline is an alternation operator. - If not set, newline is literal. */ -#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) - -/* If this bit is set, then `{...}' defines an interval, and \{ and \} - are literals. - If not set, then `\{...\}' defines an interval. */ -#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) - -/* If this bit is set, (...) defines a group, and \( and \) are literals. - If not set, \(...\) defines a group, and ( and ) are literals. */ -#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) - -/* If this bit is set, then \<digit> matches <digit>. - If not set, then \<digit> is a back-reference. */ -#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) - -/* If this bit is set, then | is an alternation operator, and \| is literal. - If not set, then \| is an alternation operator, and | is literal. */ -#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) - -/* If this bit is set, then an ending range point collating higher - than the starting range point, as in [z-a], is invalid. - If not set, then when ending range point collates higher than the - starting range point, the range is ignored. */ -#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) - -/* If this bit is set, then an unmatched ) is ordinary. - If not set, then an unmatched ) is invalid. */ -#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) - -/* This global variable defines the particular regexp syntax to use (for - some interfaces). When a regexp is compiled, the syntax used is - stored in the pattern buffer, so changing this does not affect - already-compiled regexps. */ -extern reg_syntax_t re_syntax_options; - -/* Define combinations of the above bits for the standard possibilities. - (The [[[ comments delimit what gets put into the Texinfo file, so - don't delete them!) */ -/* [[[begin syntaxes]]] */ -#define RE_SYNTAX_EMACS 0 - -#define RE_SYNTAX_AWK \ - (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ - | RE_UNMATCHED_RIGHT_PAREN_ORD) - -#define RE_SYNTAX_POSIX_AWK \ - (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS) - -#define RE_SYNTAX_GREP \ - (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ - | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ - | RE_NEWLINE_ALT) - -#define RE_SYNTAX_EGREP \ - (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ - | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ - | RE_NO_BK_VBAR) - -#define RE_SYNTAX_POSIX_EGREP \ - (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) - -/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ -#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC - -#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC - -/* Syntax bits common to both basic and extended POSIX regex syntax. */ -#define _RE_SYNTAX_POSIX_COMMON \ - (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ - | RE_INTERVALS | RE_NO_EMPTY_RANGES) - -#define RE_SYNTAX_POSIX_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) - -/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes - RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this - isn't minimal, since other operators, such as \`, aren't disabled. */ -#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) - -#define RE_SYNTAX_POSIX_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ - | RE_UNMATCHED_RIGHT_PAREN_ORD) - -/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS - replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ -#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) -/* [[[end syntaxes]]] */ - -/* Maximum number of duplicates an interval can allow. Some systems - (erroneously) define this in other header files, but we want our - value, so remove any previous define. */ -#ifdef RE_DUP_MAX -#undef RE_DUP_MAX -#endif -#define RE_DUP_MAX ((1 << 15) - 1) - - -/* POSIX `cflags' bits (i.e., information for `regcomp'). */ - -/* If this bit is set, then use extended regular expression syntax. - If not set, then use basic regular expression syntax. */ -#define REG_EXTENDED 1 - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define REG_ICASE (REG_EXTENDED << 1) - -/* If this bit is set, then anchors do not match at newline - characters in the string. - If not set, then anchors do match at newlines. */ -#define REG_NEWLINE (REG_ICASE << 1) - -/* If this bit is set, then report only success or fail in regexec. - If not set, then returns differ between not matching and errors. */ -#define REG_NOSUB (REG_NEWLINE << 1) - - -/* POSIX `eflags' bits (i.e., information for regexec). */ - -/* If this bit is set, then the beginning-of-line operator doesn't match - the beginning of the string (presumably because it's not the - beginning of a line). - If not set, then the beginning-of-line operator does match the - beginning of the string. */ -#define REG_NOTBOL 1 - -/* Like REG_NOTBOL, except for the end-of-line. */ -#define REG_NOTEOL (1 << 1) - - -/* If any error codes are removed, changed, or added, update the - `re_error_msg' table in regex.c. */ -typedef enum -{ - REG_NOERROR = 0, /* Success. */ - REG_NOMATCH, /* Didn't find a match (for regexec). */ - - /* POSIX regcomp return error codes. (In the order listed in the - standard.) */ - REG_BADPAT, /* Invalid pattern. */ - REG_ECOLLATE, /* Not implemented. */ - REG_ECTYPE, /* Invalid character class name. */ - REG_EESCAPE, /* Trailing backslash. */ - REG_ESUBREG, /* Invalid back reference. */ - REG_EBRACK, /* Unmatched left bracket. */ - REG_EPAREN, /* Parenthesis imbalance. */ - REG_EBRACE, /* Unmatched \{. */ - REG_BADBR, /* Invalid contents of \{\}. */ - REG_ERANGE, /* Invalid range end. */ - REG_ESPACE, /* Ran out of memory. */ - REG_BADRPT, /* No preceding re for repetition op. */ - - /* Error codes we've added. */ - REG_EEND, /* Premature end. */ - REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ - REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ -} reg_errcode_t; - -/* This data structure represents a compiled pattern. Before calling - the pattern compiler, the fields `buffer', `allocated', `fastmap', - `translate', and `no_sub' can be set. After the pattern has been - compiled, the `re_nsub' field is available. All other fields are - private to the regex routines. */ - -struct re_pattern_buffer -{ -/* [[[begin pattern_buffer]]] */ - /* Space that holds the compiled pattern. It is declared as - `unsigned char *' because its elements are - sometimes used as array indexes. */ - unsigned char *buffer; - - /* Number of bytes to which `buffer' points. */ - unsigned long allocated; - - /* Number of bytes actually used in `buffer'. */ - unsigned long used; - - /* Syntax setting with which the pattern was compiled. */ - reg_syntax_t syntax; - - /* Pointer to a fastmap, if any, otherwise zero. re_search uses - the fastmap, if there is one, to skip over impossible - starting points for matches. */ - char *fastmap; - - /* Either a translate table to apply to all characters before - comparing them, or zero for no translation. The translation - is applied to a pattern when it is compiled and to a string - when it is matched. */ - char *translate; - - /* Number of subexpressions found by the compiler. */ - size_t re_nsub; - - /* Zero if this pattern cannot match the empty string, one else. - Well, in truth it's used only in `re_search_2', to see - whether or not we should use the fastmap, so we don't set - this absolutely perfectly; see `re_compile_fastmap' (the - `duplicate' case). */ - unsigned can_be_null : 1; - - /* If REGS_UNALLOCATED, allocate space in the `regs' structure - for `max (RE_NREGS, re_nsub + 1)' groups. - If REGS_REALLOCATE, reallocate space if necessary. - If REGS_FIXED, use what's there. */ -#define REGS_UNALLOCATED 0 -#define REGS_REALLOCATE 1 -#define REGS_FIXED 2 - unsigned regs_allocated : 2; - - /* Set to zero when `regex_compile' compiles a pattern; set to one - by `re_compile_fastmap' if it updates the fastmap. */ - unsigned fastmap_accurate : 1; - - /* If set, `re_match_2' does not return information about - subexpressions. */ - unsigned no_sub : 1; - - /* If set, a beginning-of-line anchor doesn't match at the - beginning of the string. */ - unsigned not_bol : 1; - - /* Similarly for an end-of-line anchor. */ - unsigned not_eol : 1; - - /* If true, an anchor at a newline matches. */ - unsigned newline_anchor : 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; - - -/* This is the structure we store register match data in. See - regex.texinfo for a full description of what registers match. */ -struct re_registers -{ - unsigned num_regs; - regoff_t *start; - regoff_t *end; -}; - - -/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, - `re_match_2' returns information about at least this many registers - the first time a `regs' structure is passed. */ -#ifndef RE_NREGS -#define RE_NREGS 30 -#endif - - -/* POSIX specification for registers. Aside from the different names than - `re_registers', POSIX uses an array of structures, instead of a - structure of arrays. */ -typedef struct -{ - regoff_t rm_so; /* Byte offset from string's start to substring's start. */ - regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ -} regmatch_t; - -/* Declarations for routines. */ - -/* To avoid duplicating every routine declaration -- once with a - prototype (if we are ANSI), and once without (if we aren't) -- we - use the following macro to declare argument types. This - unfortunately clutters up the declarations a bit, but I think it's - worth it. */ - -#if __STDC__ - -#define _RE_ARGS(args) args - -#else /* not __STDC__ */ - -#define _RE_ARGS(args) () - -#endif /* not __STDC__ */ - -/* Sets the current default syntax to SYNTAX, and return the old syntax. - You can also simply assign to the `re_syntax_options' variable. */ -extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); - -/* Compile the regular expression PATTERN, with length LENGTH - and syntax given by the global `re_syntax_options', into the buffer - BUFFER. Return NULL if successful, and an error string if not. */ -extern const char *re_compile_pattern - _RE_ARGS ((const char *pattern, int length, - struct re_pattern_buffer *buffer)); - - -/* Compile a fastmap for the compiled pattern in BUFFER; used to - accelerate searches. Return 0 if successful and -2 if was an - internal error. */ -extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); - - -/* Search in the string STRING (with length LENGTH) for the pattern - compiled into BUFFER. Start searching at position START, for RANGE - characters. Return the starting position of the match, -1 for no - match, or -2 for an internal error. Also return register - information in REGS (if REGS and BUFFER->no_sub are nonzero). */ -extern int re_search - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, int range, struct re_registers *regs)); - - -/* Like `re_search', but search in the concatenation of STRING1 and - STRING2. Also, stop searching at index START + STOP. */ -extern int re_search_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, int range, struct re_registers *regs, int stop)); - - -/* Like `re_search', but return how many characters in STRING the regexp - in BUFFER matched, starting at position START. */ -extern int re_match - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, struct re_registers *regs)); - - -/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ -extern int re_match_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, struct re_registers *regs, int stop)); - - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using BUFFER and REGS will use this memory - for recording register information. STARTS and ENDS must be - allocated with malloc, and must each be at least `NUM_REGS * sizeof - (regoff_t)' bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ -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. */ -extern char *re_comp _RE_ARGS ((const char *)); -extern int re_exec _RE_ARGS ((const char *)); - -/* POSIX compatibility. */ -extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags)); -extern int regexec - _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch, - regmatch_t pmatch[], int eflags)); -extern size_t regerror - _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf, - size_t errbuf_size)); -extern void regfree _RE_ARGS ((regex_t *preg)); - -#endif /* not __REGEXP_LIBRARY_H__ */ - -/* -Local variables: -make-backup-files: t -version-control: t -trim-versions-without-asking: nil -End: -*/ diff --git a/gnu/usr.bin/cvs/lib/rename.c b/gnu/usr.bin/cvs/lib/rename.c deleted file mode 100644 index 6c43cf6f698c..000000000000 --- a/gnu/usr.bin/cvs/lib/rename.c +++ /dev/null @@ -1,72 +0,0 @@ -/* rename.c -- BSD compatible directory function for System V - Copyright (C) 1988, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> -#ifndef STDC_HEADERS -extern int errno; -#endif - -/* Rename file FROM to file TO. - Return 0 if successful, -1 if not. */ - -int -rename (from, to) - char *from; - char *to; -{ - struct stat from_stats; - int pid, status; - - if (stat (from, &from_stats) == 0) - { - if (unlink (to) && errno != ENOENT) - return -1; - if ((from_stats.st_mode & S_IFMT) == S_IFDIR) - { - /* Need a setuid root process to link and unlink directories. */ - pid = fork (); - switch (pid) - { - case -1: /* Error. */ - error (1, errno, "cannot fork"); - - case 0: /* Child. */ - execl (MVDIR, "mvdir", from, to, (char *) 0); - error (255, errno, "cannot run `%s'", MVDIR); - - default: /* Parent. */ - while (wait (&status) != pid) - /* Do nothing. */ ; - - errno = 0; /* mvdir printed the system error message. */ - return status != 0 ? -1 : 0; - } - } - else - { - if (link (from, to) == 0 && (unlink (from) == 0 || errno == ENOENT)) - return 0; - } - } - return -1; -} diff --git a/gnu/usr.bin/cvs/lib/strdup.c b/gnu/usr.bin/cvs/lib/strdup.c deleted file mode 100644 index 46fc8a0d6dbc..000000000000 --- a/gnu/usr.bin/cvs/lib/strdup.c +++ /dev/null @@ -1,43 +0,0 @@ -/* strdup.c -- return a newly allocated copy of a string - Copyright (C) 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef STDC_HEADERS -#include <string.h> -#include <stdlib.h> -#else -char *malloc (); -char *strcpy (); -#endif - -/* Return a newly allocated copy of STR, - or 0 if out of memory. */ - -char * -strdup (str) - char *str; -{ - char *newstr; - - newstr = (char *) malloc (strlen (str) + 1); - if (newstr) - strcpy (newstr, str); - return newstr; -} diff --git a/gnu/usr.bin/cvs/lib/strerror.c b/gnu/usr.bin/cvs/lib/strerror.c deleted file mode 100644 index b0bec1317a91..000000000000 --- a/gnu/usr.bin/cvs/lib/strerror.c +++ /dev/null @@ -1,813 +0,0 @@ -/* Extended support for using errno values. - Copyright (C) 1992 Free Software Foundation, Inc. - Written by Fred Fish. fnf@cygnus.com - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#include "config.h" - -#ifndef NEED_sys_errlist -/* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least) - might declare sys_errlist in a way that the compiler might consider - incompatible with our later declaration, perhaps by using const - attributes. So we hide the declaration in errno.h (if any) using a - macro. */ -#define sys_errlist sys_errlist__ -#endif - -#include <stdio.h> -#include <errno.h> - -#ifndef NEED_sys_errlist -#undef sys_errlist -#endif - -/* Routines imported from standard C runtime libraries. */ - -#ifdef __STDC__ -#include <stddef.h> -extern void *malloc (size_t size); /* 4.10.3.3 */ -extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ -#else /* !__STDC__ */ -extern char *malloc (); /* Standard memory allocater */ -extern char *memset (); -#endif /* __STDC__ */ - -#ifndef MAX -# define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -/* Translation table for errno values. See intro(2) in most UNIX systems - Programmers Reference Manuals. - - Note that this table is generally only accessed when it is used at runtime - to initialize errno name and message tables that are indexed by errno - value. - - Not all of these errnos will exist on all systems. This table is the only - thing that should have to be updated as new error numbers are introduced. - It's sort of ugly, but at least its portable. */ - -struct error_info -{ - int value; /* The numeric value from <errno.h> */ - char *name; /* The equivalent symbolic value */ -#ifdef NEED_sys_errlist - char *msg; /* Short message about this value */ -#endif -}; - -#ifdef NEED_sys_errlist -# define ENTRY(value, name, msg) {value, name, msg} -#else -# define ENTRY(value, name, msg) {value, name} -#endif - -static const struct error_info error_table[] = -{ -#if defined (EPERM) - ENTRY(EPERM, "EPERM", "Not owner"), -#endif -#if defined (ENOENT) - ENTRY(ENOENT, "ENOENT", "No such file or directory"), -#endif -#if defined (ESRCH) - ENTRY(ESRCH, "ESRCH", "No such process"), -#endif -#if defined (EINTR) - ENTRY(EINTR, "EINTR", "Interrupted system call"), -#endif -#if defined (EIO) - ENTRY(EIO, "EIO", "I/O error"), -#endif -#if defined (ENXIO) - ENTRY(ENXIO, "ENXIO", "No such device or address"), -#endif -#if defined (E2BIG) - ENTRY(E2BIG, "E2BIG", "Arg list too long"), -#endif -#if defined (ENOEXEC) - ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"), -#endif -#if defined (EBADF) - ENTRY(EBADF, "EBADF", "Bad file number"), -#endif -#if defined (ECHILD) - ENTRY(ECHILD, "ECHILD", "No child processes"), -#endif -#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */ - ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"), -#endif -#if defined (EAGAIN) - ENTRY(EAGAIN, "EAGAIN", "No more processes"), -#endif -#if defined (ENOMEM) - ENTRY(ENOMEM, "ENOMEM", "Not enough space"), -#endif -#if defined (EACCES) - ENTRY(EACCES, "EACCES", "Permission denied"), -#endif -#if defined (EFAULT) - ENTRY(EFAULT, "EFAULT", "Bad address"), -#endif -#if defined (ENOTBLK) - ENTRY(ENOTBLK, "ENOTBLK", "Block device required"), -#endif -#if defined (EBUSY) - ENTRY(EBUSY, "EBUSY", "Device busy"), -#endif -#if defined (EEXIST) - ENTRY(EEXIST, "EEXIST", "File exists"), -#endif -#if defined (EXDEV) - ENTRY(EXDEV, "EXDEV", "Cross-device link"), -#endif -#if defined (ENODEV) - ENTRY(ENODEV, "ENODEV", "No such device"), -#endif -#if defined (ENOTDIR) - ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"), -#endif -#if defined (EISDIR) - ENTRY(EISDIR, "EISDIR", "Is a directory"), -#endif -#if defined (EINVAL) - ENTRY(EINVAL, "EINVAL", "Invalid argument"), -#endif -#if defined (ENFILE) - ENTRY(ENFILE, "ENFILE", "File table overflow"), -#endif -#if defined (EMFILE) - ENTRY(EMFILE, "EMFILE", "Too many open files"), -#endif -#if defined (ENOTTY) - ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"), -#endif -#if defined (ETXTBSY) - ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"), -#endif -#if defined (EFBIG) - ENTRY(EFBIG, "EFBIG", "File too large"), -#endif -#if defined (ENOSPC) - ENTRY(ENOSPC, "ENOSPC", "No space left on device"), -#endif -#if defined (ESPIPE) - ENTRY(ESPIPE, "ESPIPE", "Illegal seek"), -#endif -#if defined (EROFS) - ENTRY(EROFS, "EROFS", "Read-only file system"), -#endif -#if defined (EMLINK) - ENTRY(EMLINK, "EMLINK", "Too many links"), -#endif -#if defined (EPIPE) - ENTRY(EPIPE, "EPIPE", "Broken pipe"), -#endif -#if defined (EDOM) - ENTRY(EDOM, "EDOM", "Math argument out of domain of func"), -#endif -#if defined (ERANGE) - ENTRY(ERANGE, "ERANGE", "Math result not representable"), -#endif -#if defined (ENOMSG) - ENTRY(ENOMSG, "ENOMSG", "No message of desired type"), -#endif -#if defined (EIDRM) - ENTRY(EIDRM, "EIDRM", "Identifier removed"), -#endif -#if defined (ECHRNG) - ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"), -#endif -#if defined (EL2NSYNC) - ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"), -#endif -#if defined (EL3HLT) - ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"), -#endif -#if defined (EL3RST) - ENTRY(EL3RST, "EL3RST", "Level 3 reset"), -#endif -#if defined (ELNRNG) - ENTRY(ELNRNG, "ELNRNG", "Link number out of range"), -#endif -#if defined (EUNATCH) - ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"), -#endif -#if defined (ENOCSI) - ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"), -#endif -#if defined (EL2HLT) - ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"), -#endif -#if defined (EDEADLK) - ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"), -#endif -#if defined (ENOLCK) - ENTRY(ENOLCK, "ENOLCK", "No record locks available"), -#endif -#if defined (EBADE) - ENTRY(EBADE, "EBADE", "Invalid exchange"), -#endif -#if defined (EBADR) - ENTRY(EBADR, "EBADR", "Invalid request descriptor"), -#endif -#if defined (EXFULL) - ENTRY(EXFULL, "EXFULL", "Exchange full"), -#endif -#if defined (ENOANO) - ENTRY(ENOANO, "ENOANO", "No anode"), -#endif -#if defined (EBADRQC) - ENTRY(EBADRQC, "EBADRQC", "Invalid request code"), -#endif -#if defined (EBADSLT) - ENTRY(EBADSLT, "EBADSLT", "Invalid slot"), -#endif -#if defined (EDEADLOCK) - ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"), -#endif -#if defined (EBFONT) - ENTRY(EBFONT, "EBFONT", "Bad font file format"), -#endif -#if defined (ENOSTR) - ENTRY(ENOSTR, "ENOSTR", "Device not a stream"), -#endif -#if defined (ENODATA) - ENTRY(ENODATA, "ENODATA", "No data available"), -#endif -#if defined (ETIME) - ENTRY(ETIME, "ETIME", "Timer expired"), -#endif -#if defined (ENOSR) - ENTRY(ENOSR, "ENOSR", "Out of streams resources"), -#endif -#if defined (ENONET) - ENTRY(ENONET, "ENONET", "Machine is not on the network"), -#endif -#if defined (ENOPKG) - ENTRY(ENOPKG, "ENOPKG", "Package not installed"), -#endif -#if defined (EREMOTE) - ENTRY(EREMOTE, "EREMOTE", "Object is remote"), -#endif -#if defined (ENOLINK) - ENTRY(ENOLINK, "ENOLINK", "Link has been severed"), -#endif -#if defined (EADV) - ENTRY(EADV, "EADV", "Advertise error"), -#endif -#if defined (ESRMNT) - ENTRY(ESRMNT, "ESRMNT", "Srmount error"), -#endif -#if defined (ECOMM) - ENTRY(ECOMM, "ECOMM", "Communication error on send"), -#endif -#if defined (EPROTO) - ENTRY(EPROTO, "EPROTO", "Protocol error"), -#endif -#if defined (EMULTIHOP) - ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"), -#endif -#if defined (EDOTDOT) - ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"), -#endif -#if defined (EBADMSG) - ENTRY(EBADMSG, "EBADMSG", "Not a data message"), -#endif -#if defined (ENAMETOOLONG) - ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"), -#endif -#if defined (EOVERFLOW) - ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"), -#endif -#if defined (ENOTUNIQ) - ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"), -#endif -#if defined (EBADFD) - ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"), -#endif -#if defined (EREMCHG) - ENTRY(EREMCHG, "EREMCHG", "Remote address changed"), -#endif -#if defined (ELIBACC) - ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"), -#endif -#if defined (ELIBBAD) - ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"), -#endif -#if defined (ELIBSCN) - ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"), -#endif -#if defined (ELIBMAX) - ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"), -#endif -#if defined (ELIBEXEC) - ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"), -#endif -#if defined (EILSEQ) - ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"), -#endif -#if defined (ENOSYS) - ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"), -#endif -#if defined (ELOOP) - ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"), -#endif -#if defined (ERESTART) - ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"), -#endif -#if defined (ESTRPIPE) - ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"), -#endif -#if defined (ENOTEMPTY) - ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"), -#endif -#if defined (EUSERS) - ENTRY(EUSERS, "EUSERS", "Too many users"), -#endif -#if defined (ENOTSOCK) - ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"), -#endif -#if defined (EDESTADDRREQ) - ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"), -#endif -#if defined (EMSGSIZE) - ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"), -#endif -#if defined (EPROTOTYPE) - ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"), -#endif -#if defined (ENOPROTOOPT) - ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"), -#endif -#if defined (EPROTONOSUPPORT) - ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"), -#endif -#if defined (ESOCKTNOSUPPORT) - ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"), -#endif -#if defined (EOPNOTSUPP) - ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"), -#endif -#if defined (EPFNOSUPPORT) - ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"), -#endif -#if defined (EAFNOSUPPORT) - ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"), -#endif -#if defined (EADDRINUSE) - ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"), -#endif -#if defined (EADDRNOTAVAIL) - ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"), -#endif -#if defined (ENETDOWN) - ENTRY(ENETDOWN, "ENETDOWN", "Network is down"), -#endif -#if defined (ENETUNREACH) - ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"), -#endif -#if defined (ENETRESET) - ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"), -#endif -#if defined (ECONNABORTED) - ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"), -#endif -#if defined (ECONNRESET) - ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"), -#endif -#if defined (ENOBUFS) - ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"), -#endif -#if defined (EISCONN) - ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"), -#endif -#if defined (ENOTCONN) - ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"), -#endif -#if defined (ESHUTDOWN) - ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"), -#endif -#if defined (ETOOMANYREFS) - ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"), -#endif -#if defined (ETIMEDOUT) - ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"), -#endif -#if defined (ECONNREFUSED) - ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"), -#endif -#if defined (EHOSTDOWN) - ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"), -#endif -#if defined (EHOSTUNREACH) - ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"), -#endif -#if defined (EALREADY) - ENTRY(EALREADY, "EALREADY", "Operation already in progress"), -#endif -#if defined (EINPROGRESS) - ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"), -#endif -#if defined (ESTALE) - ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"), -#endif -#if defined (EUCLEAN) - ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"), -#endif -#if defined (ENOTNAM) - ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"), -#endif -#if defined (ENAVAIL) - ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"), -#endif -#if defined (EISNAM) - ENTRY(EISNAM, "EISNAM", "Is a named type file"), -#endif -#if defined (EREMOTEIO) - ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"), -#endif - ENTRY(0, NULL, NULL) -}; - -/* Translation table allocated and initialized at runtime. Indexed by the - errno value to find the equivalent symbolic value. */ - -static char **error_names; -static int num_error_names = 0; - -/* Translation table allocated and initialized at runtime, if it does not - already exist in the host environment. Indexed by the errno value to find - the descriptive string. - - We don't export it for use in other modules because even though it has the - same name, it differs from other implementations in that it is dynamically - initialized rather than statically initialized. */ - -#ifdef NEED_sys_errlist - -static int sys_nerr; -static char **sys_errlist; - -#else - -extern int sys_nerr; -extern char *sys_errlist[]; - -#endif - - -/* - -NAME - - init_error_tables -- initialize the name and message tables - -SYNOPSIS - - static void init_error_tables (); - -DESCRIPTION - - Using the error_table, which is initialized at compile time, generate - the error_names and the sys_errlist (if needed) tables, which are - indexed at runtime by a specific errno value. - -BUGS - - The initialization of the tables may fail under low memory conditions, - in which case we don't do anything particularly useful, but we don't - bomb either. Who knows, it might succeed at a later point if we free - some memory in the meantime. In any case, the other routines know - how to deal with lack of a table after trying to initialize it. This - may or may not be considered to be a bug, that we don't specifically - warn about this particular failure mode. - -*/ - -static void -init_error_tables () -{ - const struct error_info *eip; - int nbytes; - - /* If we haven't already scanned the error_table once to find the maximum - errno value, then go find it now. */ - - if (num_error_names == 0) - { - for (eip = error_table; eip -> name != NULL; eip++) - { - if (eip -> value >= num_error_names) - { - num_error_names = eip -> value + 1; - } - } - } - - /* Now attempt to allocate the error_names table, zero it out, and then - initialize it from the statically initialized error_table. */ - - if (error_names == NULL) - { - nbytes = num_error_names * sizeof (char *); - if ((error_names = (char **) malloc (nbytes)) != NULL) - { - memset (error_names, 0, nbytes); - for (eip = error_table; eip -> name != NULL; eip++) - { - error_names[eip -> value] = eip -> name; - } - } - } - -#ifdef NEED_sys_errlist - - /* Now attempt to allocate the sys_errlist table, zero it out, and then - initialize it from the statically initialized error_table. */ - - if (sys_errlist == NULL) - { - nbytes = num_error_names * sizeof (char *); - if ((sys_errlist = (char **) malloc (nbytes)) != NULL) - { - memset (sys_errlist, 0, nbytes); - sys_nerr = num_error_names; - for (eip = error_table; eip -> name != NULL; eip++) - { - sys_errlist[eip -> value] = eip -> msg; - } - } - } - -#endif - -} - -/* - -NAME - - errno_max -- return the max errno value - -SYNOPSIS - - int errno_max (); - -DESCRIPTION - - Returns the maximum errno value for which a corresponding symbolic - name or message is available. Note that in the case where - we use the sys_errlist supplied by the system, it is possible for - there to be more symbolic names than messages, or vice versa. - In fact, the manual page for perror(3C) explicitly warns that one - should check the size of the table (sys_nerr) before indexing it, - since new error codes may be added to the system before they are - added to the table. Thus sys_nerr might be smaller than value - implied by the largest errno value defined in <errno.h>. - - We return the maximum value that can be used to obtain a meaningful - symbolic name or message. - -*/ - -int -errno_max () -{ - int maxsize; - - if (error_names == NULL) - { - init_error_tables (); - } - maxsize = MAX (sys_nerr, num_error_names); - return (maxsize - 1); -} - -/* - -NAME - - strerror -- map an error number to an error message string - -SYNOPSIS - - char *strerror (int errnoval) - -DESCRIPTION - - Maps an errno number to an error message string, the contents of - which are implementation defined. On systems which have the external - variables sys_nerr and sys_errlist, these strings will be the same - as the ones used by perror(). - - If the supplied error number is within the valid range of indices - for the sys_errlist, but no message is available for the particular - error number, then returns the string "Error NUM", where NUM is the - error number. - - If the supplied error number is not a valid index into sys_errlist, - returns NULL. - - The returned string is only guaranteed to be valid only until the - next call to strerror. - -*/ - -char * -strerror (errnoval) - int errnoval; -{ - char *msg; - static char buf[32]; - -#ifdef NEED_sys_errlist - - if (error_names == NULL) - { - init_error_tables (); - } - -#endif - - if ((errnoval < 0) || (errnoval >= sys_nerr)) - { - /* Out of range, just return NULL */ - msg = NULL; - } - else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL)) - { - /* In range, but no sys_errlist or no entry at this index. */ - sprintf (buf, "Error %d", errnoval); - msg = buf; - } - else - { - /* In range, and a valid message. Just return the message. */ - msg = sys_errlist[errnoval]; - } - - return (msg); -} - - - -/* - -NAME - - strerrno -- map an error number to a symbolic name string - -SYNOPSIS - - char *strerrno (int errnoval) - -DESCRIPTION - - Given an error number returned from a system call (typically - returned in errno), returns a pointer to a string containing the - symbolic name of that error number, as found in <errno.h>. - - If the supplied error number is within the valid range of indices - for symbolic names, but no name is available for the particular - error number, then returns the string "Error NUM", where NUM is - the error number. - - If the supplied error number is not within the range of valid - indices, then returns NULL. - -BUGS - - The contents of the location pointed to are only guaranteed to be - valid until the next call to strerrno. - -*/ - -char * -strerrno (errnoval) - int errnoval; -{ - char *name; - static char buf[32]; - - if (error_names == NULL) - { - init_error_tables (); - } - - if ((errnoval < 0) || (errnoval >= num_error_names)) - { - /* Out of range, just return NULL */ - name = NULL; - } - else if ((error_names == NULL) || (error_names[errnoval] == NULL)) - { - /* In range, but no error_names or no entry at this index. */ - sprintf (buf, "Error %d", errnoval); - name = buf; - } - else - { - /* In range, and a valid name. Just return the name. */ - name = error_names[errnoval]; - } - - return (name); -} - -/* - -NAME - - strtoerrno -- map a symbolic errno name to a numeric value - -SYNOPSIS - - int strtoerrno (char *name) - -DESCRIPTION - - Given the symbolic name of a error number, map it to an errno value. - If no translation is found, returns 0. - -*/ - -int -strtoerrno (name) - char *name; -{ - int errnoval = 0; - - if (name != NULL) - { - if (error_names == NULL) - { - init_error_tables (); - } - for (errnoval = 0; errnoval < num_error_names; errnoval++) - { - if ((error_names[errnoval] != NULL) && - (strcmp (name, error_names[errnoval]) == 0)) - { - break; - } - } - if (errnoval == num_error_names) - { - errnoval = 0; - } - } - return (errnoval); -} - - -/* A simple little main that does nothing but print all the errno translations - if MAIN is defined and this file is compiled and linked. */ - -#ifdef MAIN - -main () -{ - int errn; - int errnmax; - char *name; - char *msg; - char *strerrno (); - char *strerror (); - - errnmax = errno_max (); - printf ("%d entries in names table.\n", num_error_names); - printf ("%d entries in messages table.\n", sys_nerr); - printf ("%d is max useful index.\n", errnmax); - - /* Keep printing values until we get to the end of *both* tables, not - *either* table. Note that knowing the maximum useful index does *not* - relieve us of the responsibility of testing the return pointer for - NULL. */ - - for (errn = 0; errn <= errnmax; errn++) - { - name = strerrno (errn); - name = (name == NULL) ? "<NULL>" : name; - msg = strerror (errn); - msg = (msg == NULL) ? "<NULL>" : msg; - printf ("%-4d%-18s%s\n", errn, name, msg); - } -} - -#endif diff --git a/gnu/usr.bin/cvs/lib/y.tab.h b/gnu/usr.bin/cvs/lib/y.tab.h deleted file mode 100644 index 4a541d2c97f7..000000000000 --- a/gnu/usr.bin/cvs/lib/y.tab.h +++ /dev/null @@ -1,18 +0,0 @@ -#define tAGO 257 -#define tDAY 258 -#define tDAYZONE 259 -#define tID 260 -#define tMERIDIAN 261 -#define tMINUTE_UNIT 262 -#define tMONTH 263 -#define tMONTH_UNIT 264 -#define tSEC_UNIT 265 -#define tSNUMBER 266 -#define tUNUMBER 267 -#define tZONE 268 -#define tDST 269 -typedef union { - time_t Number; - enum _MERIDIAN Meridian; -} YYSTYPE; -extern YYSTYPE yylval; diff --git a/gnu/usr.bin/cvs/mkmodules/Makefile b/gnu/usr.bin/cvs/mkmodules/Makefile deleted file mode 100644 index 9f66fdefc97f..000000000000 --- a/gnu/usr.bin/cvs/mkmodules/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PROG = mkmodules -SRCS = mkmodules.c - -CFLAGS += -I${.CURDIR}/../cvs -I${.CURDIR}/../lib -LDADD= -L${.CURDIR}/../lib/obj -lcvs - -.include <bsd.prog.mk> -.include "../../Makefile.inc" diff --git a/gnu/usr.bin/cvs/mkmodules/xxx b/gnu/usr.bin/cvs/mkmodules/xxx deleted file mode 100644 index f0dd87dee7e7..000000000000 --- a/gnu/usr.bin/cvs/mkmodules/xxx +++ /dev/null @@ -1,5320 +0,0 @@ -# 1 "/usr/src/gnu/cvs/mkmodules/mkmodules.c" - - - - - - - - - - - - - -# 1 "/usr/include/sys/syslimits.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 14 "/usr/src/gnu/cvs/mkmodules/mkmodules.c" 2 - -# 1 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 1 - - -# 1 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 1 - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/types.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -typedef unsigned char u_char; -typedef unsigned short u_short; -typedef unsigned int u_int; -typedef unsigned long u_long; -typedef unsigned short ushort; - -typedef char * caddr_t; -typedef long daddr_t; -typedef short dev_t; -typedef u_long ino_t; -typedef long off_t; -typedef u_short nlink_t; -typedef long swblk_t; -typedef long segsz_t; -typedef u_short uid_t; -typedef u_short gid_t; -typedef short pid_t; -typedef u_short mode_t; -typedef u_long fixpt_t; - - -typedef struct _uquad { u_long val[2]; } u_quad; -typedef struct _quad { long val[2]; } quad; -typedef long * qaddr_t; - - - - - - -# 1 "/usr/include/machine/ansi.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 69 "/usr/include/sys/types.h" 2 - - -# 1 "/usr/include/machine/types.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct _physadr { - int r[1]; -} *physadr; - -typedef struct label_t { - int val[6]; -} label_t; - -typedef u_long vm_offset_t; -typedef u_long vm_size_t; - - -# 71 "/usr/include/sys/types.h" 2 - - - - -typedef unsigned long clock_t; - - - - -typedef unsigned int size_t; - - - - -typedef long time_t; - - - - - - - - - - - - - - - - -typedef long fd_mask; - - - - - - -typedef struct fd_set { - fd_mask fds_bits[(((256 )+(( (sizeof(fd_mask) * 8 ) )-1))/( (sizeof(fd_mask) * 8 ) )) ]; -} fd_set; - - - - - - -# 132 "/usr/include/sys/types.h" - - - - -# 20 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 2 - -# 1 "/usr/include/sys/stat.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -struct stat -{ - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - off_t st_size; - time_t st_atime; - long st_spare1; - time_t st_mtime; - long st_spare2; - time_t st_ctime; - long st_spare3; - long st_blksize; - long st_blocks; - u_long st_flags; - u_long st_gen; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/cdefs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 76 "/usr/include/sys/cdefs.h" - - - -# 114 "/usr/include/sys/stat.h" 2 - - - -mode_t umask (mode_t) ; -int chmod (const char *, mode_t) ; -int fstat (int, struct stat *) ; -int mkdir (const char *, mode_t) ; -int mkfifo (const char *, mode_t) ; -int stat (const char *, struct stat *) ; - -int fchmod (int, mode_t) ; -int lstat (const char *, struct stat *) ; - - - -# 21 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -off_t lseek (); - - - - - -# 1 "/usr/include/time.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/machine/ansi.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 57 "/usr/include/machine/ansi.h" - -# 39 "/usr/include/time.h" 2 - - - - - - - - - - - - - - - - - - - - - -struct tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - long tm_gmtoff; - char *tm_zone; -}; - -# 1 "/usr/include/sys/cdefs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 78 "/usr/include/sys/cdefs.h" - -# 74 "/usr/include/time.h" 2 - - - -char *asctime (const struct tm *) ; -clock_t clock (void) ; -char *ctime (const time_t *) ; -double difftime (time_t, time_t) ; -struct tm *gmtime (const time_t *) ; -struct tm *localtime (const time_t *) ; -time_t mktime (struct tm *) ; -size_t strftime (char *, size_t, const char *, const struct tm *) ; -time_t time (time_t *) ; - - -void tzset (void) ; - - - -char *timezone (int, int) ; -void tzsetwall (void) ; - - - - -# 72 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 2 - - - -# 86 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" - -# 1 "/usr/include/sys/timeb.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -struct timeb { - time_t time; - unsigned short millitm; - short timezone; - short dstflag; -}; -# 87 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 2 - - - - - - - - - - -# 1 "/usr/include/sys/param.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/types.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 135 "/usr/include/sys/types.h" - -# 46 "/usr/include/sys/param.h" 2 - - - - - - - - - - -# 1 "/usr/include/sys/syslimits.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 56 "/usr/include/sys/param.h" 2 - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/signal.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/machine/trap.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 42 "/usr/include/sys/signal.h" 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/cdefs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 78 "/usr/include/sys/cdefs.h" - -# 90 "/usr/include/sys/signal.h" 2 - - - -typedef void (*sig_t) (int) ; - - -typedef void (*__sighandler_t) (int) ; -typedef unsigned int sigset_t; - - -int sigaddset (sigset_t *, int) ; -int sigdelset (sigset_t *, int) ; -int sigemptyset (sigset_t *) ; -int sigfillset (sigset_t *) ; -int sigismember (const sigset_t *, int) ; - - - - - - - - - - - -struct sigaction { - __sighandler_t sa_handler; - sigset_t sa_mask; - int sa_flags; -}; - - - - - - - - - - - - - - - - - - -struct sigvec { - void (*sv_handler)(); - int sv_mask; - int sv_flags; -}; - - - - - - - -struct sigaltstack { - char *ss_base; - int ss_len; - int ss_onstack; -}; - - - - -struct sigstack { - char *ss_sp; - int ss_onstack; -}; - - - - - - - - -struct sigcontext { - int sc_onstack; - int sc_mask; - int sc_sp; - int sc_fp; - int sc_ap; - int sc_pc; - int sc_ps; -}; - - - - - - - - - - - - - - -# 1 "/usr/include/sys/types.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 135 "/usr/include/sys/types.h" - -# 195 "/usr/include/sys/signal.h" 2 - - - - -__sighandler_t signal (int, __sighandler_t) ; -int raise (int) ; - -int kill (pid_t, int) ; -int sigaction (int, const struct sigaction *, struct sigaction *) ; -int sigpending (sigset_t *) ; -int sigprocmask (int, const sigset_t *, sigset_t *) ; -int sigsuspend (const sigset_t *) ; - - -int killpg (pid_t, int) ; -void psignal (unsigned, const char *) ; -int sigblock (int) ; -int siginterrupt (int, int) ; -int sigpause (int) ; -int sigreturn (struct sigcontext *) ; -int sigsetmask (int) ; -int sigstack (const struct sigstack *, struct sigstack *) ; -int sigvec (int, struct sigvec *, struct sigvec *) ; - - - - - -# 79 "/usr/include/sys/param.h" 2 - - - -# 1 "/usr/include/machine/param.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 82 "/usr/include/sys/param.h" 2 - -# 1 "/usr/include/machine/endian.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/cdefs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 78 "/usr/include/sys/cdefs.h" - -# 55 "/usr/include/machine/endian.h" 2 - - - - - - - - - -# 77 "/usr/include/machine/endian.h" - - - - - - - - - - - - - - - - - - -# 106 "/usr/include/machine/endian.h" - - - - - - - - - - - - -# 83 "/usr/include/sys/param.h" 2 - -# 1 "/usr/include/machine/limits.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 84 "/usr/include/sys/param.h" 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 97 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 2 - - - - - - - - - - - - - - - - - - - -struct utimbuf -{ - long actime; - long modtime; -}; - -int utime (); - - -# 145 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" - -# 1 "/usr/include/strings.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/string.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/machine/ansi.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 57 "/usr/include/machine/ansi.h" - -# 38 "/usr/include/string.h" 2 - - - - - - - - - - - -# 1 "/usr/include/sys/cdefs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 78 "/usr/include/sys/cdefs.h" - -# 49 "/usr/include/string.h" 2 - - - -void *memchr (const void *, int, size_t) ; -int memcmp (const void *, const void *, size_t) ; -void *memcpy (void *, const void *, size_t) ; -void *memmove (void *, const void *, size_t) ; -void *memset (void *, int, size_t) ; -char *strcat (char *, const char *) ; -char *strchr (const char *, int) ; -int strcmp (const char *, const char *) ; -int strcoll (const char *, const char *) ; -char *strcpy (char *, const char *) ; -size_t strcspn (const char *, const char *) ; -char *strerror (int) ; -size_t strlen (const char *) ; -char *strncat (char *, const char *, size_t) ; -int strncmp (const char *, const char *, size_t) ; -char *strncpy (char *, const char *, size_t) ; -char *strpbrk (const char *, const char *) ; -char *strrchr (const char *, int) ; -size_t strspn (const char *, const char *) ; -char *strstr (const char *, const char *) ; -char *strtok (char *, const char *) ; -size_t strxfrm (char *, const char *, size_t) ; - - - -int bcmp (const void *, const void *, size_t) ; -void bcopy (const void *, void *, size_t) ; -void bzero (void *, size_t) ; -int ffs (int) ; -char *index (const char *, int) ; -void *memccpy (void *, const void *, int, size_t) ; -char *rindex (const char *, int) ; -int strcasecmp (const char *, const char *) ; -char *strdup (const char *) ; -void strmode (int, char *) ; -int strncasecmp (const char *, const char *, size_t) ; -char *strsep (char **, const char *) ; -void swab (const void *, void *, size_t) ; - - - - -# 36 "/usr/include/strings.h" 2 - -# 146 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 2 - - - -# 1 "/usr/include/errno.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern int errno; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 149 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 2 - - - - -char *getenv (); -char *malloc (); -char *realloc (); -char *calloc (); -extern int errno; - - - - - - -# 173 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" - - - - - - -# 1 "/usr/include/sys/file.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/fcntl.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/types.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 135 "/usr/include/sys/types.h" - -# 46 "/usr/include/sys/fcntl.h" 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 99 "/usr/include/sys/fcntl.h" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -struct flock { - short l_type; - short l_whence; - off_t l_start; - off_t l_len; - pid_t l_pid; -}; - - - - - - - - - - - - -# 1 "/usr/include/sys/cdefs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 78 "/usr/include/sys/cdefs.h" - -# 169 "/usr/include/sys/fcntl.h" 2 - - - -int open (const char *, int, ...) ; -int creat (const char *, mode_t) ; -int fcntl (int, int, ...) ; - -int flock (int, int) ; - - - - - -# 36 "/usr/include/sys/file.h" 2 - -# 1 "/usr/include/sys/unistd.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 37 "/usr/include/sys/file.h" 2 - - -# 73 "/usr/include/sys/file.h" - -# 179 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 2 - -char *getwd (); - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/dir.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/dirent.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -struct dirent { - u_long d_fileno; - u_short d_reclen; - u_short d_namlen; - - - - - char d_name[255 + 1]; - -}; - - - - - - - - - - - -typedef struct _dirdesc { - int dd_fd; - long dd_loc; - long dd_size; - char *dd_buf; - int dd_len; - long dd_seek; -} DIR; - - - - - - - - - - - -# 1 "/usr/include/sys/cdefs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 78 "/usr/include/sys/cdefs.h" - -# 88 "/usr/include/dirent.h" 2 - - - -DIR *opendir (const char *) ; -struct dirent *readdir (DIR *) ; -void rewinddir (DIR *) ; -int closedir (DIR *) ; - -long telldir (const DIR *) ; -void seekdir (DIR *, long) ; -int scandir (const char *, struct dirent ***, - int (*)(struct dirent *), int (*)(const void *, const void *)) ; -int alphasort (const void *, const void *) ; -int getdirentries (int, char *, int, long *) ; - - - - - - -# 44 "/usr/include/sys/dir.h" 2 - - - - - - - - - - - - - - - - - - -# 208 "/usr/src/gnu/cvs/mkmodules/../lib/system.h" 2 - - - - - - - - - - - - - - - - -# 3 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/include/stdio.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/cdefs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 78 "/usr/include/sys/cdefs.h" - -# 42 "/usr/include/stdio.h" 2 - - -# 1 "/usr/include/machine/ansi.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 57 "/usr/include/machine/ansi.h" - -# 44 "/usr/include/stdio.h" 2 - - - - - - - - - - -typedef long fpos_t; - - - - - - - - - - -struct __sbuf { - unsigned char *_base; - int _size; -}; - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct __sFILE { - unsigned char *_p; - int _r; - int _w; - short _flags; - short _file; - struct __sbuf _bf; - int _lbfsize; - - - void *_cookie; - int (*_close) (void *) ; - int (*_read) (void *, char *, int) ; - fpos_t (*_seek) (void *, fpos_t, int) ; - int (*_write) (void *, const char *, int) ; - - - struct __sbuf _ub; - unsigned char *_up; - int _ur; - - - unsigned char _ubuf[3]; - unsigned char _nbuf[1]; - - - struct __sbuf _lb; - - - int _blksize; - int _offset; -} FILE; - - -extern FILE __sF[]; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void clearerr (FILE *) ; -int fclose (FILE *) ; -int feof (FILE *) ; -int ferror (FILE *) ; -int fflush (FILE *) ; -int fgetc (FILE *) ; -int fgetpos (FILE *, fpos_t *) ; -char *fgets (char *, size_t, FILE *) ; -FILE *fopen (const char *, const char *) ; -int fprintf (FILE *, const char *, ...) ; -int fputc (int, FILE *) ; -int fputs (const char *, FILE *) ; -int fread (void *, size_t, size_t, FILE *) ; -FILE *freopen (const char *, const char *, FILE *) ; -int fscanf (FILE *, const char *, ...) ; -int fseek (FILE *, long, int) ; -int fsetpos (FILE *, const fpos_t *) ; -long ftell (const FILE *) ; -int fwrite (const void *, size_t, size_t, FILE *) ; -int getc (FILE *) ; -int getchar (void) ; -char *gets (char *) ; - -extern int sys_nerr; -extern char *sys_errlist[]; - -void perror (const char *) ; -int printf (const char *, ...) ; -int putc (int, FILE *) ; -int putchar (int) ; -int puts (const char *) ; -int remove (const char *) ; -int rename (const char *, const char *) ; -void rewind (FILE *) ; -int scanf (const char *, ...) ; -void setbuf (FILE *, char *) ; -int setvbuf (FILE *, char *, int, size_t) ; -int sprintf (char *, const char *, ...) ; -int sscanf (char *, const char *, ...) ; -FILE *tmpfile (void) ; -char *tmpnam (char *) ; -int ungetc (int, FILE *) ; -int vfprintf (FILE *, const char *, char * ) ; -int vprintf (const char *, char * ) ; -int vsprintf (char *, const char *, char * ) ; - - - - - - - - - - -char *ctermid (char *) ; -FILE *fdopen (int, const char *) ; -int fileno (FILE *) ; - - - - - - - - -char *fgetline (FILE *, size_t *) ; -int fpurge (FILE *) ; -int getw (FILE *) ; -int pclose (FILE *) ; -FILE *popen (const char *, const char *) ; -int putw (int, FILE *) ; -void setbuffer (FILE *, char *, int) ; -int setlinebuf (FILE *) ; -char *tempnam (const char *, const char *) ; -int snprintf (char *, size_t, const char *, ...) ; -int vsnprintf (char *, size_t, const char *, char * ) ; -int vscanf (const char *, char * ) ; -int vsscanf (const char *, const char *, char * ) ; - - - - - - - - - - - - - -FILE *funopen (const void *, - int (*)(void *, char *, int), - int (*)(void *, const char *, int), - fpos_t (*)(void *, fpos_t, int), - int (*)(void *)) ; - - - - - - - - - -int __srget (FILE *) ; -int __svfscanf (FILE *, const char *, char * ) ; -int __swbuf (int, FILE *) ; - - - - - - - - -static inline int __sputc(int _c, FILE *_p) { - if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) - return (*_p->_p++ = _c); - else - return (__swbuf(_c, _p)); -} -# 331 "/usr/include/stdio.h" - - - - - - - - - - - - - - - - - - - - - - - -# 4 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/include/ctype.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern char _ctype_[]; - - - - - - - - - - - - - - - - - - -# 5 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/include/pwd.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 1 "/usr/include/sys/types.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 135 "/usr/include/sys/types.h" - -# 39 "/usr/include/pwd.h" 2 - - - - - - - - - - - - - - - - - - - - -struct passwd { - char *pw_name; - char *pw_passwd; - int pw_uid; - int pw_gid; - time_t pw_change; - char *pw_class; - char *pw_gecos; - char *pw_dir; - char *pw_shell; - time_t pw_expire; -}; - -# 1 "/usr/include/sys/cdefs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 78 "/usr/include/sys/cdefs.h" - -# 72 "/usr/include/pwd.h" 2 - - - -struct passwd *getpwuid (uid_t) ; -struct passwd *getpwnam (const char *) ; - -struct passwd *getpwent (void) ; -int setpassent (int) ; -int setpwent (void) ; -void endpwent (void) ; - - - - -# 6 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/include/signal.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 222 "/usr/include/signal.h" - -# 7 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/src/gnu/cvs/mkmodules/../cvs/hash.h" 1 - - - - - - - - - - - - - - - - - - -enum ntype -{ - UNKNOWN, HEADER, ENTRIES, FILES, LIST, RCSNODE, - RCSVERS, DIRS, UPDATE, LOCK, NDBMNODE -}; -typedef enum ntype Ntype; - -struct node -{ - Ntype type; - struct node *next; - struct node *prev; - struct node *hashnext; - struct node *hashprev; - char *key; - char *data; - void (*delproc) (); -}; -typedef struct node Node; - -struct list -{ - Node *list; - Node *hasharray[151 ]; - struct list *next; -}; -typedef struct list List; - -struct entnode -{ - char *version; - char *timestamp; - char *options; - char *tag; - char *date; -}; -typedef struct entnode Entnode; - - -List *getlist (void); -Node *findnode (List * list, char *key); -Node *getnode (void); -int addnode (List * list, Node * p); -int walklist (List * list, int (*proc) ()); -void dellist (List ** listp); -void delnode (Node * p); -void freenode (Node * p); -void sortlist (List * list, int (*comp) ()); -# 77 "/usr/src/gnu/cvs/mkmodules/../cvs/hash.h" - -# 8 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/src/gnu/cvs/mkmodules/../cvs/rcs.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -struct rcsnode -{ - int refcount; - int flags; - char *path; - char *head; - char *branch; - List *symbols; - List *versions; - List *dates; -}; -typedef struct rcsnode RCSNode; - -struct rcsversnode -{ - char *version; - char *date; - char *next; - List *branches; -}; -typedef struct rcsversnode RCSVers; - - - - - - - - - - - - - - -List *RCS_parsefiles (List * files, char *xrepos); -RCSNode *RCS_parse (char *file, char *repos); -RCSNode *RCS_parsercsfile (char *rcsfile); -char *RCS_check_kflag (char *arg); -char *RCS_getdate (RCSNode * rcs, char *date, int force_tag_match); -char *RCS_gettag (RCSNode * rcs, char *tag, int force_tag_match); -char *RCS_getversion (RCSNode * rcs, char *tag, char *date, - int force_tag_match); -char *RCS_magicrev (RCSNode *rcs, char *rev); -int RCS_isbranch (char *file, char *rev, List *srcfiles); -char *RCS_whatbranch (char *file, char *tag, List *srcfiles); -char *RCS_head (RCSNode * rcs); -int RCS_datecmp (char *date1, char *date2); -time_t RCS_getrevtime (RCSNode * rcs, char *rev, char *date, int fudge); -void RCS_check_tag (char *tag); -void freercsnode (RCSNode ** rnodep); -# 102 "/usr/src/gnu/cvs/mkmodules/../cvs/rcs.h" - -# 9 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/src/gnu/cvs/mkmodules/../lib/regex.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -typedef unsigned reg_syntax_t; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern reg_syntax_t obscure_syntax; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -typedef enum -{ - REG_NOERROR = 0, - REG_NOMATCH, - - - - REG_BADPAT, - REG_ECOLLATE, - REG_ECTYPE, - REG_EESCAPE, - REG_ESUBREG, - REG_EBRACK, - REG_EPAREN, - REG_EBRACE, - REG_BADBR, - REG_ERANGE, - REG_ESPACE, - REG_BADRPT, - - - REG_EEND, - REG_ESIZE, - REG_ERPAREN -} reg_errcode_t; - - - - - - - - - - -struct re_pattern_buffer -{ - - - - - unsigned char *buffer; - - - unsigned long allocated; - - - unsigned long used; - - - reg_syntax_t syntax; - - - - - char *fastmap; - - - - - - char *translate; - - - size_t re_nsub; - - - - - - - unsigned can_be_null : 2; - - - - unsigned fastmap_accurate : 1; - - - - unsigned no_sub : 1; - - - - unsigned not_bol : 1; - - - unsigned not_eol : 1; - - - unsigned newline_anchor : 1; - - - - - unsigned caller_allocated_regs : 1; - -}; - -typedef struct re_pattern_buffer regex_t; - - - - - - - - - - - -typedef int regoff_t; - - - - -struct re_registers -{ - unsigned num_regs; - regoff_t *start; - regoff_t *end; -}; - - - - - - - - - - - - -typedef struct -{ - regoff_t rm_so; - regoff_t rm_eo; -} regmatch_t; - - - - - - - - - - -extern reg_syntax_t re_set_syntax (reg_syntax_t syntax); - - - - -extern const char *re_compile_pattern (const char *pattern, int length, - struct re_pattern_buffer *buffer); - - - - - -extern int re_compile_fastmap (struct re_pattern_buffer *buffer); - - - - - - - -extern int re_search (struct re_pattern_buffer *buffer, - const char *string, int length, - int start, int range, - struct re_registers *regs); - - - - -extern int re_search_2 (struct re_pattern_buffer *buffer, - const char *string1, int length1, - const char *string2, int length2, - int start, int range, - struct re_registers *regs, - int stop); - - - - -extern int re_match (const struct re_pattern_buffer *buffer, - const char *string, int length, - int start, struct re_registers *regs); - - - -extern int re_match_2 (const struct re_pattern_buffer *buffer, - const char *string1, int length1, - const char *string2, int length2, - int start, - struct re_registers *regs, - int stop); - - - - - - - - - - - -extern int regcomp (regex_t *preg, const char *pattern, int cflags); -extern int regexec (const regex_t *preg, const char *string, size_t nmatch, - regmatch_t pmatch[], int eflags); -extern size_t regerror (int errcode, const regex_t *preg, char *errbuf, - size_t errbuf_size); -extern void regfree (regex_t *preg); - -# 468 "/usr/src/gnu/cvs/mkmodules/../lib/regex.h" - - - - - - - - - - - - -# 10 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/src/gnu/cvs/mkmodules/../lib/fnmatch.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern int fnmatch (const char *pattern, const char *string, int flags); - - - - - -# 11 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/src/gnu/cvs/mkmodules/../lib/getopt.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - -extern char *optarg; - - - - - - - - - - - - - -extern int optind; - - - - -extern int opterr; - - - - - - - - - - - - - - - - - - - - - -struct option -{ - char *name; - int has_arg; - int *flag; - int val; -}; - - -extern const struct option *_getopt_long_options; - - - - - - - -extern int _getopt_long_only; - - - - - -extern int option_index; - - -int gnu_getopt (int argc, char **argv, const char *shortopts); -int gnu_getopt_long (int argc, char **argv, const char *shortopts, - const struct option *longopts, int *longind); -int gnu_getopt_long_only (int argc, char **argv, const char *shortopts, - const struct option *longopts, int *longind); - - - - - -# 12 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/src/gnu/cvs/mkmodules/../lib/wait.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 13 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - -# 1 "/usr/src/gnu/cvs/mkmodules/../cvs/config.h" 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern void exit (); - - - -extern char *getwd (); - - - - - - - - - - - - - - - -# 14 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - - -# 1 "/usr/src/gnu/cvs/mkmodules/../cvs/myndbm.h" 1 - - - - - - -typedef struct -{ - List *dbm_list; - Node *dbm_next; -} DBM; - -typedef struct -{ - char *dptr; - int dsize; -} datum; - - - - - - - - - - - - - -DBM *mydbm_open (char *file, int flags, int mode); -void mydbm_close (DBM * db); -datum mydbm_fetch (DBM * db, datum key); -datum mydbm_firstkey (DBM * db); -datum mydbm_nextkey (DBM * db); - - - - - - - - - -# 16 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -enum mtype -{ - CHECKOUT, TAG, PATCH -}; - - - - - - -enum classify_type -{ - T_UNKNOWN = 1, - T_CONFLICT, - T_NEEDS_MERGE, - T_MODIFIED, - T_CHECKOUT, - T_ADDED, - T_REMOVED, - T_REMOVE_ENTRY, - T_UPTODATE, - T_TITLE -}; -typedef enum classify_type Ctype; - - - - - - - - -struct vers_ts -{ - char *vn_user; - - - - - - char *vn_rcs; - - char *ts_user; - char *ts_rcs; - char *options; - - char *tag; - char *date; - Entnode *entdata; - RCSNode *srcfile; -}; -typedef struct vers_ts Vers_TS; - - - - - -struct stickydirtag -{ - int aflag; - char *tag; - char *date; - char *options; -}; - - - - - - - - - - - - - - - - -enum direnter_type -{ - R_PROCESS = 1, - R_SKIP_FILES, - R_SKIP_DIRS, - R_SKIP_ALL -}; -typedef enum direnter_type Dtype; - -extern char *program_name, *command_name; -extern char *Rcsbin, *Editor, *CVSroot; -extern char *CurDir; -extern int really_quiet, quiet; -extern int use_editor; -extern int cvswrite; - -extern int trace; -extern int noexec; -extern int logoff; - - - -int Reader_Lock (char *xrepository); -DBM *open_module (void); -FILE *Fopen (char *name, char *mode); -FILE *open_file (char *name, char *mode); -List *Find_Dirs (char *repository, int which); -List *ParseEntries (int aflag); -char *Make_Date (char *rawdate); -char *Name_Repository (char *dir, char *update_dir); -char *Short_Repository (char *repository); -char *getcaller (void); -char *time_stamp (char *file); -char *xmalloc (int bytes); -char *xrealloc (char *ptr, int bytes); -char *xstrdup (char *str); -int No_Difference (char *file, Vers_TS * vers, List * entries); -int Parse_Info (char *infofile, char *repository, int (*callproc) (), int all); -int Reader_Lock (char *xrepository); -int SIG_register (int sig, void (*fn) ()); -int Writer_Lock (List * list); -int gethostname (char *name, int namelen); -int ign_name (char *name); -int isdir (char *file); -int isfile (char *file); -int islink (char *file); -int isreadable (char *file); -int iswritable (char *file); -int link_file (char *from, char *to); -int numdots (char *s); -int run_exec (char *stin, char *stout, char *sterr, int flags); -int unlink_file (char *f); -int update (int argc, char *argv[]); -int xcmp (char *file1, char *file2); -int yesno (void); -time_t get_date (char *date, struct timeb *now); -void Create_Admin (char *dir, char *repository, char *tag, char *date); -void Lock_Cleanup (void); -void ParseTag (char **tagp, char **datep); -void Scratch_Entry (List * list, char *fname); -void WriteTag (char *dir, char *tag, char *date); -void cat_module (int status); -void check_entries (char *dir); -void close_module (DBM * db); -void copy_file (char *from, char *to); -void error (int status, int errnum, char *message,...); -void fperror (FILE * fp, int status, int errnum, char *message,...); -void free_names (int *pargc, char *argv[]); -void freevers_ts (Vers_TS ** versp); -void ign_add (char *ign, int hold); -void ign_add_file (char *file, int hold); -void ign_setup (void); -void line2argv (int *pargc, char *argv[], char *line); -void make_directories (char *name); -void make_directory (char *name); -void rename_file (char *from, char *to); -void run_arg (char *s); -void run_args (char *fmt,...); -void run_print (FILE * fp); -void run_setup (char *fmt,...); -void strip_path (char *path); -void update_delproc (Node * p); -void usage (char **cpp); -void xchmod (char *fname, int writable); -int Checkin (int type, char *file, char *repository, char *rcs, char *rev, - char *tag, char *message, List * entries); -Ctype Classify_File (char *file, char *tag, char *date, char *options, - int force_tag_match, int aflag, char *repository, - List *entries, List *srcfiles, Vers_TS **versp); -List *Find_Names (char *repository, int which, int aflag, - List ** optentries); -void Register (List * list, char *fname, char *vn, char *ts, - char *options, char *tag, char *date); -void Update_Logfile (char *repository, char *xmessage, char *xrevision, - FILE * xlogfp, List * xchanges); -Vers_TS *Version_TS (char *repository, char *options, char *tag, - char *date, char *user, int force_tag_match, - int set_time, List * entries, List * xfiles); -void do_editor (char *dir, char *message, char *repository, - List * changes); -int do_module (DBM * db, char *mname, enum mtype m_type, char *msg, - int (*callback_proc) (), char *where, int shorten, - int local_specified, int run_module_prog, char *extra_arg); -int do_recursion (int (*xfileproc) (), int (*xfilesdoneproc) (), - Dtype (*xdirentproc) (), int (*xdirleaveproc) (), - Dtype xflags, int xwhich, int xaflag, int xreadlock, - int xdosrcs); -int do_update (int argc, char *argv[], char *xoptions, char *xtag, - char *xdate, int xforce, int local, int xbuild, - int xaflag, int xprune, int xpipeout, int which, - char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir); -void history_write (int type, char *update_dir, char *revs, char *name, - char *repository); -int start_recursion (int (*fileproc) (), int (*filesdoneproc) (), - Dtype (*direntproc) (), int (*dirleaveproc) (), - int argc, char *argv[], int local, int which, - int aflag, int readlock, char *update_preload, - int dosrcs); -void SIG_beginCrSect (); -void SIG_endCrSect (); -# 438 "/usr/src/gnu/cvs/mkmodules/../cvs/cvs.h" - -# 15 "/usr/src/gnu/cvs/mkmodules/mkmodules.c" 2 - - - - - - -PATH_MAX +2 - - -static char rcsid[] = "@(#)mkmodules.c 1.39 92/03/31"; - - - - - - -char *program_name, *command_name; - -char *Rcsbin = "" ; -int noexec = 0; -int trace = 0; - - -static int checkout_file (char *file, char *temp); -static void make_tempfile (char *temp); -static void mkmodules_usage (void); -static void rename_rcsfile (char *temp, char *real); - - - - - - -# 60 "/usr/src/gnu/cvs/mkmodules/mkmodules.c" - - -int -main (argc, argv) - int argc; - char *argv[]; -{ - extern char *getenv (); - char temp[PATH_MAX +2 ]; - char *cp; - - DBM *db; - - - - - - if ((program_name = rindex (argv[0], '/')) == 0 ) - program_name = argv[0]; - else - program_name++; - - if (argc != 2) - mkmodules_usage (); - - if ((cp = getenv ("RCSBIN" )) != 0 ) - Rcsbin = cp; - - - - - - if (Rcsbin[0] != '\0') - { - int len = strlen (Rcsbin); - char *rcsbin; - - if (Rcsbin[len - 1] != '/') - { - rcsbin = Rcsbin; - Rcsbin = xmalloc (len + 2); - (void) strcpy (Rcsbin, rcsbin); - (void) strcat (Rcsbin, "/"); - } - } - - if (chdir (argv[1]) < 0) - error (1, errno, "cannot chdir to %s", argv[1]); - - - - - make_tempfile (temp); - switch (checkout_file ("modules" , temp)) - { - - case 0: - - - if ((db = mydbm_open (temp, 0x0000 , 0666)) != 0 ) - mydbm_close (db); - - - - - rename_rcsfile (temp, "modules" ); - break; - - case -1: - (void) unlink_file (temp); - exit (1); - - - default: - error (0, 0, - "'cvs checkout' is less functional without a %s file", - "modules" ); - break; - } - - (void) unlink_file (temp); - - - - - - make_tempfile (temp); - if (checkout_file ("loginfo" , temp) == 0) - rename_rcsfile (temp, "loginfo" ); - else - error (0, 0, - "no logging of 'cvs commit' messages is done without a %s file", - "loginfo" ); - (void) unlink_file (temp); - - - - - - make_tempfile (temp); - if (checkout_file ("rcsinfo" , temp) == 0) - rename_rcsfile (temp, "rcsinfo" ); - else - error (0, 0, - "a %s file can be used to configure 'cvs commit' templates", - "rcsinfo" ); - (void) unlink_file (temp); - - - - - - make_tempfile (temp); - if (checkout_file ("editinfo" , temp) == 0) - rename_rcsfile (temp, "editinfo" ); - else - error (0, 0, - "a %s file can be used to validate log messages", - "editinfo" ); - (void) unlink_file (temp); - - - - - - make_tempfile (temp); - if (checkout_file ("commitinfo" , temp) == 0) - rename_rcsfile (temp, "commitinfo" ); - else - error (0, 0, - "a %s file can be used to configure 'cvs commit' checking", - "commitinfo" ); - (void) unlink_file (temp); - return (0); -} - - - - -static void -make_tempfile (temp) - char *temp; -{ - static int seed = 0; - int fd; - - if (seed == 0) - seed = getpid (); - while (1) - { - (void) sprintf (temp, "%s%d", ".#" , seed++); - if ((fd = open (temp, 0x0200 | 0x0800 | 0x0002 , 0666)) != -1) - break; - if (errno != 17 ) - error (1, errno, "cannot create temporary file %s", temp); - } - if (close(fd) < 0) - error(1, errno, "cannot close temporary file %s", temp); -} - -static int -checkout_file (file, temp) - char *file; - char *temp; -{ - char rcs[PATH_MAX +2 ]; - int retcode = 0; - - (void) sprintf (rcs, "%s%s", file, ",v" ); - if (!isfile (rcs)) - return (1); - run_setup ("%s%s -q -p", Rcsbin, "co" ); - run_arg (rcs); - if ((retcode = run_exec ( (char *)0 , temp, (char *)0 , 0x0000 )) != 0) - { - error (0, retcode == -1 ? errno : 0, "failed to check out %s file", file); - } - return (retcode); -} - -# 369 "/usr/src/gnu/cvs/mkmodules/mkmodules.c" - - -static void -rename_rcsfile (temp, real) - char *temp; - char *real; -{ - char bak[50]; - - if (chmod (temp, 0444) < 0) - error (0, errno, "warning: cannot chmod %s", temp); - (void) sprintf (bak, "%s%s", ".#" , real); - (void) unlink_file (bak); - (void) rename (real, bak); - (void) rename (temp, real); -} - - - - -void -Lock_Cleanup () -{ -} - -static void -mkmodules_usage () -{ - (void) fprintf ((&__sF[2]) , "Usage: %s modules-directory\n", program_name); - exit (1); -} |