summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgildea <empty>1994-09-09 19:30:54 +0000
committergildea <empty>1994-09-09 19:30:54 +0000
commit9261e57ffedb3dbd9e46963b27194ae53899498b (patch)
tree6b27d118853fd43b1017c5778d564d542ed496a0
parent63dbb5bf727a5b3865948f8f9f99afaf41fdefd1 (diff)
patch 2.0.12u9R6
-rw-r--r--xc/util/patch/ChangeLog290
-rw-r--r--xc/util/patch/MANIFEST27
-rw-r--r--xc/util/patch/README98
-rw-r--r--xc/util/patch/backupfile.c338
-rw-r--r--xc/util/patch/backupfile.h37
-rw-r--r--xc/util/patch/config.H33
-rw-r--r--xc/util/patch/config.h.SH146
-rw-r--r--xc/util/patch/malloc.c467
-rw-r--r--xc/util/patch/util.c450
9 files changed, 1886 insertions, 0 deletions
diff --git a/xc/util/patch/ChangeLog b/xc/util/patch/ChangeLog
new file mode 100644
index 000000000..305293787
--- /dev/null
+++ b/xc/util/patch/ChangeLog
@@ -0,0 +1,290 @@
+Mon May 31 00:49:40 1993 Paul Eggert (eggert@twinsun.com)
+
+ * patchlevel.h: PATCHLEVEL 12u9.
+
+ * inp.c (plan_a): Don't lock the checked-out file if `patch -o'
+ redirected the output elsewhere.
+ * common.h (CHECKOUT_LOCKED, GET_LOCKED): New macros. GET and
+ CHECKOUT now just checkout unlocked copies.
+
+ * Makefile (dist): Use gzip, not compress.
+
+Fri May 28 08:44:50 1993 Paul Eggert (eggert@twinsun.com)
+
+ * backupfile.c (basename): Define even if NODIR isn't defined.
+ * patch.c (main): Ask just once to apply a reversed patch.
+
+Tue Sep 15 00:36:15 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u8.
+
+Mon Sep 14 22:01:23 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Makefile.SH: Add uninstall target. Simplify install target.
+
+ * util.c (fatal, pfatal): Add some asterisks to make fatal
+ messages stand out more.
+
+Tue Aug 25 22:13:36 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * patch.c (main, get_some_switches), common.h, inp.c (plan_a,
+ plan_b), pch.c (there_is_another_patch): Add -t option,
+ similar to -f.
+
+Mon Jul 27 11:27:07 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * inp.c (plan_a, util.c (fetchname): Use a macro to simplify code.
+ * common.h: Define SCCSDIFF and RCSDIFF.
+ * inp.c (plan_a): Use them to make sure it's safe to check out
+ the default RCS or SCCS version.
+ From Paul Eggert.
+
+Wed Jul 22 14:37:08 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * patch.man: Use the standard comment syntax -- '\" -- instead
+ of '''.
+
+Tue Jul 21 15:26:01 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Configure: Add /etc /usr/lib /lib to pth.
+
+Mon Jul 20 14:10:32 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * util.h: Declare basename.
+ * inp.c (plan_a), util.c (fetchname): Use it to isolate the
+ leading path when testing for RCS and SCCS files.
+
+Sat Jul 11 18:03:26 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Configure: Use the user's PATH and build pth from it.
+
+Fri Jul 10 16:03:23 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Configure: Change cc -S to cc -c and tr '[ - ]' '[\012-\012]'
+ to tr ' ' '\012' for AIX 3.2.
+ From chip@tct.com (Chip Salzenberg).
+
+ * util.c (makedirs): Only make the directories that don't exist.
+ From chip@tct.com (Chip Salzenberg).
+
+Wed Jul 8 01:21:15 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * util.c (fatal, pfatal): Print "patch: " before message.
+ * pch.c, inp.c, patch.c, util.c: Remove "patch: " from the
+ callers that had it.
+
+ * util.c (pfatal): New function.
+ * util.h: Declare it and pfatal[1-4] macros.
+ * various files: Use it instead of fatal where appropriate.
+
+ * Configure: Make /usr/local/man/man1 the first choice for the
+ man pages.
+
+ * patch.c (main): Open ofp after checking for ed script.
+ Close ofp and rejfp before trying plan B.
+ From epang@sfu.ca (Eugene Pang).
+
+ * backupfile.h: Declare get_version.
+
+ * Move decls of rindex and popen to common.h.
+
+ * common.h (myuid): New variable.
+ * patch.c (main): Initialize it.
+ * inp.c (myuid): Function removed.
+ (plan_a): Use the variable, not the function.
+
+ * patch.c: Reinstate -E option.
+
+Tue Jul 7 23:19:28 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * inp.c (myuid): New function.
+ (plan_a): Call it. Optimize stat calls. Be smarter about
+ detecting checked out RCS and SCCS files.
+ From Paul Eggert (eggert@twinsun.com).
+
+ * inp.c, util.c, patch.c: Don't bother checking for stat() > 0.
+
+Mon Jul 6 13:01:52 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * version.c (version): Don't print the RCS stuff, since we're
+ not updating it regularly.
+
+ * patch.c (get_some_switches): Make the usage message more accurate.
+
+ * patchlevel.h: PATCHLEVEL 12u7.
+
+ * Makefile.SH (dist): New target.
+ Makedist: File removed.
+
+ * inp.c (plan_a): Check whether the user can write to the
+ file, not whether anyone can write to the file.
+
+Sat Jul 4 00:06:58 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * inp.c (plan_a): Try to check out read-only files from RCS or SCCS.
+
+ * util.c (move_file): If backing up by linking fails, try copying.
+ From cek@sdc.boeing.com (Conrad Kimball).
+
+ * patch.c (get_some_switches): Eliminate -E option; always
+ remove empty output files.
+
+ * util.c (fetchname): Only undo slash removal for relative
+ paths if -p was not given.
+
+ * Makefile.sh: Add mostlyclean target.
+
+Fri Jul 3 23:48:14 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * util.c (fetchname): Accept whitespace between `Index:' and filename.
+ Also plug a small memory leak for diffs against /dev/null.
+ From eggert@twinsun.com (Paul Eggert).
+
+ * common.h: Don't define TRUE and FALSE if already defined.
+ From phk@data.fls.dk (Poul-Henning Kamp).
+
+Wed Apr 29 10:19:33 1992 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu)
+
+ * backupfile.c (get_version): Exit if given a bad backup type.
+
+Fri Mar 27 09:57:14 1992 Karl Berry (karl at hayley)
+
+ * common.h (S_ISDIR, S_ISREG): define these.
+ * inp.c (plan_a): use S_ISREG, not S_IFREG.
+ * util.c (fetchname): use S_ISDIR, not S_IFDIR.
+
+Mon Mar 16 14:10:42 1992 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u6.
+
+Sat Mar 14 13:13:29 1992 David J. MacKenzie (djm at frob.eng.umd.edu)
+
+ * Configure, config.h.SH: Check for directory header and unistd.h.
+
+ * patch.c (main): If -E was given and output file is empty after
+ patching, remove it.
+ (get_some_switches): Recognize -E option.
+
+ * patch.c (copy_till): Make garbled output an error, not a warning
+ that doesn't change the exit status.
+
+ * common.h: Protect against system declarations of malloc and realloc.
+
+ * Makedist: Add backupfile.[ch].
+
+ * Configure: Look for C library where NeXT and SVR4 put it.
+ Look in /usr/ucb after /bin and /usr/bin for utilities,
+ and look in /usr/ccs/bin, to make SVR4 happier.
+ Recognize m68k predefine.
+
+ * util.c (fetchname): Test of stat return value was backward.
+ From csss@scheme.cs.ubc.ca.
+
+ * version.c (version): Exit with status 0, not 1.
+
+ * Makefile.SH: Add backupfile.[cho].
+ * patch.c (main): Initialize backup file generation.
+ (get_some_switches): Add -V option.
+ * common.h, util,c, patch.c: Replace origext with simple_backup_suffix.
+ * util.c (move_file): Use find_backup_file_name.
+
+Tue Dec 3 11:27:16 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u5.
+
+ * Makefile.SH: Change clean, distclean, and realclean targets a
+ little so they agree with the GNU coding standards.
+ Add Makefile to addedbyconf, so distclean removes it.
+
+ * Configure: Recognize Domain/OS C library in /lib/libc.
+ From mmuegel@mot.com (Michael S. Muegel).
+
+ * pch.c: Fixes from Wayne Davison:
+ Patch now accepts no-context context diffs that are
+ specified with an assumed one line hunk (e.g. "*** 10 ****").
+ Fixed a bug in both context and unified diff processing that would
+ put a zero-context hunk in the wrong place (one line too soon).
+ Fixed a minor problem with p_max in unified diffs where it would
+ set p_max to hunkmax unnecessarily (the only adverse effect was to
+ not supply empty lines at eof by assuming they were truncated).
+
+Tue Jul 2 03:25:51 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
+
+ * Configure: Check for signal declaration in
+ /usr/include/sys/signal.h as well as /usr/include/signal.h.
+
+ * Configure, common.h, config.h.SH: Comment out the sprintf
+ declaration and tests to determine its return value type. It
+ conflicts with ANSI C systems' prototypes in stdio.h and the
+ return value of sprintf is never used anyway -- it's always cast
+ to void.
+
+Thu Jun 27 13:05:32 1991 David J. MacKenzie (djm at churchy.gnu.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u4.
+
+Thu Feb 21 15:18:14 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
+
+ * pch.c (another_hunk): Fix off by 1 error. From
+ iverson@xstor.com (Tim Iverson).
+
+Sun Jan 20 20:18:58 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
+
+ * Makefile.SH (all): Don't make a dummy `all' file.
+
+ * patchlevel.h: PATCHLEVEL 12u3.
+
+ * patch.c (nextarg): New function.
+ (get_some_switches): Use it, to prevent dereferencing a null
+ pointer if an option that takes an arg is not given one (is last
+ on the command line). From Paul Eggert.
+
+ * pch.c (another_hunk): Fix from Wayne Davison to recognize
+ single-line hunks in unified diffs (with a single line number
+ instead of a range).
+
+ * inp.c (rev_in_string): Don't use `s' before defining it. From
+ Wayne Davison.
+
+Mon Jan 7 06:25:11 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u2.
+
+ * pch.c (intuit_diff_type): Recognize `+++' in diff headers, for
+ unified diff format. From unidiff patch 1.
+
+Mon Dec 3 00:14:25 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
+
+ * patch.c (get_some_switches): Make the usage message more
+ informative.
+
+Sun Dec 2 23:20:18 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
+
+ * Configure: When checking for C preprocessor, look for 'abc.*xyz'
+ instead of 'abc.xyz', so ANSI C preprocessors work.
+
+ * Apply fix for -D from ksb@mentor.cc.purdue.edu (Kevin Braunsdorf).
+
+ * Apply unidiff patches from davison@dri.com (Wayne Davison).
+
+Wed Mar 7 23:47:25 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * pch.c: Call malformed instead of goto malformed
+ (just allows easier debugging).
+
+Tue Jan 23 21:27:00 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * common.h (TMP*NAME): Make these char *, not char [].
+ patch.c (main): Use TMPDIR (if present) to set TMP*NAME.
+ common.h: Declare getenv.
+
+Sun Dec 17 17:29:48 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * patch.c (reverse_flag_specified): New variable.
+ (get_some_switches, reinitialize_almost_everything): Use it.
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+version-control: never
+end:
diff --git a/xc/util/patch/MANIFEST b/xc/util/patch/MANIFEST
new file mode 100644
index 000000000..05fc9417c
--- /dev/null
+++ b/xc/util/patch/MANIFEST
@@ -0,0 +1,27 @@
+After all the patch kits are run you should have the following files:
+
+Filename Kit Description
+-------- --- -----------
+Configure 1 A shell script that installs everything system dependent.
+EXTERN.h 4 Toggle .h files to look foreign.
+INTERN.h 4 Toggle .h files to look domestic.
+MANIFEST 2 This list of files.
+Makefile.SH 2 The makefile.
+README 1 Installation instructions.
+backupfile.c 4 Make Emacs style backup file names.
+backupfile.h 4 Declarations to make Emacs style backup file names.
+common.h 3 Common definitions.
+config.H 4 Sample config.h, in case Configure won't run.
+config.h.SH 3 Produces config.h.
+inp.c 3 Input file abstract data type routines.
+inp.h 3 Public defs for above.
+malloc.c 1 An optional malloc package.
+patch.c 3 The patch program.
+patch.man 2 Manual page for patch.
+patchlevel.h 4 The patch level of the patch program.
+pch.c 2 Patch abstract data type routines.
+pch.h 3 Public defs for above.
+util.c 3 Utility routines.
+util.h 3 Public defs for above.
+version.c 1 Version number routine.
+version.h 4 Public defs for above.
diff --git a/xc/util/patch/README b/xc/util/patch/README
new file mode 100644
index 000000000..c8bd0e9c4
--- /dev/null
+++ b/xc/util/patch/README
@@ -0,0 +1,98 @@
+This version of patch contains modifications made by the Free Software
+Foundation, summarized in the file ChangeLog. Primarily they are to
+support the unified context diff format that GNU diff can produce, and
+to support making GNU Emacs-style backup files. They also include
+fixes for some bugs.
+
+There are two GNU variants of patch: this one, which retains Larry
+Wall's interactive Configure script and has patchlevels starting with
+`12u'; and another one that has a GNU-style non-interactive configure
+script and accepts long-named options, and has patchlevels starting
+with `12g'. Unlike the 12g variant, the 12u variant contains no
+copylefted code, for the paranoid. The two variants are otherwise the
+same. They should be available from the same places.
+
+The FSF is distributing this version of patch independently because as
+of this writing, Larry Wall has not released a new version of patch
+since mid-1988. I have heard that he has been too busy working on
+other things, like Perl.
+
+Here is a wish list of some projects to improve patch:
+
+1. Correctly handle files and patchfiles that contain NUL characters.
+This is hard to do straightforwardly; it would be less work to
+adopt a kind of escape encoding internally.
+Let ESC be a "control prefix". ESC @ stands for NUL. ESC [ stands for ESC.
+You need to crunch this when reading input (replace fgets),
+and when writing the output file (replace fputs),
+but otherwise everything can go along as it does now.
+Be careful to handle reject files correctly;
+I think they are currently created using `write', not `fputs'.
+
+2. Correctly handle patches produced by GNU diff for files that do
+not end with a newline.
+
+Please send bug reports for this version of patch to
+bug-gnu-utils@prep.ai.mit.edu as well as to Larry Wall (lwall@netlabs.com).
+ --djm@gnu.ai.mit.edu (David MacKenzie)
+
+ Patch Kit, Version 2.0
+
+ Copyright (c) 1988, Larry Wall
+
+You may copy the patch kit in whole or in part as long as you don't try to
+make money off it, or pretend that you wrote it.
+--------------------------------------------------------------------------
+
+Please read all the directions below before you proceed any further, and
+then follow them carefully. Failure to do so may void your warranty. :-)
+
+After you have unpacked your kit, you should have all the files listed
+in MANIFEST.
+
+Installation
+
+1) Run Configure. This will figure out various things about your system.
+ Some things Configure will figure out for itself, other things it will
+ ask you about. It will then proceed to make config.h, config.sh, and
+ Makefile.
+
+ You might possibly have to trim # comments from the front of Configure
+ if your sh doesn't handle them, but all other # comments will be taken
+ care of.
+
+ If you don't have sh, you'll have to rip the prototype of config.h out
+ of Configure and generate the defines by hand.
+
+2) Glance through config.h to make sure system dependencies are correct.
+ Most of them should have been taken care of by running the
+ Configure script.
+
+ If you have any additional changes to make to the C definitions, they
+ can be done in the Makefile, or in config.h. Bear in mind that they may
+ get undone next time you run Configure.
+
+3) make
+
+ This will attempt to make patch in the current directory.
+
+4) make install
+
+ This will put patch into a public directory (normally /usr/local/bin).
+ It will also try to put the man pages in a reasonable place. It will not
+ nroff the man page, however.
+
+5) Read the manual entry before running patch.
+
+6) IMPORTANT! Help save the world! Communicate any problems and
+ suggested patches to me, lwall@netlabs.com (Larry Wall),
+ so we can keep the world in sync. If you have a problem, there's
+ someone else out there who either has had or will have the same problem.
+
+ If possible, send in patches such that the patch program will apply them.
+ Context diffs are the best, then normal diffs. Don't send ed scripts--
+ I've probably changed my copy since the version you have.
+
+ Watch for patch patches in comp.sources.bugs. Patches will generally be
+ in a form usable by the patch program. Your current patch level
+ is shown in patchlevel.h.
diff --git a/xc/util/patch/backupfile.c b/xc/util/patch/backupfile.c
new file mode 100644
index 000000000..41632a6e2
--- /dev/null
+++ b/xc/util/patch/backupfile.c
@@ -0,0 +1,338 @@
+/* backupfile.c -- make Emacs style backup file names
+ Copyright (C) 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it without restriction.
+
+ 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. */
+
+/* David MacKenzie <djm@ai.mit.edu>.
+ Some algorithms adapted from GNU Emacs. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include "backupfile.h"
+#include "config.h"
+char *index ();
+char *rindex ();
+char *malloc ();
+
+#ifdef DIRENT
+#include <dirent.h>
+#ifdef direct
+#undef direct
+#endif
+#define direct dirent
+#define NLENGTH(direct) (strlen((direct)->d_name))
+#else /* !DIRENT */
+#define NLENGTH(direct) ((direct)->d_namlen)
+#ifdef USG
+#ifdef SYSNDIR
+#include <sys/ndir.h>
+#else /* !SYSNDIR */
+#include <ndir.h>
+#endif /* !SYSNDIR */
+#else /* !USG */
+#ifdef SYSDIR
+#include <sys/dir.h>
+#endif /* SYSDIR */
+#endif /* !USG */
+#endif /* !DIRENT */
+
+#ifndef isascii
+#define ISDIGIT(c) (isdigit ((unsigned char) (c)))
+#else
+#define ISDIGIT(c) (isascii (c) && isdigit (c))
+#endif
+
+#if defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if defined (_POSIX_VERSION)
+/* POSIX does not require that the d_ino field be present, and some
+ systems do not provide it. */
+#define REAL_DIR_ENTRY(dp) 1
+#else
+#define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
+#endif
+
+/* Which type of backup file names are generated. */
+enum backup_type backup_type = none;
+
+/* The extension added to file names to produce a simple (as opposed
+ to numbered) backup file name. */
+char *simple_backup_suffix = "~";
+
+char *basename ();
+char *dirname ();
+static char *concat ();
+char *find_backup_file_name ();
+static char *make_version_name ();
+static int max_backup_version ();
+static int version_number ();
+
+/* Return NAME with any leading path stripped off. */
+
+char *
+basename (name)
+ char *name;
+{
+ char *base;
+
+ base = rindex (name, '/');
+ return base ? base + 1 : name;
+}
+
+#ifndef NODIR
+/* Return the name of the new backup file for file FILE,
+ allocated with malloc. Return 0 if out of memory.
+ FILE must not end with a '/' unless it is the root directory.
+ Do not call this function if backup_type == none. */
+
+char *
+find_backup_file_name (file)
+ char *file;
+{
+ char *dir;
+ char *base_versions;
+ int highest_backup;
+
+ if (backup_type == simple)
+ return concat (file, simple_backup_suffix);
+ base_versions = concat (basename (file), ".~");
+ if (base_versions == 0)
+ return 0;
+ dir = dirname (file);
+ if (dir == 0)
+ {
+ free (base_versions);
+ return 0;
+ }
+ highest_backup = max_backup_version (base_versions, dir);
+ free (base_versions);
+ free (dir);
+ if (backup_type == numbered_existing && highest_backup == 0)
+ return concat (file, simple_backup_suffix);
+ return make_version_name (file, highest_backup + 1);
+}
+
+/* Return the number of the highest-numbered backup file for file
+ FILE in directory DIR. If there are no numbered backups
+ of FILE in DIR, or an error occurs reading DIR, return 0.
+ FILE should already have ".~" appended to it. */
+
+static int
+max_backup_version (file, dir)
+ char *file, *dir;
+{
+ DIR *dirp;
+ struct direct *dp;
+ int highest_version;
+ int this_version;
+ int file_name_length;
+
+ dirp = opendir (dir);
+ if (!dirp)
+ return 0;
+
+ highest_version = 0;
+ file_name_length = strlen (file);
+
+ while ((dp = readdir (dirp)) != 0)
+ {
+ if (!REAL_DIR_ENTRY (dp) || NLENGTH (dp) <= file_name_length)
+ continue;
+
+ this_version = version_number (file, dp->d_name, file_name_length);
+ if (this_version > highest_version)
+ highest_version = this_version;
+ }
+ closedir (dirp);
+ return highest_version;
+}
+
+/* Return a string, allocated with malloc, containing
+ "FILE.~VERSION~". Return 0 if out of memory. */
+
+static char *
+make_version_name (file, version)
+ char *file;
+ int version;
+{
+ char *backup_name;
+
+ backup_name = malloc (strlen (file) + 16);
+ if (backup_name == 0)
+ return 0;
+ sprintf (backup_name, "%s.~%d~", file, version);
+ return backup_name;
+}
+
+/* If BACKUP is a numbered backup of BASE, return its version number;
+ otherwise return 0. BASE_LENGTH is the length of BASE.
+ BASE should already have ".~" appended to it. */
+
+static int
+version_number (base, backup, base_length)
+ char *base;
+ char *backup;
+ int base_length;
+{
+ int version;
+ char *p;
+
+ version = 0;
+ if (!strncmp (base, backup, base_length) && ISDIGIT (backup[base_length]))
+ {
+ for (p = &backup[base_length]; ISDIGIT (*p); ++p)
+ version = version * 10 + *p - '0';
+ if (p[0] != '~' || p[1])
+ version = 0;
+ }
+ return version;
+}
+
+/* Return the newly-allocated concatenation of STR1 and STR2.
+ If out of memory, return 0. */
+
+static char *
+concat (str1, str2)
+ char *str1, *str2;
+{
+ char *newstr;
+ char str1_length = strlen (str1);
+
+ newstr = malloc (str1_length + strlen (str2) + 1);
+ if (newstr == 0)
+ return 0;
+ strcpy (newstr, str1);
+ strcpy (newstr + str1_length, str2);
+ return newstr;
+}
+
+/* Return the leading directories part of PATH,
+ allocated with malloc. If out of memory, return 0.
+ Assumes that trailing slashes have already been
+ removed. */
+
+char *
+dirname (path)
+ char *path;
+{
+ char *newpath;
+ char *slash;
+ int length; /* Length of result, not including NUL. */
+
+ slash = rindex (path, '/');
+ if (slash == 0)
+ {
+ /* File is in the current directory. */
+ path = ".";
+ length = 1;
+ }
+ else
+ {
+ /* Remove any trailing slashes from result. */
+ while (slash > path && *slash == '/')
+ --slash;
+
+ length = slash - path + 1;
+ }
+ newpath = malloc (length + 1);
+ if (newpath == 0)
+ return 0;
+ strncpy (newpath, path, length);
+ newpath[length] = 0;
+ return newpath;
+}
+
+/* If ARG is an unambiguous match for an element of the
+ null-terminated array OPTLIST, return the index in OPTLIST
+ of the matched element, else -1 if it does not match any element
+ or -2 if it is ambiguous (is a prefix of more than one element). */
+
+int
+argmatch (arg, optlist)
+ char *arg;
+ char **optlist;
+{
+ int i; /* Temporary index in OPTLIST. */
+ int arglen; /* Length of ARG. */
+ int matchind = -1; /* Index of first nonexact match. */
+ int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */
+
+ arglen = strlen (arg);
+
+ /* Test all elements for either exact match or abbreviated matches. */
+ for (i = 0; optlist[i]; i++)
+ {
+ if (!strncmp (optlist[i], arg, arglen))
+ {
+ if (strlen (optlist[i]) == arglen)
+ /* Exact match found. */
+ return i;
+ else if (matchind == -1)
+ /* First nonexact match found. */
+ matchind = i;
+ else
+ /* Second nonexact match found. */
+ ambiguous = 1;
+ }
+ }
+ if (ambiguous)
+ return -2;
+ else
+ return matchind;
+}
+
+/* Error reporting for argmatch.
+ KIND is a description of the type of entity that was being matched.
+ VALUE is the invalid value that was given.
+ PROBLEM is the return value from argmatch. */
+
+void
+invalid_arg (kind, value, problem)
+ char *kind;
+ char *value;
+ int problem;
+{
+ fprintf (stderr, "patch: ");
+ if (problem == -1)
+ fprintf (stderr, "invalid");
+ else /* Assume -2. */
+ fprintf (stderr, "ambiguous");
+ fprintf (stderr, " %s `%s'\n", kind, value);
+}
+
+static char *backup_args[] =
+{
+ "never", "simple", "nil", "existing", "t", "numbered", 0
+};
+
+static enum backup_type backup_types[] =
+{
+ simple, simple, numbered_existing, numbered_existing, numbered, numbered
+};
+
+/* Return the type of backup indicated by VERSION.
+ Unique abbreviations are accepted. */
+
+enum backup_type
+get_version (version)
+ char *version;
+{
+ int i;
+
+ if (version == 0 || *version == 0)
+ return numbered_existing;
+ i = argmatch (version, backup_args);
+ if (i >= 0)
+ return backup_types[i];
+ invalid_arg ("version control type", version, i);
+ exit (1);
+}
+#endif /* NODIR */
diff --git a/xc/util/patch/backupfile.h b/xc/util/patch/backupfile.h
new file mode 100644
index 000000000..43240a130
--- /dev/null
+++ b/xc/util/patch/backupfile.h
@@ -0,0 +1,37 @@
+/* backupfile.h -- declarations for making Emacs style backup file names
+ Copyright (C) 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it without restriction.
+
+ 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. */
+
+/* When to make backup files. */
+enum backup_type
+{
+ /* Never make backups. */
+ none,
+
+ /* Make simple backups of every file. */
+ simple,
+
+ /* Make numbered backups of files that already have numbered backups,
+ and simple backups of the others. */
+ numbered_existing,
+
+ /* Make numbered backups of every file. */
+ numbered
+};
+
+extern enum backup_type backup_type;
+extern char *simple_backup_suffix;
+
+#ifdef __STDC__
+char *find_backup_file_name (char *file);
+enum backup_type get_version (char *version);
+#else
+char *find_backup_file_name ();
+enum backup_type get_version ();
+#endif
diff --git a/xc/util/patch/config.H b/xc/util/patch/config.H
new file mode 100644
index 000000000..93cdf0327
--- /dev/null
+++ b/xc/util/patch/config.H
@@ -0,0 +1,33 @@
+/* config.h
+ * This file was produced by running the Configure script.
+ * Feel free to modify any of this as the need arises.
+ */
+
+
+#/*undef EUNICE /* no file linking? */
+#/*undef VMS
+
+#/*undef index strchr /* cultural */
+#/*undef rindex strrchr /* differences? */
+
+#/*undef void int /* is void to be avoided? */
+
+/* How many register declarations are paid attention to? */
+
+#define Reg1 register
+#define Reg2 register
+#define Reg3 register
+#define Reg4 register
+#define Reg5 register
+#define Reg6 register
+#define Reg7
+#define Reg8
+#define Reg9
+#define Reg10
+#define Reg11
+#define Reg12
+#define Reg13
+#define Reg14
+#define Reg15
+#define Reg16
+
diff --git a/xc/util/patch/config.h.SH b/xc/util/patch/config.h.SH
new file mode 100644
index 000000000..e34562fcc
--- /dev/null
+++ b/xc/util/patch/config.h.SH
@@ -0,0 +1,146 @@
+case $CONFIG in
+'')
+ if test ! -f config.sh; then
+ ln ../config.sh . || \
+ ln ../../config.sh . || \
+ ln ../../../config.sh . || \
+ (echo "Can't find config.sh."; exit 1)
+ echo "Using config.sh from above..."
+ fi
+ . ./config.sh
+ ;;
+esac
+echo "Extracting config.h (with variable substitutions)"
+cat <<!GROK!THIS! >config.h
+/* config.h
+ * This file was produced by running the config.h.SH script, which
+ * gets its values from config.sh, which is generally produced by
+ * running Configure.
+ *
+ * Feel free to modify any of this as the need arises. Note, however,
+ * that running config.h.SH again will wipe out any changes you've made.
+ * For a more permanent change edit config.sh and rerun config.h.SH.
+ */
+
+
+/* EUNICE:
+ * This symbol, if defined, indicates that the program is being compiled
+ * under the EUNICE package under VMS. The program will need to handle
+ * things like files that don't go away the first time you unlink them,
+ * due to version numbering. It will also need to compensate for lack
+ * of a respectable link() command.
+ */
+/* VMS:
+ * This symbol, if defined, indicates that the program is running under
+ * VMS. It is currently only set in conjunction with the EUNICE symbol.
+ */
+#$d_eunice EUNICE /**/
+#$d_eunice VMS /**/
+
+/* CPPSTDIN:
+ * This symbol contains the first part of the string which will invoke
+ * the C preprocessor on the standard input and produce to standard
+ * output. Typical value of "cc -E" or "/lib/cpp".
+ */
+/* CPPMINUS:
+ * This symbol contains the second part of the string which will invoke
+ * the C preprocessor on the standard input and produce to standard
+ * output. This symbol will have the value "-" if CPPSTDIN needs a minus
+ * to specify standard input, otherwise the value is "".
+ */
+#define CPPSTDIN "$cppstdin"
+#define CPPMINUS "$cppminus"
+
+/* CHARSPRINTF:
+ * This symbol is defined if this system declares "char *sprintf()" in
+ * stdio.h. The trend seems to be to declare it as "int sprintf()". It
+ * is up to the package author to declare sprintf correctly based on the
+ * symbol.
+ */
+/* #$d_charsprf CHARSPRINTF /**/
+
+/* FLEXFILENAMES:
+ * This symbol, if defined, indicates that the system supports filenames
+ * longer than 14 characters.
+ */
+#$d_flexfnam FLEXFILENAMES /**/
+
+/* index:
+ * This preprocessor symbol is defined, along with rindex, if the system
+ * uses the strchr and strrchr routines instead.
+ */
+/* rindex:
+ * This preprocessor symbol is defined, along with index, if the system
+ * uses the strchr and strrchr routines instead.
+ */
+#$d_index index strchr /* cultural */
+#$d_index rindex strrchr /* differences? */
+
+/* VOIDSIG:
+ * This symbol is defined if this system declares "void (*signal())()" in
+ * signal.h. The old way was to declare it as "int (*signal())()". It
+ * is up to the package author to declare things correctly based on the
+ * symbol.
+ */
+#$d_voidsig VOIDSIG /**/
+
+/* DIRHEADER:
+ * This definition indicates which directory library header to use.
+ */
+$d_dirheader
+
+/* HAVE_UNISTD_H:
+ * This is defined if the system has unistd.h.
+ */
+#$d_unistd HAVE_UNISTD_H /**/
+
+/* Reg1:
+ * This symbol, along with Reg2, Reg3, etc. is either the word "register"
+ * or null, depending on whether the C compiler pays attention to this
+ * many register declarations. The intent is that you don't have to
+ * order your register declarations in the order of importance, so you
+ * can freely declare register variables in sub-blocks of code and as
+ * function parameters. Do not use Reg<n> more than once per routine.
+ */
+
+#define Reg1 $reg1 /**/
+#define Reg2 $reg2 /**/
+#define Reg3 $reg3 /**/
+#define Reg4 $reg4 /**/
+#define Reg5 $reg5 /**/
+#define Reg6 $reg6 /**/
+#define Reg7 $reg7 /**/
+#define Reg8 $reg8 /**/
+#define Reg9 $reg9 /**/
+#define Reg10 $reg10 /**/
+#define Reg11 $reg11 /**/
+#define Reg12 $reg12 /**/
+#define Reg13 $reg13 /**/
+#define Reg14 $reg14 /**/
+#define Reg15 $reg15 /**/
+#define Reg16 $reg16 /**/
+
+/* VOIDFLAGS:
+ * This symbol indicates how much support of the void type is given by this
+ * compiler. What various bits mean:
+ *
+ * 1 = supports declaration of void
+ * 2 = supports arrays of pointers to functions returning void
+ * 4 = supports comparisons between pointers to void functions and
+ * addresses of void functions
+ *
+ * The package designer should define VOIDUSED to indicate the requirements
+ * of the package. This can be done either by #defining VOIDUSED before
+ * including config.h, or by defining defvoidused in Myinit.U. If the
+ * level of void support necessary is not present, defines void to int.
+ */
+#ifndef VOIDUSED
+#define VOIDUSED $defvoidused
+#endif
+#define VOIDFLAGS $voidflags
+#if (VOIDFLAGS & VOIDUSED) != VOIDUSED
+#$define void int /* is void to be avoided? */
+#$define M_VOID /* Xenix strikes again */
+#endif
+
+!GROK!THIS!
diff --git a/xc/util/patch/malloc.c b/xc/util/patch/malloc.c
new file mode 100644
index 000000000..3145bd434
--- /dev/null
+++ b/xc/util/patch/malloc.c
@@ -0,0 +1,467 @@
+/*
+ * @(#)nmalloc.c 1 (Caltech) 2/21/82
+ *
+ * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
+ *
+ * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
+ *
+ * This is a very fast storage allocator. It allocates blocks of a small
+ * number of different sizes, and keeps free lists of each size. Blocks
+ * that don't exactly fit are passed up to the next larger size. In this
+ * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
+ * This is designed for use in a program that uses vast quantities of
+ * memory, but bombs when it runs out. To make it a little better, it
+ * warns the user when he starts to get near the end.
+ *
+ * June 84, ACT: modified rcheck code to check the range given to malloc,
+ * rather than the range determined by the 2-power used.
+ *
+ * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
+ * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
+ * You should call malloc_init to reinitialize after loading dumped Emacs.
+ * Call malloc_stats to get info on memory stats if MSTATS turned on.
+ * realloc knows how to return same block given, just changing its size,
+ * if the power of 2 is correct.
+ */
+
+/*
+ * nextf[i] is the pointer to the next free block of size 2^(i+3). The
+ * smallest allocatable block is 8 bytes. The overhead information will
+ * go in the first int of the block, and the returned pointer will point
+ * to the second.
+ *
+#ifdef MSTATS
+ * nmalloc[i] is the difference between the number of mallocs and frees
+ * for a given block size.
+#endif /* MSTATS */
+ */
+
+#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
+#define ISFREE ((char) 0x54) /* magic byte that implies free block */
+ /* this is for error checking only */
+
+extern char etext;
+
+/* end of the program; can be changed by calling init_malloc */
+static char *endofpure = &etext;
+
+#ifdef MSTATS
+static int nmalloc[30];
+static int nmal, nfre;
+#endif /* MSTATS */
+
+/* If range checking is not turned on, all we have is a flag indicating
+ whether memory is allocated, an index in nextf[], and a size field; to
+ realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
+ on whether the former can hold the exact size (given the value of
+ 'index'). If range checking is on, we always need to know how much space
+ is allocated, so the 'size' field is never used. */
+
+struct mhead {
+ char mh_alloc; /* ISALLOC or ISFREE */
+ char mh_index; /* index in nextf[] */
+/* Remainder are valid only when block is allocated */
+ unsigned short mh_size; /* size, if < 0x10000 */
+#ifdef rcheck
+ unsigned mh_nbytes; /* number of bytes allocated */
+ int mh_magic4; /* should be == MAGIC4 */
+#endif /* rcheck */
+ };
+
+/* Access free-list pointer of a block.
+ It is stored at block + 4.
+ This is not a field in the mhead structure
+ because we want sizeof (struct mhead)
+ to describe the overhead for when the block is in use,
+ and we do not want the free-list pointer to count in that. */
+
+#define CHAIN(a) \
+ (*(struct mhead **) (sizeof (char *) + (char *) (a)))
+
+#ifdef rcheck
+
+/* To implement range checking, we write magic values in at the beginning and
+ end of each allocated block, and make sure they are undisturbed whenever a
+ free or a realloc occurs. */
+/* Written in each of the 4 bytes following the block's real space */
+#define MAGIC1 0x55
+/* Written in the 4 bytes before the block's real space */
+#define MAGIC4 0x55555555
+#define ASSERT(p) if (!(p)) botch("p"); else
+static
+botch(s)
+ char *s;
+{
+
+ printf("assertion botched: %s\n", s);
+ abort();
+}
+#define EXTRA 4 /* 4 bytes extra for MAGIC1s */
+#else
+#define ASSERT(p)
+#define EXTRA 0
+#endif /* rcheck */
+
+/* nextf[i] is free list of blocks of size 2**(i + 3) */
+
+static struct mhead *nextf[30];
+
+#ifdef M_WARN
+/* Number of bytes of writable memory we can expect to be able to get */
+static int lim_data;
+/* Level number of warnings already issued.
+ 0 -- no warnings issued.
+ 1 -- 75% warning already issued.
+ 2 -- 85% warning already issued.
+*/
+static int warnlevel;
+#endif /* M_WARN */
+
+/* nonzero once initial bunch of free blocks made */
+static int gotpool;
+
+/* Cause reinitialization based on job parameters;
+ also declare where the end of pure storage is. */
+malloc_init (end)
+ char *end; {
+ endofpure = end;
+#ifdef M_WARN
+ lim_data = 0;
+ warnlevel = 0;
+#endif /* M_WARN */
+ }
+
+static
+morecore (nu) /* ask system for more memory */
+ register int nu; { /* size index to get more of */
+ char *sbrk ();
+ register char *cp;
+ register int nblks;
+ register int siz;
+
+#ifdef M_WARN
+#ifndef BSD42
+#ifdef USG
+ extern long ulimit ();
+ if (lim_data == 0) /* find out how much we can get */
+ lim_data = ulimit (3, 0) - TEXT_START;
+#else /*HMS: was endif */
+ if (lim_data == 0) /* find out how much we can get */
+ lim_data = vlimit (LIM_DATA, -1);
+#endif /* USG */ /HMS:* was not here */
+#else
+ if (lim_data == 0) {
+ struct rlimit XXrlimit;
+
+ getrlimit (RLIMIT_DATA, &XXrlimit);
+ lim_data = XXrlimit.rlim_cur;} /* soft limit */
+#endif /* BSD42 */
+#endif /* M_WARN */
+
+ /* On initial startup, get two blocks of each size up to 1k bytes */
+ if (!gotpool)
+ getpool (), getpool (), gotpool = 1;
+
+ /* Find current end of memory and issue warning if getting near max */
+
+ cp = sbrk (0);
+ siz = cp - endofpure;
+#ifdef M_WARN
+ switch (warnlevel) {
+ case 0:
+ if (siz > (lim_data / 4) * 3) {
+ warnlevel++;
+ malloc_warning ("Warning: past 75% of memory limit");}
+ break;
+ case 1:
+ if (siz > (lim_data / 20) * 17) {
+ warnlevel++;
+ malloc_warning ("Warning: past 85% of memory limit");}
+ break;
+ case 2:
+ if (siz > (lim_data / 20) * 19) {
+ warnlevel++;
+ malloc_warning ("Warning: past 95% of memory limit");}
+ break;}
+#endif /* M_WARN */
+
+ if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ sbrk (1024 - ((int) cp & 0x3ff));
+
+ /* Take at least 2k, and figure out how many blocks of the desired size we're about to get */
+ nblks = 1;
+ if ((siz = nu) < 8)
+ nblks = 1 << ((siz = 8) - nu);
+
+ if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
+ return; /* no more room! */
+ if ((int) cp & 7) { /* shouldn't happen, but just in case */
+ cp = (char *) (((int) cp + 8) & ~7);
+ nblks--;}
+
+ /* save new header and link the nblks blocks together */
+ nextf[nu] = (struct mhead *) cp;
+ siz = 1 << (nu + 3);
+ while (1) {
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = nu;
+ if (--nblks <= 0) break;
+ CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
+ cp += siz;}
+/* CHAIN ((struct mhead *) cp) = 0; /* since sbrk() returns cleared core, this is already set */
+ }
+
+static
+getpool () {
+ register int nu;
+ register char *cp = sbrk (0);
+
+ if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ sbrk (1024 - ((int) cp & 0x3ff));
+
+ /* Get 2k of storage */
+
+ cp = sbrk (04000);
+ if (cp == (char *) -1)
+ return;
+
+ /* Divide it into an initial 8-word block
+ plus one block of size 2**nu for nu = 3 ... 10. */
+
+ CHAIN (cp) = nextf[0];
+ nextf[0] = (struct mhead *) cp;
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = 0;
+ cp += 8;
+
+ for (nu = 0; nu < 7; nu++) {
+ CHAIN (cp) = nextf[nu];
+ nextf[nu] = (struct mhead *) cp;
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = nu;
+ cp += 8 << nu;}}
+
+char *
+malloc (n) /* get a block */
+ unsigned n; {
+ register struct mhead *p;
+ register unsigned int nbytes;
+ register int nunits = 0;
+
+ /* Figure out how many bytes are required, rounding up to the nearest
+ multiple of 4, then figure out which nextf[] area to use */
+ nbytes = (n + sizeof *p + EXTRA + 3) & ~3;
+ {
+ register unsigned int shiftr = (nbytes - 1) >> 2;
+
+ while (shiftr >>= 1)
+ nunits++;
+ }
+
+ /* If there are no blocks of the appropriate size, go get some */
+ /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
+ if (nextf[nunits] == 0)
+ morecore (nunits);
+
+ /* Get one block off the list, and set the new list head */
+ if ((p = nextf[nunits]) == 0)
+ return 0;
+ nextf[nunits] = CHAIN (p);
+
+ /* Check for free block clobbered */
+ /* If not for this check, we would gobble a clobbered free chain ptr */
+ /* and bomb out on the NEXT allocate of this size block */
+ if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
+#ifdef rcheck
+ botch ("block on free list clobbered");
+#else
+ abort ();
+#endif /* rcheck */
+
+ /* Fill in the info, and if range checking, set up the magic numbers */
+ p -> mh_alloc = ISALLOC;
+#ifdef rcheck
+ p -> mh_nbytes = n;
+ p -> mh_magic4 = MAGIC4;
+ {
+ register char *m = (char *) (p + 1) + n;
+
+ *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
+ }
+#else
+ p -> mh_size = n;
+#endif /* rcheck */
+#ifdef MSTATS
+ nmalloc[nunits]++;
+ nmal++;
+#endif /* MSTATS */
+ return (char *) (p + 1);}
+
+free (mem)
+ char *mem; {
+ register struct mhead *p;
+ {
+ register char *ap = mem;
+
+ ASSERT (ap != 0);
+ p = (struct mhead *) ap - 1;
+ ASSERT (p -> mh_alloc == ISALLOC);
+#ifdef rcheck
+ ASSERT (p -> mh_magic4 == MAGIC4);
+ ap += p -> mh_nbytes;
+ ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
+ ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1);
+#endif /* rcheck */
+ }
+ {
+ register int nunits = p -> mh_index;
+
+ ASSERT (nunits <= 29);
+ p -> mh_alloc = ISFREE;
+ CHAIN (p) = nextf[nunits];
+ nextf[nunits] = p;
+#ifdef MSTATS
+ nmalloc[nunits]--;
+ nfre++;
+#endif /* MSTATS */
+ }
+ }
+
+char *
+realloc (mem, n)
+ char *mem;
+ register unsigned n; {
+ register struct mhead *p;
+ register unsigned int tocopy;
+ register int nbytes;
+ register int nunits;
+
+ if ((p = (struct mhead *) mem) == 0)
+ return malloc (n);
+ p--;
+ nunits = p -> mh_index;
+ ASSERT (p -> mh_alloc == ISALLOC);
+#ifdef rcheck
+ ASSERT (p -> mh_magic4 == MAGIC4);
+ {
+ register char *m = mem + (tocopy = p -> mh_nbytes);
+ ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
+ ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1);
+ }
+#else
+ if (p -> mh_index >= 13)
+ tocopy = (1 << (p -> mh_index + 3)) - sizeof *p;
+ else
+ tocopy = p -> mh_size;
+#endif /* rcheck */
+
+ /* See if desired size rounds to same power of 2 as actual size. */
+ nbytes = (n + sizeof *p + EXTRA + 7) & ~7;
+
+ /* If ok, use the same block, just marking its size as changed. */
+ if (nbytes > (4 << nunits) && nbytes <= (8 << nunits)) {
+#ifdef rcheck
+ register char *m = mem + tocopy;
+ *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
+ p-> mh_nbytes = n;
+ m = mem + n;
+ *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1;
+#else
+ p -> mh_size = n;
+#endif /* rcheck */
+ return mem;}
+
+ if (n < tocopy)
+ tocopy = n;
+ {
+ register char *new;
+ void bcopy(); /*HMS: here? */
+
+ if ((new = malloc (n)) == 0)
+ return 0;
+ bcopy (mem, new, tocopy);
+ free (mem);
+ return new;
+ }
+ }
+
+#ifdef MSTATS
+/* Return statistics describing allocation of blocks of size 2**n. */
+
+struct mstats_value {
+ int blocksize;
+ int nfree;
+ int nused;
+ };
+
+struct mstats_value
+malloc_stats (size)
+ int size; {
+ struct mstats_value v;
+ register int i;
+ register struct mhead *p;
+
+ v.nfree = 0;
+
+ if (size < 0 || size >= 30) {
+ v.blocksize = 0;
+ v.nused = 0;
+ return v;}
+
+ v.blocksize = 1 << (size + 3);
+ v.nused = nmalloc[size];
+
+ for (p = nextf[size]; p; p = CHAIN (p))
+ v.nfree++;
+
+ return v;}
+#endif
+
+/* how much space is available? */
+
+unsigned freespace() {
+ register int i, j;
+ register struct mhead *p;
+ register unsigned space = 0;
+ int local; /* address only is used */
+
+ space = (char *)&local - sbrk(0); /* stack space */
+
+ for (i = 0; i < 30; i++) {
+ for (j = 0, p = nextf[i]; p; p = CHAIN (p), j++) ;
+ space += j * (1 << (i + 3));}
+
+ return(space);}
+
+/* How big is this cell? */
+
+unsigned mc_size(cp)
+ char *cp;{
+ register struct mhead *p;
+
+ if ((p = (struct mhead *) cp) == 0) {
+ /*HMS? */
+ }
+ p--;
+#ifdef rcheck
+ return p -> mh_nbytes;
+#else
+ return (1 << (p -> mh_index + 3)) - sizeof *p;
+/**/
+/* if (p -> mh_index >= 13)
+/* return (1 << (p -> mh_index + 3)) - sizeof *p;
+/* else
+/* return p -> mh_size;
+/**/
+#endif /* rcheck */
+ }
+
+/*HMS: Really should use memcpy, if available... */
+
+void bcopy(source, dest, len)
+ register char *source, *dest;
+ register len; {
+ register i;
+
+ for (i = 0; i < len; i++)
+ *dest++ = *source++;}
diff --git a/xc/util/patch/util.c b/xc/util/patch/util.c
new file mode 100644
index 000000000..e33f21ddb
--- /dev/null
+++ b/xc/util/patch/util.c
@@ -0,0 +1,450 @@
+#include "EXTERN.h"
+#include "common.h"
+#include "INTERN.h"
+#include "util.h"
+#include "backupfile.h"
+
+void my_exit();
+
+static char *
+private_strerror (errnum)
+ int errnum;
+{
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+
+ if (errnum > 0 && errnum <= sys_nerr)
+ return sys_errlist[errnum];
+ return "Unknown system error";
+}
+#define strerror private_strerror
+
+/* Rename a file, copying it if necessary. */
+
+int
+move_file(from,to)
+char *from, *to;
+{
+ char bakname[512];
+ Reg1 char *s;
+ Reg2 int i;
+ Reg3 int fromfd;
+
+ /* to stdout? */
+
+ if (strEQ(to, "-")) {
+#ifdef DEBUGGING
+ if (debug & 4)
+ say2("Moving %s to stdout.\n", from);
+#endif
+ fromfd = open(from, 0);
+ if (fromfd < 0)
+ pfatal2("internal error, can't reopen %s", from);
+ while ((i=read(fromfd, buf, sizeof buf)) > 0)
+ if (write(1, buf, i) != 1)
+ pfatal1("write failed");
+ Close(fromfd);
+ return 0;
+ }
+
+ if (origprae) {
+ Strcpy(bakname, origprae);
+ Strcat(bakname, to);
+ } else {
+#ifndef NODIR
+ char *backupname = find_backup_file_name(to);
+ if (backupname == (char *) 0)
+ fatal1("out of memory\n");
+ Strcpy(bakname, backupname);
+ free(backupname);
+#else /* NODIR */
+ Strcpy(bakname, to);
+ Strcat(bakname, simple_backup_suffix);
+#endif /* NODIR */
+ }
+
+ if (stat(to, &filestat) == 0) { /* output file exists */
+ dev_t to_device = filestat.st_dev;
+ ino_t to_inode = filestat.st_ino;
+ char *simplename = bakname;
+
+ for (s=bakname; *s; s++) {
+ if (*s == '/')
+ simplename = s+1;
+ }
+ /* Find a backup name that is not the same file.
+ Change the first lowercase char into uppercase;
+ if that isn't sufficient, chop off the first char and try again. */
+ while (stat(bakname, &filestat) == 0 &&
+ to_device == filestat.st_dev && to_inode == filestat.st_ino) {
+ /* Skip initial non-lowercase chars. */
+ for (s=simplename; *s && !islower(*s); s++) ;
+ if (*s)
+ *s = toupper(*s);
+ else
+ Strcpy(simplename, simplename+1);
+ }
+ while (unlink(bakname) >= 0) ; /* while() is for benefit of Eunice */
+#ifdef DEBUGGING
+ if (debug & 4)
+ say3("Moving %s to %s.\n", to, bakname);
+#endif
+ if (link(to, bakname) < 0) {
+ /* Maybe `to' is a symlink into a different file system.
+ Copying replaces the symlink with a file; using rename
+ would be better. */
+ Reg4 int tofd;
+ Reg5 int bakfd;
+
+ bakfd = creat(bakname, 0666);
+ if (bakfd < 0) {
+ say4("Can't backup %s, output is in %s: %s\n", to, from,
+ strerror(errno));
+ return -1;
+ }
+ tofd = open(to, 0);
+ if (tofd < 0)
+ pfatal2("internal error, can't open %s", to);
+ while ((i=read(tofd, buf, sizeof buf)) > 0)
+ if (write(bakfd, buf, i) != i)
+ pfatal1("write failed");
+ Close(tofd);
+ Close(bakfd);
+ }
+ while (unlink(to) >= 0) ;
+ }
+#ifdef DEBUGGING
+ if (debug & 4)
+ say3("Moving %s to %s.\n", from, to);
+#endif
+ if (link(from, to) < 0) { /* different file system? */
+ Reg4 int tofd;
+
+ tofd = creat(to, 0666);
+ if (tofd < 0) {
+ say4("Can't create %s, output is in %s: %s\n",
+ to, from, strerror(errno));
+ return -1;
+ }
+ fromfd = open(from, 0);
+ if (fromfd < 0)
+ pfatal2("internal error, can't reopen %s", from);
+ while ((i=read(fromfd, buf, sizeof buf)) > 0)
+ if (write(tofd, buf, i) != i)
+ pfatal1("write failed");
+ Close(fromfd);
+ Close(tofd);
+ }
+ Unlink(from);
+ return 0;
+}
+
+/* Copy a file. */
+
+void
+copy_file(from,to)
+char *from, *to;
+{
+ Reg3 int tofd;
+ Reg2 int fromfd;
+ Reg1 int i;
+
+ tofd = creat(to, 0666);
+ if (tofd < 0)
+ pfatal2("can't create %s", to);
+ fromfd = open(from, 0);
+ if (fromfd < 0)
+ pfatal2("internal error, can't reopen %s", from);
+ while ((i=read(fromfd, buf, sizeof buf)) > 0)
+ if (write(tofd, buf, i) != i)
+ pfatal2("write to %s failed", to);
+ Close(fromfd);
+ Close(tofd);
+}
+
+/* Allocate a unique area for a string. */
+
+char *
+savestr(s)
+Reg1 char *s;
+{
+ Reg3 char *rv;
+ Reg2 char *t;
+
+ if (!s)
+ s = "Oops";
+ t = s;
+ while (*t++);
+ rv = malloc((MEM) (t - s));
+ if (rv == Nullch) {
+ if (using_plan_a)
+ out_of_mem = TRUE;
+ else
+ fatal1("out of memory\n");
+ }
+ else {
+ t = rv;
+ while (*t++ = *s++);
+ }
+ return rv;
+}
+
+#if defined(lint) && defined(CANVARARG)
+
+/*VARARGS ARGSUSED*/
+say(pat) char *pat; { ; }
+/*VARARGS ARGSUSED*/
+fatal(pat) char *pat; { ; }
+/*VARARGS ARGSUSED*/
+pfatal(pat) char *pat; { ; }
+/*VARARGS ARGSUSED*/
+ask(pat) char *pat; { ; }
+
+#else
+
+/* Vanilla terminal output (buffered). */
+
+void
+say(pat,arg1,arg2,arg3)
+char *pat;
+long arg1,arg2,arg3;
+{
+ fprintf(stderr, pat, arg1, arg2, arg3);
+ Fflush(stderr);
+}
+
+/* Terminal output, pun intended. */
+
+void /* very void */
+fatal(pat,arg1,arg2,arg3)
+char *pat;
+long arg1,arg2,arg3;
+{
+ fprintf(stderr, "patch: **** ");
+ fprintf(stderr, pat, arg1, arg2, arg3);
+ my_exit(1);
+}
+
+/* Say something from patch, something from the system, then silence . . . */
+
+void /* very void */
+pfatal(pat,arg1,arg2,arg3)
+char *pat;
+long arg1,arg2,arg3;
+{
+ int errnum = errno;
+
+ fprintf(stderr, "patch: **** ");
+ fprintf(stderr, pat, arg1, arg2, arg3);
+ fprintf(stderr, ": %s\n", strerror(errnum));
+ my_exit(1);
+}
+
+/* Get a response from the user, somehow or other. */
+
+void
+ask(pat,arg1,arg2,arg3)
+char *pat;
+long arg1,arg2,arg3;
+{
+ int ttyfd;
+ int r;
+ bool tty2 = isatty(2);
+
+ Sprintf(buf, pat, arg1, arg2, arg3);
+ Fflush(stderr);
+ write(2, buf, strlen(buf));
+ if (tty2) { /* might be redirected to a file */
+ r = read(2, buf, sizeof buf);
+ }
+ else if (isatty(1)) { /* this may be new file output */
+ Fflush(stdout);
+ write(1, buf, strlen(buf));
+ r = read(1, buf, sizeof buf);
+ }
+ else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
+ /* might be deleted or unwriteable */
+ write(ttyfd, buf, strlen(buf));
+ r = read(ttyfd, buf, sizeof buf);
+ Close(ttyfd);
+ }
+ else if (isatty(0)) { /* this is probably patch input */
+ Fflush(stdin);
+ write(0, buf, strlen(buf));
+ r = read(0, buf, sizeof buf);
+ }
+ else { /* no terminal at all--default it */
+ buf[0] = '\n';
+ r = 1;
+ }
+ if (r <= 0)
+ buf[0] = 0;
+ else
+ buf[r] = '\0';
+ if (!tty2)
+ say1(buf);
+}
+#endif /* lint */
+
+/* How to handle certain events when not in a critical region. */
+
+void
+set_signals(reset)
+int reset;
+{
+#ifndef lint
+#ifdef VOIDSIG
+ static void (*hupval)(),(*intval)();
+#else
+ static int (*hupval)(),(*intval)();
+#endif
+
+ if (!reset) {
+ hupval = signal(SIGHUP, SIG_IGN);
+ if (hupval != SIG_IGN)
+#ifdef VOIDSIG
+ hupval = my_exit;
+#else
+ hupval = (int(*)())my_exit;
+#endif
+ intval = signal(SIGINT, SIG_IGN);
+ if (intval != SIG_IGN)
+#ifdef VOIDSIG
+ intval = my_exit;
+#else
+ intval = (int(*)())my_exit;
+#endif
+ }
+ Signal(SIGHUP, hupval);
+ Signal(SIGINT, intval);
+#endif
+}
+
+/* How to handle certain events when in a critical region. */
+
+void
+ignore_signals()
+{
+#ifndef lint
+ Signal(SIGHUP, SIG_IGN);
+ Signal(SIGINT, SIG_IGN);
+#endif
+}
+
+/* Make sure we'll have the directories to create a file.
+ If `striplast' is TRUE, ignore the last element of `filename'. */
+
+void
+makedirs(filename,striplast)
+Reg1 char *filename;
+bool striplast;
+{
+ char tmpbuf[256];
+ Reg2 char *s = tmpbuf;
+ char *dirv[20]; /* Point to the NULs between elements. */
+ Reg3 int i;
+ Reg4 int dirvp = 0; /* Number of finished entries in dirv. */
+
+ /* Copy `filename' into `tmpbuf' with a NUL instead of a slash
+ between the directories. */
+ while (*filename) {
+ if (*filename == '/') {
+ filename++;
+ dirv[dirvp++] = s;
+ *s++ = '\0';
+ }
+ else {
+ *s++ = *filename++;
+ }
+ }
+ *s = '\0';
+ dirv[dirvp] = s;
+ if (striplast)
+ dirvp--;
+ if (dirvp < 0)
+ return;
+
+ strcpy(buf, "mkdir");
+ s = buf;
+ for (i=0; i<=dirvp; i++) {
+ struct stat sbuf;
+
+ if (stat(tmpbuf, &sbuf) && errno == ENOENT) {
+ while (*s) s++;
+ *s++ = ' ';
+ strcpy(s, tmpbuf);
+ }
+ *dirv[i] = '/';
+ }
+ if (s != buf)
+ system(buf);
+}
+
+/* Make filenames more reasonable. */
+
+char *
+fetchname(at,strip_leading,assume_exists)
+char *at;
+int strip_leading;
+int assume_exists;
+{
+ char *fullname;
+ char *name;
+ Reg1 char *t;
+ char tmpbuf[200];
+ int sleading = strip_leading;
+
+ if (!at)
+ return Nullch;
+ while (isspace(*at))
+ at++;
+#ifdef DEBUGGING
+ if (debug & 128)
+ say4("fetchname %s %d %d\n",at,strip_leading,assume_exists);
+#endif
+ if (strnEQ(at, "/dev/null", 9)) /* so files can be created by diffing */
+ return Nullch; /* against /dev/null. */
+ name = fullname = t = savestr(at);
+
+ /* Strip off up to `sleading' leading slashes and null terminate. */
+ for (; *t && !isspace(*t); t++)
+ if (*t == '/')
+ if (--sleading >= 0)
+ name = t+1;
+ *t = '\0';
+
+ /* If no -p option was given (957 is the default value!),
+ we were given a relative pathname,
+ and the leading directories that we just stripped off all exist,
+ put them back on. */
+ if (strip_leading == 957 && name != fullname && *fullname != '/') {
+ name[-1] = '\0';
+ if (stat(fullname, &filestat) == 0 && S_ISDIR (filestat.st_mode)) {
+ name[-1] = '/';
+ name=fullname;
+ }
+ }
+
+ name = savestr(name);
+ free(fullname);
+
+ if (stat(name, &filestat) && !assume_exists) {
+ char *filebase = basename(name);
+ int pathlen = filebase - name;
+
+ /* Put any leading path into `tmpbuf'. */
+ strncpy(tmpbuf, name, pathlen);
+
+#define try(f, a1, a2) (Sprintf(tmpbuf + pathlen, f, a1, a2), stat(tmpbuf, &filestat) == 0)
+ if ( try("RCS/%s%s", filebase, RCSSUFFIX)
+ || try("RCS/%s" , filebase, 0)
+ || try( "%s%s", filebase, RCSSUFFIX)
+ || try("SCCS/%s%s", SCCSPREFIX, filebase)
+ || try( "%s%s", SCCSPREFIX, filebase))
+ return name;
+ free(name);
+ name = Nullch;
+ }
+
+ return name;
+}