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:
parent
21eb9ed3e1
commit
177f95a913
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=12755
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
@ -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
|
@ -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)))
|
@ -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)))))
|
@ -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))))
|
@ -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))))
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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)
|
@ -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
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
}
|
@ -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;
|
||||
}
|
@ -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 */
|
@ -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
|
@ -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));
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user