1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-02-02 17:08:56 +00:00

Clean out some files which are no longer part of CVS...

This commit is contained in:
Peter Wemm 1995-12-11 00:28:08 +00:00
parent 21eb9ed3e1
commit 177f95a913
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=12755
27 changed files with 0 additions and 5869 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)))

View File

@ -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)))))

View File

@ -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))))

View File

@ -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))))

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -1,161 +0,0 @@
#! /bin/sh
:
#
#ident "@(#)cvs:$Name: $:$Id: cvsinit.sh,v 1.7 1995/11/14 23:44:18 woods Exp $"
# Copyright (c) 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.4 kit.
# This script should be run for each repository you create to help you
# setup your site for CVS. You may also run it to update existing
# repositories if you install a new version of CVS.
# this line is edited by Makefile when creating cvsinit.inst
CVSLIB="/usr/share/examples/cvs"
CVS_VERSION="cvs-1.6.3"
# All purpose usage message, also suffices for --help and --version.
if test $# -gt 0; then
echo "cvsinit version $CVS_VERSION"
echo "usage: $0"
echo "(set CVSROOT to the repository that you want to initialize)"
exit 0
fi
# Make sure that the CVSROOT variable is set
if [ "x$CVSROOT" = x ]; then
echo "The CVSROOT environment variable is not set."
echo ""
echo "You should choose a location for your source repository"
echo "that can be shared by many developers. It also helps to"
echo "place the source repository on a file system that has"
echo "plenty of free space."
echo ""
echo "Please enter the full path for your CVSROOT source repository:"
read CVSROOT junk
unset junk
remind_cvsroot=yes
else
remind_cvsroot=no
fi
# Now, create the $CVSROOT if it is not already there
if [ ! -d $CVSROOT ]; then
echo "Creating $CVSROOT..."
path=
for comp in `echo $CVSROOT | sed -e 's,/, ,g'`; do
path=$path/$comp
if [ ! -d $path ]; then
mkdir $path
fi
done
else
true
fi
# Next, check for $CVSROOT/CVSROOT
if [ ! -d $CVSROOT/CVSROOT ]; then
if [ -d $CVSROOT/CVSROOT.adm ]; then
echo "You have the old $CVSROOT/CVSROOT.adm directory."
echo "I will rename it to $CVSROOT/CVSROOT for you..."
mv $CVSROOT/CVSROOT.adm $CVSROOT/CVSROOT
else
echo "Creating the $CVSROOT/CVSROOT directory..."
mkdir $CVSROOT/CVSROOT
fi
else
true
fi
if [ ! -d $CVSROOT/CVSROOT ]; then
echo "Unable to create $CVSROOT/CVSROOT."
echo "I give up."
exit 1
fi
# Create the special control files and templates within $CVSROOT/CVSROOT
EXAMPLES="checkoutlist commitinfo cvswrappers editinfo loginfo modules
rcsinfo rcstemplate taginfo wrap unwrap"
NEWSAMPLE=false
for info in $EXAMPLES; do
if [ -f $CVSROOT/CVSROOT/${info},v ]; then
if [ ! -f $CVSROOT/CVSROOT/$info ]; then
echo "Checking out $CVSROOT/CVSROOT/$info"
echo " from $CVSROOT/CVSROOT/${info},v..."
(cd $CVSROOT/CVSROOT; co -q $info)
fi
else
NEWSAMPLE=true
if [ -f $CVSROOT/CVSROOT/$info ]; then
echo "Checking in $CVSROOT/CVSROOT/${info},v"
echo " from $CVSROOT/CVSROOT/$info..."
else
echo "Creating a sample $CVSROOT/CVSROOT/$info file..."
case $info in
modules)
sed -n -e '/END_REQUIRED_CONTENT/q' \
-e p $CVSLIB/examples/modules > $CVSROOT/CVSROOT/modules
;;
rcstemplate)
cp $CVSLIB/examples/$info $CVSROOT/CVSROOT/$info
;;
wrap|unwrap)
cp $CVSLIB/examples/$info $CVSROOT/CVSROOT/$info
chmod +x $CVSROOT/CVSROOT/$info
;;
*)
# comment out everything in all the other examples....
sed -e 's/^\([^#]\)/#\1/' $CVSLIB/examples/$info > $CVSROOT/CVSROOT/$info
;;
esac
fi
(cd $CVSROOT/CVSROOT; ci -q -u -t/dev/null -m"initial checkin of $info" $info)
fi
done
if $NEWSAMPLE ; then
echo "NOTE: You may wish to check out the CVSROOT module and edit any new"
echo "configuration files to match your local requirements."
echo ""
fi
# check to see if there are any references to the old CVSROOT.adm directory
if grep CVSROOT.adm $CVSROOT/CVSROOT/modules >/dev/null 2>&1; then
echo "Warning: your $CVSROOT/CVSROOT/modules file still"
echo " contains references to the old CVSROOT.adm directory"
echo " You should really change these to the new CVSROOT directory"
echo ""
fi
# These files are generated from the contrib files.
# FIXME: Is it really wise to overwrite possible local changes like this?
# Normal folks will keep these up to date by modifying the source in
# their CVS module and re-installing CVS, but is everyone OK with that?
#
#
CONTRIBS="log commit_prep log_accum cln_hist"
#
for contrib in $CONTRIBS; do
echo "Copying the new version of '${contrib}'"
echo " to $CVSROOT/CVSROOT for you..."
cp $CVSLIB/contrib/$contrib $CVSROOT/CVSROOT/$contrib
done
# XXX - also add a stub for the cvsignore file
# Turn on history logging by default
if [ ! -f $CVSROOT/CVSROOT/history ]; then
echo "Enabling CVS history logging..."
touch $CVSROOT/CVSROOT/history
chmod g+w $CVSROOT/CVSROOT/history
echo "(Remove $CVSROOT/CVSROOT/history to disable.)"
fi
# finish up by running mkmodules
echo "All done! Running 'mkmodules' as my final step..."
mkmodules $CVSROOT/CVSROOT
exit 0

View File

@ -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));
}
}

View File

@ -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 */
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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