From ad2e1584276e14bde4fc851ce79b0871a77a6208 Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 30 Dec 1995 19:02:48 +0000 Subject: recording cvs-1.6 file death --- usr.bin/patch/Makefile | 6 - usr.bin/patch/README | 79 ---- usr.bin/patch/common.h | 138 ------ usr.bin/patch/inp.c | 313 -------------- usr.bin/patch/inp.h | 18 - usr.bin/patch/patch.1 | 446 ------------------- usr.bin/patch/patch.c | 800 ---------------------------------- usr.bin/patch/pch.c | 1108 ------------------------------------------------ usr.bin/patch/pch.h | 36 -- usr.bin/patch/util.c | 339 --------------- usr.bin/patch/util.h | 74 ---- 11 files changed, 3357 deletions(-) delete mode 100644 usr.bin/patch/Makefile delete mode 100644 usr.bin/patch/README delete mode 100644 usr.bin/patch/common.h delete mode 100644 usr.bin/patch/inp.c delete mode 100644 usr.bin/patch/inp.h delete mode 100644 usr.bin/patch/patch.1 delete mode 100644 usr.bin/patch/patch.c delete mode 100644 usr.bin/patch/pch.c delete mode 100644 usr.bin/patch/pch.h delete mode 100644 usr.bin/patch/util.c delete mode 100644 usr.bin/patch/util.h (limited to 'usr.bin/patch') diff --git a/usr.bin/patch/Makefile b/usr.bin/patch/Makefile deleted file mode 100644 index d6db9f7..0000000 --- a/usr.bin/patch/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 6/6/93 - -PROG= patch -SRCS= patch.c pch.c inp.c version.c util.c - -.include diff --git a/usr.bin/patch/README b/usr.bin/patch/README deleted file mode 100644 index 017b1a0..0000000 --- a/usr.bin/patch/README +++ /dev/null @@ -1,79 +0,0 @@ - -The Makefile and config.h files in this directory work with the current -BSD release. Don't run the Configure script, you'll get wrong results. - -Keith Bostic 1/10/88 ------------------------------------------------------------------------------ - - Patch Kit, Version 2.0 - - Copyright (c) 1986, 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@sdcrdcf.UUCP (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 net.sources.bugs. Patches will generally be - in a form usable by the patch program. If you are just now bringing up - patch and aren't sure how many patches there are, write to me and I'll - send any you don't have. Your current patch level is shown in patchlevel.h. - - -NEW FEATURES IN THIS RELEASE - -(Correct) support for 4.3bsd-style context diffs. -Files can be created from scratch. -You can specify a fuzz-factor for context matching. -You can force patch to ask no questions. -You can specify how much of the leading pathname to strip off filenames. -Uses a Configure script for greater portability. -You are now asked if you want to apply a reversed patch. -No limit (apart from memory) on the size of hunks. diff --git a/usr.bin/patch/common.h b/usr.bin/patch/common.h deleted file mode 100644 index 42d6883..0000000 --- a/usr.bin/patch/common.h +++ /dev/null @@ -1,138 +0,0 @@ -/* $Header: common.h,v 2.0 86/09/17 15:36:39 lwall Exp $ - * - * $Log: common.h,v $ - * Revision 2.0 86/09/17 15:36:39 lwall - * Baseline for netwide release. - * - */ - -#define DEBUGGING - -#include "config.h" - -/* shut lint up about the following when return value ignored */ - -#define Signal (void)signal -#define Unlink (void)unlink -#define Lseek (void)lseek -#define Fseek (void)fseek -#define Fstat (void)fstat -#define Pclose (void)pclose -#define Close (void)close -#define Fclose (void)fclose -#define Fflush (void)fflush -#define Sprintf (void)sprintf -#define Mktemp (void)mktemp -#define Strcpy (void)strcpy -#define Strcat (void)strcat - -#include -#include -#include -#include -#include -#include - -/* constants */ - -#define TRUE (1) -#define FALSE (0) - -#define MAXHUNKSIZE 100000 /* is this enough lines? */ -#define INITHUNKMAX 125 /* initial dynamic allocation size */ -#define MAXLINELEN 1024 -#define BUFFERSIZE 1024 -#define ORIGEXT ".orig" -#define SCCSPREFIX "s." -#define GET "get -e %s" -#define RCSSUFFIX ",v" -#define CHECKOUT "co -l %s" - -/* handy definitions */ - -#define Null(t) ((t)0) -#define Nullch Null(char *) -#define Nullfp Null(FILE *) -#define Nulline Null(LINENUM) - -#define Ctl(ch) ((ch) & 037) - -#define strNE(s1,s2) (strcmp(s1, s2)) -#define strEQ(s1,s2) (!strcmp(s1, s2)) -#define strnNE(s1,s2,l) (strncmp(s1, s2, l)) -#define strnEQ(s1,s2,l) (!strncmp(s1, s2, l)) - -/* typedefs */ - -typedef char bool; -typedef long LINENUM; /* must be signed */ -typedef unsigned MEM; /* what to feed malloc */ - -/* globals */ - -EXT int Argc; /* guess */ -EXT char **Argv; -EXT int Argc_last; /* for restarting plan_b */ -EXT char **Argv_last; - -EXT struct stat filestat; /* file statistics area */ -EXT int filemode INIT(0644); - -EXT char buf[MAXLINELEN]; /* general purpose buffer */ -EXT FILE *ofp INIT(Nullfp); /* output file pointer */ -EXT FILE *rejfp INIT(Nullfp); /* reject file pointer */ - -EXT bool using_plan_a INIT(TRUE); /* try to keep everything in memory */ -EXT bool out_of_mem INIT(FALSE); /* ran out of memory in plan a */ - -#define MAXFILEC 2 -EXT int filec INIT(0); /* how many file arguments? */ -EXT char *filearg[MAXFILEC]; -EXT bool ok_to_create_file INIT(FALSE); -EXT char *bestguess INIT(Nullch); /* guess at correct filename */ - -EXT char *outname INIT(Nullch); -EXT char rejname[128]; - -EXT char *origext INIT(Nullch); - -EXT char TMPOUTNAME[] INIT("/tmp/patchoXXXXXX"); -EXT char TMPINNAME[] INIT("/tmp/patchiXXXXXX"); /* might want /usr/tmp here */ -EXT char TMPREJNAME[] INIT("/tmp/patchrXXXXXX"); -EXT char TMPPATNAME[] INIT("/tmp/patchpXXXXXX"); -EXT bool toutkeep INIT(FALSE); -EXT bool trejkeep INIT(FALSE); - -EXT LINENUM last_offset INIT(0); -#ifdef DEBUGGING -EXT int debug INIT(0); -#endif -EXT LINENUM maxfuzz INIT(2); -EXT bool force INIT(FALSE); -EXT bool verbose INIT(TRUE); -EXT bool reverse INIT(FALSE); -EXT bool noreverse INIT(FALSE); -EXT bool skip_rest_of_patch INIT(FALSE); -EXT int strippath INIT(957); -EXT bool canonicalize INIT(FALSE); - -#define CONTEXT_DIFF 1 -#define NORMAL_DIFF 2 -#define ED_DIFF 3 -#define NEW_CONTEXT_DIFF 4 -EXT int diff_type INIT(0); - -EXT bool do_defines INIT(FALSE); /* patch using ifdef, ifndef, etc. */ -EXT char if_defined[128]; /* #ifdef xyzzy */ -EXT char not_defined[128]; /* #ifndef xyzzy */ -EXT char else_defined[] INIT("#else\n");/* #else */ -EXT char end_defined[128]; /* #endif xyzzy */ - -EXT char *revision INIT(Nullch); /* prerequisite revision, if any */ - -char *malloc(); -char *realloc(); -char *strcpy(); -char *strcat(); -long atol(); -char *mktemp(); diff --git a/usr.bin/patch/inp.c b/usr.bin/patch/inp.c deleted file mode 100644 index a3eeb90..0000000 --- a/usr.bin/patch/inp.c +++ /dev/null @@ -1,313 +0,0 @@ -/* $Header: inp.c,v 2.0 86/09/17 15:37:02 lwall Exp $ - * - * $Log: inp.c,v $ - * Revision 2.0 86/09/17 15:37:02 lwall - * Baseline for netwide release. - * - */ - -#include "EXTERN.h" -#include "common.h" -#include "util.h" -#include "pch.h" -#include "INTERN.h" -#include "inp.h" - -/* Input-file-with-indexable-lines abstract type */ - -static long i_size; /* size of the input file */ -static char *i_womp; /* plan a buffer for entire file */ -static char **i_ptr; /* pointers to lines in i_womp */ - -static int tifd = -1; /* plan b virtual string array */ -static char *tibuf[2]; /* plan b buffers */ -static LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */ -static LINENUM lines_per_buf; /* how many lines per buffer */ -static int tireclen; /* length of records in tmp file */ - -/* New patch--prepare to edit another file. */ - -void -re_input() -{ - if (using_plan_a) { - i_size = 0; -#ifndef lint - if (i_ptr != Null(char**)) - free((char *)i_ptr); -#endif - if (i_womp != Nullch) - free(i_womp); - i_womp = Nullch; - i_ptr = Null(char **); - } - else { - using_plan_a = TRUE; /* maybe the next one is smaller */ - Close(tifd); - tifd = -1; - free(tibuf[0]); - free(tibuf[1]); - tibuf[0] = tibuf[1] = Nullch; - tiline[0] = tiline[1] = -1; - tireclen = 0; - } -} - -/* Constuct the line index, somehow or other. */ - -void -scan_input(filename) -char *filename; -{ - if (!plan_a(filename)) - plan_b(filename); - if (verbose) { - say3("Patching file %s using Plan %s...\n", filename, - (using_plan_a ? "A" : "B") ); - } -} - -/* Try keeping everything in memory. */ - -bool -plan_a(filename) -char *filename; -{ - int ifd; - Reg1 char *s; - Reg2 LINENUM iline; - - if (ok_to_create_file && stat(filename, &filestat) < 0) { - if (verbose) - say2("(Creating file %s...)\n",filename); - makedirs(filename, TRUE); - close(creat(filename, 0666)); - } - if (stat(filename, &filestat) < 0) { - Sprintf(buf, "RCS/%s%s", filename, RCSSUFFIX); - if (stat(buf, &filestat) >= 0 || stat(buf+4, &filestat) >= 0) { - Sprintf(buf, CHECKOUT, filename); - if (verbose) - say2("Can't find %s--attempting to check it out from RCS.\n", - filename); - if (system(buf) || stat(filename, &filestat)) - fatal2("Can't check out %s.\n", filename); - } - else { - Sprintf(buf, "SCCS/%s%s", SCCSPREFIX, filename); - if (stat(buf, &filestat) >= 0 || stat(buf+5, &filestat) >= 0) { - Sprintf(buf, GET, filename); - if (verbose) - say2("Can't find %s--attempting to get it from SCCS.\n", - filename); - if (system(buf) || stat(filename, &filestat)) - fatal2("Can't get %s.\n", filename); - } - else - fatal2("Can't find %s.\n", filename); - } - } - filemode = filestat.st_mode; - if ((filemode & S_IFMT) & ~S_IFREG) - fatal2("%s is not a normal file--can't patch.\n", filename); - i_size = filestat.st_size; - if (out_of_mem) { - set_hunkmax(); /* make sure dynamic arrays are allocated */ - out_of_mem = FALSE; - return FALSE; /* force plan b because plan a bombed */ - } -#ifdef lint - i_womp = Nullch; -#else - i_womp = malloc((MEM)(i_size+2)); /* lint says this may alloc less than */ - /* i_size, but that's okay, I think. */ -#endif - if (i_womp == Nullch) - return FALSE; - if ((ifd = open(filename, 0)) < 0) - fatal2("Can't open file %s\n", filename); -#ifndef lint - if (read(ifd, i_womp, (int)i_size) != i_size) { - Close(ifd); /* probably means i_size > 15 or 16 bits worth */ - free(i_womp); /* at this point it doesn't matter if i_womp was */ - return FALSE; /* undersized. */ - } -#endif - Close(ifd); - if (i_size && i_womp[i_size-1] != '\n') - i_womp[i_size++] = '\n'; - i_womp[i_size] = '\0'; - - /* count the lines in the buffer so we know how many pointers we need */ - - iline = 0; - for (s=i_womp; *s; s++) { - if (*s == '\n') - iline++; - } -#ifdef lint - i_ptr = Null(char**); -#else - i_ptr = (char **)malloc((MEM)((iline + 2) * sizeof(char *))); -#endif - if (i_ptr == Null(char **)) { /* shucks, it was a near thing */ - free((char *)i_womp); - return FALSE; - } - - /* now scan the buffer and build pointer array */ - - iline = 1; - i_ptr[iline] = i_womp; - for (s=i_womp; *s; s++) { - if (*s == '\n') - i_ptr[++iline] = s+1; /* these are NOT null terminated */ - } - input_lines = iline - 1; - - /* now check for revision, if any */ - - if (revision != Nullch) { - if (!rev_in_string(i_womp)) { - if (force) { - if (verbose) - say2("\ -Warning: this file doesn't appear to be the %s version--patching anyway.\n", - revision); - } - else { - ask2("\ -This file doesn't appear to be the %s version--patch anyway? [n] ", - revision); - if (*buf != 'y') - fatal1("Aborted.\n"); - } - } - else if (verbose) - say2("Good. This file appears to be the %s version.\n", - revision); - } - return TRUE; /* plan a will work */ -} - -/* Keep (virtually) nothing in memory. */ - -void -plan_b(filename) -char *filename; -{ - Reg3 FILE *ifp; - Reg1 int i = 0; - Reg2 int maxlen = 1; - Reg4 bool found_revision = (revision == Nullch); - - using_plan_a = FALSE; - if ((ifp = fopen(filename, "r")) == Nullfp) - fatal2("Can't open file %s\n", filename); - if ((tifd = creat(TMPINNAME, 0666)) < 0) - fatal2("Can't open file %s\n", TMPINNAME); - while (fgets(buf, sizeof buf, ifp) != Nullch) { - if (revision != Nullch && !found_revision && rev_in_string(buf)) - found_revision = TRUE; - if ((i = strlen(buf)) > maxlen) - maxlen = i; /* find longest line */ - } - if (revision != Nullch) { - if (!found_revision) { - if (force) { - if (verbose) - say2("\ -Warning: this file doesn't appear to be the %s version--patching anyway.\n", - revision); - } - else { - ask2("\ -This file doesn't appear to be the %s version--patch anyway? [n] ", - revision); - if (*buf != 'y') - fatal1("Aborted.\n"); - } - } - else if (verbose) - say2("Good. This file appears to be the %s version.\n", - revision); - } - Fseek(ifp, 0L, 0); /* rewind file */ - lines_per_buf = BUFFERSIZE / maxlen; - tireclen = maxlen; - tibuf[0] = malloc((MEM)(BUFFERSIZE + 1)); - tibuf[1] = malloc((MEM)(BUFFERSIZE + 1)); - if (tibuf[1] == Nullch) - fatal1("Can't seem to get enough memory.\n"); - for (i=1; ; i++) { - if (! (i % lines_per_buf)) /* new block */ - if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE) - fatal1("patch: can't write temp file.\n"); - if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp) - == Nullch) { - input_lines = i - 1; - if (i % lines_per_buf) - if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE) - fatal1("patch: can't write temp file.\n"); - break; - } - } - Fclose(ifp); - Close(tifd); - if ((tifd = open(TMPINNAME, 0)) < 0) { - fatal2("Can't reopen file %s\n", TMPINNAME); - } -} - -/* Fetch a line from the input file, \n terminated, not necessarily \0. */ - -char * -ifetch(line,whichbuf) -Reg1 LINENUM line; -int whichbuf; /* ignored when file in memory */ -{ - if (line < 1 || line > input_lines) - return ""; - if (using_plan_a) - return i_ptr[line]; - else { - LINENUM offline = line % lines_per_buf; - LINENUM baseline = line - offline; - - if (tiline[0] == baseline) - whichbuf = 0; - else if (tiline[1] == baseline) - whichbuf = 1; - else { - tiline[whichbuf] = baseline; -#ifndef lint /* complains of long accuracy */ - Lseek(tifd, (off_t)baseline / lines_per_buf * BUFFERSIZE, 0); -#endif - if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0) - fatal2("Error reading tmp file %s.\n", TMPINNAME); - } - return tibuf[whichbuf] + (tireclen*offline); - } -} - -/* True if the string argument contains the revision number we want. */ - -bool -rev_in_string(string) -char *string; -{ - Reg1 char *s; - Reg2 int patlen; - - if (revision == Nullch) - return TRUE; - patlen = strlen(revision); - for (s = string; *s; s++) { - if (isspace(*s) && strnEQ(s+1, revision, patlen) && - isspace(s[patlen+1] )) { - return TRUE; - } - } - return FALSE; -} - diff --git a/usr.bin/patch/inp.h b/usr.bin/patch/inp.h deleted file mode 100644 index c6d2a91..0000000 --- a/usr.bin/patch/inp.h +++ /dev/null @@ -1,18 +0,0 @@ -/* $Header: inp.h,v 2.0 86/09/17 15:37:25 lwall Exp $ - * - * $Log: inp.h,v $ - * Revision 2.0 86/09/17 15:37:25 lwall - * Baseline for netwide release. - * - */ - -EXT LINENUM input_lines INIT(0); /* how long is input file in lines */ -EXT LINENUM last_frozen_line INIT(0); /* how many input lines have been */ - /* irretractibly output */ - -bool rev_in_string(); -void scan_input(); -bool plan_a(); /* returns false if insufficient memory */ -void plan_b(); -char *ifetch(); - diff --git a/usr.bin/patch/patch.1 b/usr.bin/patch/patch.1 deleted file mode 100644 index 3e4a12e..0000000 --- a/usr.bin/patch/patch.1 +++ /dev/null @@ -1,446 +0,0 @@ -''' $Header: patch.man,v 2.0 86/09/17 15:39:09 lwall Exp $ -''' -''' $Log: patch.man,v $ -''' Revision 2.0 86/09/17 15:39:09 lwall -''' Baseline for netwide release. -''' -''' Revision 1.4 86/08/01 19:23:22 lwall -''' Documented -v, -p, -F. -''' Added notes to patch senders. -''' -''' Revision 1.3 85/03/26 15:11:06 lwall -''' Frozen. -''' -''' Revision 1.2.1.4 85/03/12 16:14:27 lwall -''' Documented -p. -''' -''' Revision 1.2.1.3 85/03/12 16:09:41 lwall -''' Documented -D. -''' -''' Revision 1.2.1.2 84/12/05 11:06:55 lwall -''' Added -l switch, and noted bistability bug. -''' -''' Revision 1.2.1.1 84/12/04 17:23:39 lwall -''' Branch for sdcrdcf changes. -''' -''' Revision 1.2 84/12/04 17:22:02 lwall -''' Baseline version. -''' -.de Sh -.br -.ne 5 -.PP -\fB\\$1\fR -.PP -.. -.de Sp -.if t .sp .5v -.if n .sp -.. -''' -''' Set up \*(-- to give an unbreakable dash; -''' string Tr holds user defined translation string. -''' Bell System Logo is used as a dummy character. -''' -.ie n \{\ -.tr \(bs-\*(Tr -.ds -- \(bs- -.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch -.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch -.ds L" "" -.ds R" "" -.ds L' ' -.ds R' ' -'br\} -.el\{\ -.ds -- \(em\| -.tr \*(Tr -.ds L" `` -.ds R" '' -.ds L' ` -.ds R' ' -'br\} -.TH PATCH 1 "June 30, 1993" -.SH NAME -patch \- a program for applying a diff file to an original -.SH SYNOPSIS -.B patch -[options] orig patchfile [+ [options] orig] -.sp -but usually just -.sp -.B patch - -sets the maximum fuzz factor. -This switch only applied to context diffs, and causes -.I patch -to ignore up to that many lines in looking for places to install a hunk. -Note that a larger fuzz factor increases the odds of a faulty patch. -The default fuzz factor is 2, and it may not be set to more than -the number of lines of context in the context diff, ordinarily 3. -.TP 5 -.B \-l -causes the pattern matching to be done loosely, in case the tabs and -spaces have been munged in your input file. -Any sequence of whitespace in the pattern line will match any sequence -in the input file. -Normal characters must still match exactly. -Each line of the context must still match a line in the input file. -.TP 5 -.B \-n -forces -.I patch -to interpret the patch file as a normal diff. -.TP 5 -.B \-N -causes -.I patch -to ignore patches that it thinks are reversed or already applied. -See also -.B \-R . -.TP 5 -.B \-o -causes the next argument to be interpreted as the output file name. -.TP 5 -.B \-p -sets the pathname strip count, -which controls how pathnames found in the patch file are treated, in case -the you keep your files in a different directory than the person who sent -out the patch. -The strip count specifies how many backslashes are to be stripped from -the front of the pathname. -(Any intervening directory names also go away.) -For example, supposing the filename in the patch file was -.sp - /u/howard/src/blurfl/blurfl.c -.sp -setting -.B \-p -or -.B \-p0 -gives the entire pathname unmodified, -.B \-p1 -gives -.sp - u/howard/src/blurfl/blurfl.c -.sp -without the leading slash, -.B \-p4 -gives -.sp - blurfl/blurfl.c -.sp -and not specifying -.B \-p -at all just gives you "blurfl.c". -Whatever you end up with is looked for either in the current directory, -or the directory specified by the -.B \-d -switch. -.TP 5 -.B \-r -causes the next argument to be interpreted as the reject file name. -.TP 5 -.B \-R -tells -.I patch -that this patch was created with the old and new files swapped. -(Yes, I'm afraid that does happen occasionally, human nature being what it -is.) -.I Patch -will attempt to swap each hunk around before applying it. -Rejects will come out in the swapped format. -The -.B \-R -switch will not work with ed diff scripts because there is too little -information to reconstruct the reverse operation. -.Sp -If the first hunk of a patch fails, -.I patch -will reverse the hunk to see if it can be applied that way. -If it can, you will be asked if you want to have the -.B \-R -switch set. -If it can't, the patch will continue to be applied normally. -(Note: this method cannot detect a reversed patch if it is a normal diff -and if the first command is an append (i.e. it should have been a delete) -since appends always succeed, due to the fact that a null context will match -anywhere. -Luckily, most patches add or change lines rather than delete them, so most -reversed normal diffs will begin with a delete, which will fail, triggering -the heuristic.) -.TP 5 -.B \-s -makes -.I patch -do its work silently, unless an error occurs. -.TP 5 -.B \-S -causes -.I patch -to ignore this patch from the patch file, but continue on looking -for the next patch in the file. -Thus -.sp - patch -S + -S + -sets internal debugging flags, and is of interest only to -.I patch -patchers. -.SH ENVIRONMENT -No environment variables are used by -.IR patch . -.SH FILES -/tmp/patch* -.SH SEE ALSO -diff(1) -.SH NOTES FOR PATCH SENDERS -There are several things you should bear in mind if you are going to -be sending out patches. -First, you can save people a lot of grief by keeping a patchlevel.h file -which is patched to increment the patch level as the first diff in the -patch file you send out. -If you put a Prereq: line in with the patch, it won't let them apply -patches out of order without some warning. -Second, make sure you've specified the filenames right, either in a -context diff header, or with an Index: line. -If you are patching something in a subdirectory, be sure to tell the patch -user to specify a -.B \-p -switch as needed. -Third, you can create a file by sending out a diff that compares a -null file to the file you want to create. -This will only work if the file you want to create doesn't exist already in -the target directory. -Fourth, take care not to send out reversed patches, since it makes people wonder -whether they already applied the patch. -Fifth, while you may be able to get away with putting 582 diff listings into -one file, it is probably wiser to group related patches into separate files in -case something goes haywire. -.SH DIAGNOSTICS -Too many to list here, but generally indicative that -.I patch -couldn't parse your patch file. -.PP -The message \*(L"Hmm...\*(R" indicates that there is unprocessed text in -the patch file and that -.I patch -is attempting to intuit whether there is a patch in that text and, if so, -what kind of patch it is. -.SH CAVEATS -.I Patch -cannot tell if the line numbers are off in an ed script, and can only detect -bad line numbers in a normal diff when it finds a \*(L"change\*(R" or -a \*(L"delete\*(R" command. -A context diff using fuzz factor 3 may have the same problem. -Until a suitable interactive interface is added, you should probably do -a context diff in these cases to see if the changes made sense. -Of course, compiling without errors is a pretty good indication that the patch -worked, but not always. -.PP -.I Patch -usually produces the correct results, even when it has to do a lot of -guessing. -However, the results are guaranteed to be correct only when the patch is -applied to exactly the same version of the file that the patch was -generated from. -.SH BUGS -Could be smarter about partial matches, excessively \&deviant offsets and -swapped code, but that would take an extra pass. -.PP -If code has been duplicated (for instance with #ifdef OLDCODE ... #else ... -#endif), -.I patch -is incapable of patching both versions, and, if it works at all, will likely -patch the wrong one, and tell you that it succeeded to boot. -.PP -If you apply a patch you've already applied, -.I patch -will think it is a reversed patch, and offer to un-apply the patch. -This could be construed as a feature. diff --git a/usr.bin/patch/patch.c b/usr.bin/patch/patch.c deleted file mode 100644 index 0f91c5c..0000000 --- a/usr.bin/patch/patch.c +++ /dev/null @@ -1,800 +0,0 @@ -#ifndef lint -static char sccsid[] = "@(#)patch.c 8.1 (Berkeley) 6/6/93"; -#endif not lint - -char rcsid[] = - "$Header: patch.c,v 2.0.1.4 87/02/16 14:00:04 lwall Exp $"; - -/* patch - a program to apply diffs to original files - * - * Copyright 1986, Larry Wall - * - * This program may be copied as long as you don't try to make any - * money off of it, or pretend that you wrote it. - * - * $Log: patch.c,v $ - * Revision 2.0.1.4 87/02/16 14:00:04 lwall - * Short replacement caused spurious "Out of sync" message. - * - * Revision 2.0.1.3 87/01/30 22:45:50 lwall - * Improved diagnostic on sync error. - * Moved do_ed_script() to pch.c. - * - * Revision 2.0.1.2 86/11/21 09:39:15 lwall - * Fuzz factor caused offset of installed lines. - * - * Revision 2.0.1.1 86/10/29 13:10:22 lwall - * Backwards search could terminate prematurely. - * - * Revision 2.0 86/09/17 15:37:32 lwall - * Baseline for netwide release. - * - * Revision 1.5 86/08/01 20:53:24 lwall - * Changed some %d's to %ld's. - * Linted. - * - * Revision 1.4 86/08/01 19:17:29 lwall - * Fixes for machines that can't vararg. - * Added fuzz factor. - * Generalized -p. - * General cleanup. - * - * 85/08/15 van%ucbmonet@berkeley - * Changes for 4.3bsd diff -c. - * - * Revision 1.3 85/03/26 15:07:43 lwall - * Frozen. - * - * Revision 1.2.1.9 85/03/12 17:03:35 lwall - * Changed pfp->_file to fileno(pfp). - * - * Revision 1.2.1.8 85/03/12 16:30:43 lwall - * Check i_ptr and i_womp to make sure they aren't null before freeing. - * Also allow ed output to be suppressed. - * - * Revision 1.2.1.7 85/03/12 15:56:13 lwall - * Added -p option from jromine@uci-750a. - * - * Revision 1.2.1.6 85/03/12 12:12:51 lwall - * Now checks for normalness of file to patch. - * - * Revision 1.2.1.5 85/03/12 11:52:12 lwall - * Added -D (#ifdef) option from joe@fluke. - * - * Revision 1.2.1.4 84/12/06 11:14:15 lwall - * Made smarter about SCCS subdirectories. - * - * Revision 1.2.1.3 84/12/05 11:18:43 lwall - * Added -l switch to do loose string comparison. - * - * Revision 1.2.1.2 84/12/04 09:47:13 lwall - * Failed hunk count not reset on multiple patch file. - * - * Revision 1.2.1.1 84/12/04 09:42:37 lwall - * Branch for sdcrdcf changes. - * - * Revision 1.2 84/11/29 13:29:51 lwall - * Linted. Identifiers uniqified. Fixed i_ptr malloc() bug. Fixed - * multiple calls to mktemp(). Will now work on machines that can only - * read 32767 chars. Added -R option for diffs with new and old swapped. - * Various cosmetic changes. - * - * Revision 1.1 84/11/09 17:03:58 lwall - * Initial revision - * - */ - -#include "INTERN.h" -#include "common.h" -#include "EXTERN.h" -#include "version.h" -#include "util.h" -#include "pch.h" -#include "inp.h" - -/* procedures */ - -void reinitialize_almost_everything(); -void get_some_switches(); -LINENUM locate_hunk(); -void abort_hunk(); -void apply_hunk(); -void init_output(); -void init_reject(); -void copy_till(); -void spew_output(); -void dump_line(); -bool patch_match(); -bool similar(); -void re_input(); -void my_exit(); - -/* Apply a set of diffs as appropriate. */ - -main(argc,argv) -int argc; -char **argv; -{ - LINENUM where; - LINENUM newwhere; - LINENUM fuzz; - LINENUM mymaxfuzz; - int hunk = 0; - int failed = 0; - int i; - - setbuf(stderr, serrbuf); - for (i = 0; i= 2) - fatal1("You may not change to a different patch file.\n"); -} - -/* Process switches and filenames up to next '+' or end of list. */ - -void -get_some_switches() -{ - Reg1 char *s; - - rejname[0] = '\0'; - Argc_last = Argc; - Argv_last = Argv; - if (!Argc) - return; - for (Argc--,Argv++; Argc; Argc--,Argv++) { - s = Argv[0]; - if (strEQ(s, "+")) { - return; /* + will be skipped by for loop */ - } - if (*s != '-' || !s[1]) { - if (filec == MAXFILEC) - fatal1("Too many file arguments.\n"); - filearg[filec++] = savestr(s); - } - else { - switch (*++s) { - case 'b': - origext = savestr(Argv[1]); - Argc--,Argv++; - break; - case 'c': - diff_type = CONTEXT_DIFF; - break; - case 'd': - if (!*++s) { - Argc--,Argv++; - s = Argv[0]; - } - if (chdir(s) < 0) - fatal2("Can't cd to %s.\n", s); - break; - case 'D': - do_defines = TRUE; - if (!*++s) { - Argc--,Argv++; - s = Argv[0]; - } - Sprintf(if_defined, "#ifdef %s\n", s); - Sprintf(not_defined, "#ifndef %s\n", s); - Sprintf(end_defined, "#endif /* %s */\n", s); - break; - case 'e': - diff_type = ED_DIFF; - break; - case 'f': - force = TRUE; - break; - case 'F': - if (*++s == '=') - s++; - maxfuzz = atoi(s); - break; - case 'l': - canonicalize = TRUE; - break; - case 'n': - diff_type = NORMAL_DIFF; - break; - case 'N': - noreverse = TRUE; - break; - case 'o': - outname = savestr(Argv[1]); - Argc--,Argv++; - break; - case 'p': - if (*++s == '=') - s++; - strippath = atoi(s); - break; - case 'r': - Strcpy(rejname, Argv[1]); - Argc--,Argv++; - break; - case 'R': - reverse = TRUE; - break; - case 's': - verbose = FALSE; - break; - case 'S': - skip_rest_of_patch = TRUE; - break; - case 'v': - version(); - break; -#ifdef DEBUGGING - case 'x': - debug = atoi(s+1); - break; -#endif - default: - fatal2("Unrecognized switch: %s\n", Argv[0]); - } - } - } -} - -/* Attempt to find the right place to apply this hunk of patch. */ - -LINENUM -locate_hunk(fuzz) -LINENUM fuzz; -{ - Reg1 LINENUM first_guess = pch_first() + last_offset; - Reg2 LINENUM offset; - LINENUM pat_lines = pch_ptrn_lines(); - Reg3 LINENUM max_pos_offset = input_lines - first_guess - - pat_lines + 1; - Reg4 LINENUM max_neg_offset = first_guess - last_frozen_line - 1 - + pch_context(); - - if (!pat_lines) /* null range matches always */ - return first_guess; - if (max_neg_offset >= first_guess) /* do not try lines < 0 */ - max_neg_offset = first_guess - 1; - if (first_guess <= input_lines && patch_match(first_guess, Nulline, fuzz)) - return first_guess; - for (offset = 1; ; offset++) { - Reg5 bool check_after = (offset <= max_pos_offset); - Reg6 bool check_before = (offset <= max_neg_offset); - - if (check_after && patch_match(first_guess, offset, fuzz)) { -#ifdef DEBUGGING - if (debug & 1) - say3("Offset changing from %ld to %ld\n", last_offset, offset); -#endif - last_offset = offset; - return first_guess+offset; - } - else if (check_before && patch_match(first_guess, -offset, fuzz)) { -#ifdef DEBUGGING - if (debug & 1) - say3("Offset changing from %ld to %ld\n", last_offset, -offset); -#endif - last_offset = -offset; - return first_guess-offset; - } - else if (!check_before && !check_after) - return Nulline; - } -} - -/* We did not find the pattern, dump out the hunk so they can handle it. */ - -void -abort_hunk() -{ - Reg1 LINENUM i; - Reg2 LINENUM pat_end = pch_end(); - /* add in last_offset to guess the same as the previous successful hunk */ - LINENUM oldfirst = pch_first() + last_offset; - LINENUM newfirst = pch_newfirst() + last_offset; - LINENUM oldlast = oldfirst + pch_ptrn_lines() - 1; - LINENUM newlast = newfirst + pch_repl_lines() - 1; - char *stars = (diff_type == NEW_CONTEXT_DIFF ? " ****" : ""); - char *minuses = (diff_type == NEW_CONTEXT_DIFF ? " ----" : " -----"); - - fprintf(rejfp, "***************\n"); - for (i=0; i<=pat_end; i++) { - switch (pch_char(i)) { - case '*': - if (oldlast < oldfirst) - fprintf(rejfp, "*** 0%s\n", stars); - else if (oldlast == oldfirst) - fprintf(rejfp, "*** %ld%s\n", oldfirst, stars); - else - fprintf(rejfp, "*** %ld,%ld%s\n", oldfirst, oldlast, stars); - break; - case '=': - if (newlast < newfirst) - fprintf(rejfp, "--- 0%s\n", minuses); - else if (newlast == newfirst) - fprintf(rejfp, "--- %ld%s\n", newfirst, minuses); - else - fprintf(rejfp, "--- %ld,%ld%s\n", newfirst, newlast, minuses); - break; - case '\n': - fprintf(rejfp, "%s", pfetch(i)); - break; - case ' ': case '-': case '+': case '!': - fprintf(rejfp, "%c %s", pch_char(i), pfetch(i)); - break; - default: - say1("Fatal internal error in abort_hunk().\n"); - abort(); - } - } -} - -/* We found where to apply it (we hope), so do it. */ - -void -apply_hunk(where) -LINENUM where; -{ - Reg1 LINENUM old = 1; - Reg2 LINENUM lastline = pch_ptrn_lines(); - Reg3 LINENUM new = lastline+1; -#define OUTSIDE 0 -#define IN_IFNDEF 1 -#define IN_IFDEF 2 -#define IN_ELSE 3 - Reg4 int def_state = OUTSIDE; - Reg5 bool R_do_defines = do_defines; - Reg6 LINENUM pat_end = pch_end(); - - where--; - while (pch_char(new) == '=' || pch_char(new) == '\n') - new++; - - while (old <= lastline) { - if (pch_char(old) == '-') { - copy_till(where + old - 1); - if (R_do_defines) { - if (def_state == OUTSIDE) { - fputs(not_defined, ofp); - def_state = IN_IFNDEF; - } - else if (def_state == IN_IFDEF) { - fputs(else_defined, ofp); - def_state = IN_ELSE; - } - fputs(pfetch(old), ofp); - } - last_frozen_line++; - old++; - } - else if (new > pat_end) - break; - else if (pch_char(new) == '+') { - copy_till(where + old - 1); - if (R_do_defines) { - if (def_state == IN_IFNDEF) { - fputs(else_defined, ofp); - def_state = IN_ELSE; - } - else if (def_state == OUTSIDE) { - fputs(if_defined, ofp); - def_state = IN_IFDEF; - } - } - fputs(pfetch(new), ofp); - new++; - } - else { - if (pch_char(new) != pch_char(old)) { - say3("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n", - pch_hunk_beg() + old, - pch_hunk_beg() + new); -#ifdef DEBUGGING - say3("oldchar = '%c', newchar = '%c'\n", - pch_char(old), pch_char(new)); -#endif - my_exit(1); - } - if (pch_char(new) == '!') { - copy_till(where + old - 1); - if (R_do_defines) { - fputs(not_defined, ofp); - def_state = IN_IFNDEF; - } - while (pch_char(old) == '!') { - if (R_do_defines) { - fputs(pfetch(old), ofp); - } - last_frozen_line++; - old++; - } - if (R_do_defines) { - fputs(else_defined, ofp); - def_state = IN_ELSE; - } - while (pch_char(new) == '!') { - fputs(pfetch(new), ofp); - new++; - } - if (R_do_defines) { - fputs(end_defined, ofp); - def_state = OUTSIDE; - } - } - else { - assert(pch_char(new) == ' '); - old++; - new++; - } - } - } - if (new <= pat_end && pch_char(new) == '+') { - copy_till(where + old - 1); - if (R_do_defines) { - if (def_state == OUTSIDE) { - fputs(if_defined, ofp); - def_state = IN_IFDEF; - } - else if (def_state == IN_IFNDEF) { - fputs(else_defined, ofp); - def_state = IN_ELSE; - } - } - while (new <= pat_end && pch_char(new) == '+') { - fputs(pfetch(new), ofp); - new++; - } - } - if (R_do_defines && def_state != OUTSIDE) { - fputs(end_defined, ofp); - } -} - -/* Open the new file. */ - -void -init_output(name) -char *name; -{ - ofp = fopen(name, "w"); - if (ofp == Nullfp) - fatal2("patch: can't create %s.\n", name); -} - -/* Open a file to put hunks we can't locate. */ - -void -init_reject(name) -char *name; -{ - rejfp = fopen(name, "w"); - if (rejfp == Nullfp) - fatal2("patch: can't create %s.\n", name); -} - -/* Copy input file to output, up to wherever hunk is to be applied. */ - -void -copy_till(lastline) -Reg1 LINENUM lastline; -{ - Reg2 LINENUM R_last_frozen_line = last_frozen_line; - - if (R_last_frozen_line > lastline) - say1("patch: misordered hunks! output will be garbled.\n"); - while (R_last_frozen_line < lastline) { - dump_line(++R_last_frozen_line); - } - last_frozen_line = R_last_frozen_line; -} - -/* Finish copying the input file to the output file. */ - -void -spew_output() -{ -#ifdef DEBUGGING - if (debug & 256) - say3("il=%ld lfl=%ld\n",input_lines,last_frozen_line); -#endif - if (input_lines) - copy_till(input_lines); /* dump remainder of file */ - Fclose(ofp); - ofp = Nullfp; -} - -/* Copy one line from input to output. */ - -void -dump_line(line) -LINENUM line; -{ - Reg1 char *s; - Reg2 char R_newline = '\n'; - - /* Note: string is not null terminated. */ - for (s=ifetch(line, 0); putc(*s, ofp) != R_newline; s++) ; -} - -/* Does the patch pattern match at line base+offset? */ - -bool -patch_match(base, offset, fuzz) -LINENUM base; -LINENUM offset; -LINENUM fuzz; -{ - Reg1 LINENUM pline = 1 + fuzz; - Reg2 LINENUM iline; - Reg3 LINENUM pat_lines = pch_ptrn_lines() - fuzz; - - for (iline=base+offset+fuzz; pline <= pat_lines; pline++,iline++) { - if (canonicalize) { - if (!similar(ifetch(iline, (offset >= 0)), - pfetch(pline), - pch_line_len(pline) )) - return FALSE; - } - else if (strnNE(ifetch(iline, (offset >= 0)), - pfetch(pline), - pch_line_len(pline) )) - return FALSE; - } - return TRUE; -} - -/* Do two lines match with canonicalized white space? */ - -bool -similar(a,b,len) -Reg1 char *a; -Reg2 char *b; -Reg3 int len; -{ - while (len) { - if (isspace(*b)) { /* whitespace (or \n) to match? */ - if (!isspace(*a)) /* no corresponding whitespace? */ - return FALSE; - while (len && isspace(*b) && *b != '\n') - b++,len--; /* skip pattern whitespace */ - while (isspace(*a) && *a != '\n') - a++; /* skip target whitespace */ - if (*a == '\n' || *b == '\n') - return (*a == *b); /* should end in sync */ - } - else if (*a++ != *b++) /* match non-whitespace chars */ - return FALSE; - else - len--; /* probably not necessary */ - } - return TRUE; /* actually, this is not reached */ - /* since there is always a \n */ -} - -/* Exit with cleanup. */ - -void -my_exit(status) -int status; -{ - Unlink(TMPINNAME); - if (!toutkeep) { - Unlink(TMPOUTNAME); - } - if (!trejkeep) { - Unlink(TMPREJNAME); - } - Unlink(TMPPATNAME); - exit(status); -} diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c deleted file mode 100644 index 8837212..0000000 --- a/usr.bin/patch/pch.c +++ /dev/null @@ -1,1108 +0,0 @@ -/* $Header: pch.c,v 2.0.1.6 87/06/04 16:18:13 lwall Exp $ - * - * $Log: pch.c,v $ - * Revision 2.0.1.6 87/06/04 16:18:13 lwall - * pch_swap didn't swap p_bfake and p_efake. - * - * Revision 2.0.1.5 87/01/30 22:47:42 lwall - * Improved responses to mangled patches. - * - * Revision 2.0.1.4 87/01/05 16:59:53 lwall - * New-style context diffs caused double call to free(). - * - * Revision 2.0.1.3 86/11/14 10:08:33 lwall - * Fixed problem where a long pattern wouldn't grow the hunk. - * Also restored p_input_line when backtracking so error messages are right. - * - * Revision 2.0.1.2 86/11/03 17:49:52 lwall - * New-style delete triggers spurious assertion error. - * - * Revision 2.0.1.1 86/10/29 15:52:08 lwall - * Could falsely report new-style context diff. - * - * Revision 2.0 86/09/17 15:39:37 lwall - * Baseline for netwide release. - * - */ - -#include "EXTERN.h" -#include "common.h" -#include "util.h" -#include "INTERN.h" -#include "pch.h" - -/* Patch (diff listing) abstract type. */ - -static long p_filesize; /* size of the patch file */ -static LINENUM p_first; /* 1st line number */ -static LINENUM p_newfirst; /* 1st line number of replacement */ -static LINENUM p_ptrn_lines; /* # lines in pattern */ -static LINENUM p_repl_lines; /* # lines in replacement text */ -static LINENUM p_end = -1; /* last line in hunk */ -static LINENUM p_max; /* max allowed value of p_end */ -static LINENUM p_context = 3; /* # of context lines */ -static LINENUM p_input_line = 0; /* current line # from patch file */ -static char **p_line = Null(char**); /* the text of the hunk */ -static short *p_len = Null(short*); /* length of each line */ -static char *p_char = Nullch; /* +, -, and ! */ -static int hunkmax = INITHUNKMAX; /* size of above arrays to begin with */ -static int p_indent; /* indent to patch */ -static LINENUM p_base; /* where to intuit this time */ -static LINENUM p_bline; /* line # of p_base */ -static LINENUM p_start; /* where intuit found a patch */ -static LINENUM p_sline; /* and the line number for it */ -static LINENUM p_hunk_beg; /* line number of current hunk */ -static LINENUM p_efake = -1; /* end of faked up lines--don't free */ -static LINENUM p_bfake = -1; /* beg of faked up lines */ - -/* Prepare to look for the next patch in the patch file. */ - -void -re_patch() -{ - p_first = Nulline; - p_newfirst = Nulline; - p_ptrn_lines = Nulline; - p_repl_lines = Nulline; - p_end = (LINENUM)-1; - p_max = Nulline; - p_indent = 0; -} - -/* Open the patch file at the beginning of time. */ - -void -open_patch_file(filename) -char *filename; -{ - if (filename == Nullch || !*filename || strEQ(filename, "-")) { - pfp = fopen(TMPPATNAME, "w"); - if (pfp == Nullfp) - fatal2("patch: can't create %s.\n", TMPPATNAME); - while (fgets(buf, sizeof buf, stdin) != Nullch) - fputs(buf, pfp); - Fclose(pfp); - filename = TMPPATNAME; - } - pfp = fopen(filename, "r"); - if (pfp == Nullfp) - fatal2("patch file %s not found\n", filename); - Fstat(fileno(pfp), &filestat); - p_filesize = filestat.st_size; - next_intuit_at(0L,1L); /* start at the beginning */ - set_hunkmax(); -} - -/* Make sure our dynamically realloced tables are malloced to begin with. */ - -void -set_hunkmax() -{ -#ifndef lint - if (p_line == Null(char**)) - p_line = (char**) malloc((MEM)hunkmax * sizeof(char *)); - if (p_len == Null(short*)) - p_len = (short*) malloc((MEM)hunkmax * sizeof(short)); -#endif - if (p_char == Nullch) - p_char = (char*) malloc((MEM)hunkmax * sizeof(char)); -} - -/* Enlarge the arrays containing the current hunk of patch. */ - -void -grow_hunkmax() -{ - hunkmax *= 2; - /* - * Note that on most systems, only the p_line array ever gets fresh memory - * since p_len can move into p_line's old space, and p_char can move into - * p_len's old space. Not on PDP-11's however. But it doesn't matter. - */ - assert(p_line != Null(char**) && p_len != Null(short*) && p_char != Nullch); -#ifndef lint - p_line = (char**) realloc((char*)p_line, (MEM)hunkmax * sizeof(char *)); - p_len = (short*) realloc((char*)p_len, (MEM)hunkmax * sizeof(short)); - p_char = (char*) realloc((char*)p_char, (MEM)hunkmax * sizeof(char)); -#endif - if (p_line != Null(char**) && p_len != Null(short*) && p_char != Nullch) - return; - if (!using_plan_a) - fatal1("patch: out of memory (grow_hunkmax)\n"); - out_of_mem = TRUE; /* whatever is null will be allocated again */ - /* from within plan_a(), of all places */ -} - -/* True if the remainder of the patch file contains a diff of some sort. */ - -bool -there_is_another_patch() -{ - if (p_base != 0L && p_base >= p_filesize) { - if (verbose) - say1("done\n"); - return FALSE; - } - if (verbose) - say1("Hmm..."); - diff_type = intuit_diff_type(); - if (!diff_type) { - if (p_base != 0L) { - if (verbose) - say1(" Ignoring the trailing garbage.\ndone\n"); - } - else - say1(" I can't seem to find a patch in there anywhere.\n"); - return FALSE; - } - if (verbose) - say3(" %sooks like %s to me...\n", - (p_base == 0L ? "L" : "The next patch l"), - diff_type == CONTEXT_DIFF ? "a context diff" : - diff_type == NEW_CONTEXT_DIFF ? "a new-style context diff" : - diff_type == NORMAL_DIFF ? "a normal diff" : - "an ed script" ); - if (p_indent && verbose) - say3("(Patch is indented %d space%s.)\n", p_indent, p_indent==1?"":"s"); - skip_to(p_start,p_sline); - while (filearg[0] == Nullch) { - if (force) { - say1("No file to patch. Skipping...\n"); - filearg[0] = savestr(bestguess); - return TRUE; - } - ask1("File to patch: "); - if (*buf != '\n') { - if (bestguess) - free(bestguess); - bestguess = savestr(buf); - filearg[0] = fetchname(buf, 0, FALSE); - } - if (filearg[0] == Nullch) { - ask1("No file found--skip this patch? [n] "); - if (*buf != 'y') { - continue; - } - if (verbose) - say1("Skipping patch...\n"); - filearg[0] = fetchname(bestguess, 0, TRUE); - skip_rest_of_patch = TRUE; - return TRUE; - } - } - return TRUE; -} - -/* Determine what kind of diff is in the remaining part of the patch file. */ - -int -intuit_diff_type() -{ - Reg4 long this_line = 0; - Reg5 long previous_line; - Reg6 long first_command_line = -1; - long fcl_line; - Reg7 bool last_line_was_command = FALSE; - Reg8 bool this_is_a_command = FALSE; - Reg9 bool stars_last_line = FALSE; - Reg10 bool stars_this_line = FALSE; - Reg3 int indent; - Reg1 char *s; - Reg2 char *t; - char *indtmp = Nullch; - char *oldtmp = Nullch; - char *newtmp = Nullch; - char *indname = Nullch; - char *oldname = Nullch; - char *newname = Nullch; - Reg11 int retval; - bool no_filearg = (filearg[0] == Nullch); - - ok_to_create_file = FALSE; - Fseek(pfp, p_base, 0); - p_input_line = p_bline - 1; - for (;;) { - previous_line = this_line; - last_line_was_command = this_is_a_command; - stars_last_line = stars_this_line; - this_line = ftell(pfp); - indent = 0; - p_input_line++; - if (fgets(buf, sizeof buf, pfp) == Nullch) { - if (first_command_line >= 0L) { - /* nothing but deletes!? */ - p_start = first_command_line; - p_sline = fcl_line; - retval = ED_DIFF; - goto scan_exit; - } - else { - p_start = this_line; - p_sline = p_input_line; - retval = 0; - goto scan_exit; - } - } - for (s = buf; *s == ' ' || *s == '\t'; s++) { - if (*s == '\t') - indent += 8 - (indent % 8); - else - indent++; - } - for (t=s; isdigit(*t) || *t == ','; t++) ; - this_is_a_command = (isdigit(*s) && - (*t == 'd' || *t == 'c' || *t == 'a') ); - if (first_command_line < 0L && this_is_a_command) { - first_command_line = this_line; - fcl_line = p_input_line; - p_indent = indent; /* assume this for now */ - } - if (!stars_last_line && strnEQ(s, "*** ", 4)) - oldtmp = savestr(s+4); - else if (strnEQ(s, "--- ", 4)) - newtmp = savestr(s+4); - else if (strnEQ(s, "Index:", 6)) - indtmp = savestr(s+6); - else if (strnEQ(s, "Prereq:", 7)) { - for (t=s+7; isspace(*t); t++) ; - revision = savestr(t); - for (t=revision; *t && !isspace(*t); t++) ; - *t = '\0'; - if (!*revision) { - free(revision); - revision = Nullch; - } - } - if ((!diff_type || diff_type == ED_DIFF) && - first_command_line >= 0L && - strEQ(s, ".\n") ) { - p_indent = indent; - p_start = first_command_line; - p_sline = fcl_line; - retval = ED_DIFF; - goto scan_exit; - } - stars_this_line = strnEQ(s, "********", 8); - if ((!diff_type || diff_type == CONTEXT_DIFF) && stars_last_line && - strnEQ(s, "*** ", 4)) { - if (!atol(s+4)) - ok_to_create_file = TRUE; - /* if this is a new context diff the character just before */ - /* the newline is a '*'. */ - while (*s != '\n') - s++; - p_indent = indent; - p_start = previous_line; - p_sline = p_input_line - 1; - retval = (*(s-1) == '*' ? NEW_CONTEXT_DIFF : CONTEXT_DIFF); - goto scan_exit; - } - if ((!diff_type || diff_type == NORMAL_DIFF) && - last_line_was_command && - (strnEQ(s, "< ", 2) || strnEQ(s, "> ", 2)) ) { - p_start = previous_line; - p_sline = p_input_line - 1; - p_indent = indent; - retval = NORMAL_DIFF; - goto scan_exit; - } - } - scan_exit: - if (no_filearg) { - if (indtmp != Nullch) - indname = fetchname(indtmp, strippath, ok_to_create_file); - if (oldtmp != Nullch) - oldname = fetchname(oldtmp, strippath, ok_to_create_file); - if (newtmp != Nullch) - newname = fetchname(newtmp, strippath, ok_to_create_file); - if (oldname && newname) { - if (strlen(oldname) < strlen(newname)) - filearg[0] = savestr(oldname); - else - filearg[0] = savestr(newname); - } - else if (oldname) - filearg[0] = savestr(oldname); - else if (newname) - filearg[0] = savestr(newname); - else if (indname) - filearg[0] = savestr(indname); - } - if (bestguess) { - free(bestguess); - bestguess = Nullch; - } - if (filearg[0] != Nullch) - bestguess = savestr(filearg[0]); - else if (indtmp != Nullch) - bestguess = fetchname(indtmp, strippath, TRUE); - else { - if (oldtmp != Nullch) - oldname = fetchname(oldtmp, strippath, TRUE); - if (newtmp != Nullch) - newname = fetchname(newtmp, strippath, TRUE); - if (oldname && newname) { - if (strlen(oldname) < strlen(newname)) - bestguess = savestr(oldname); - else - bestguess = savestr(newname); - } - else if (oldname) - bestguess = savestr(oldname); - else if (newname) - bestguess = savestr(newname); - } - if (indtmp != Nullch) - free(indtmp); - if (oldtmp != Nullch) - free(oldtmp); - if (newtmp != Nullch) - free(newtmp); - if (indname != Nullch) - free(indname); - if (oldname != Nullch) - free(oldname); - if (newname != Nullch) - free(newname); - return retval; -} - -/* Remember where this patch ends so we know where to start up again. */ - -void -next_intuit_at(file_pos,file_line) -long file_pos; -long file_line; -{ - p_base = file_pos; - p_bline = file_line; -} - -/* Basically a verbose fseek() to the actual diff listing. */ - -void -skip_to(file_pos,file_line) -long file_pos; -long file_line; -{ - char *ret; - - assert(p_base <= file_pos); - if (verbose && p_base < file_pos) { - Fseek(pfp, p_base, 0); - say1("The text leading up to this was:\n--------------------------\n"); - while (ftell(pfp) < file_pos) { - ret = fgets(buf, sizeof buf, pfp); - assert(ret != Nullch); - say2("|%s", buf); - } - say1("--------------------------\n"); - } - else - Fseek(pfp, file_pos, 0); - p_input_line = file_line - 1; -} - -/* True if there is more of the current diff listing to process. */ - -bool -another_hunk() -{ - Reg1 char *s; - Reg8 char *ret; - Reg2 int context = 0; - - while (p_end >= 0) { - if (p_end == p_efake) - p_end = p_bfake; /* don't free twice */ - else - free(p_line[p_end]); - p_end--; - } - assert(p_end == -1); - p_efake = -1; - - p_max = hunkmax; /* gets reduced when --- found */ - if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) { - long line_beginning = ftell(pfp); - /* file pos of the current line */ - LINENUM repl_beginning = 0; /* index of --- line */ - Reg4 LINENUM fillcnt = 0; /* #lines of missing ptrn or repl */ - Reg5 LINENUM fillsrc; /* index of first line to copy */ - Reg6 LINENUM filldst; /* index of first missing line */ - bool ptrn_spaces_eaten = FALSE; /* ptrn was slightly misformed */ - Reg9 bool repl_could_be_missing = TRUE; - /* no + or ! lines in this hunk */ - bool repl_missing = FALSE; /* we are now backtracking */ - long repl_backtrack_position = 0; - /* file pos of first repl line */ - LINENUM repl_patch_line; /* input line number for same */ - Reg7 LINENUM ptrn_copiable = 0; - /* # of copiable lines in ptrn */ - - ret = pgets(buf, sizeof buf, pfp); - p_input_line++; - if (ret == Nullch || strnNE(buf, "********", 8)) { - next_intuit_at(line_beginning,p_input_line); - return FALSE; - } - p_context = 100; - p_hunk_beg = p_input_line + 1; - while (p_end < p_max) { - line_beginning = ftell(pfp); - ret = pgets(buf, sizeof buf, pfp); - p_input_line++; - if (ret == Nullch) { - if (p_max - p_end < 4) - Strcpy(buf, " \n"); /* assume blank lines got chopped */ - else { - if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - fatal1("Unexpected end of file in patch.\n"); - } - } - p_end++; - assert(p_end < hunkmax); - p_char[p_end] = *buf; - p_line[p_end] = Nullch; - switch (*buf) { - case '*': - if (strnEQ(buf, "********", 8)) { - if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - else - fatal2("Unexpected end of hunk at line %ld.\n", - p_input_line); - } - if (p_end != 0) { - if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - fatal3("Unexpected *** at line %ld: %s", p_input_line, buf); - } - context = 0; - p_line[p_end] = savestr(buf); - if (out_of_mem) { - p_end--; - return FALSE; - } - for (s=buf; *s && !isdigit(*s); s++) ; - if (!*s) - goto malformed; - p_first = (LINENUM) atol(s); - while (isdigit(*s)) s++; - if (*s == ',') { - for (; *s && !isdigit(*s); s++) ; - if (!*s) - goto malformed; - p_ptrn_lines = ((LINENUM)atol(s)) - p_first + 1; - } - else if (p_first) - p_ptrn_lines = 1; - else { - p_ptrn_lines = 0; - p_first = 1; - } - p_max = p_ptrn_lines + 6; /* we need this much at least */ - while (p_max >= hunkmax) - grow_hunkmax(); - p_max = hunkmax; - break; - case '-': - if (buf[1] == '-') { - if (repl_beginning || - (p_end != p_ptrn_lines + 1 + (p_char[p_end-1] == '\n'))) - { - if (p_end == 1) { - /* `old' lines were omitted - set up to fill */ - /* them in from 'new' context lines. */ - p_end = p_ptrn_lines + 1; - fillsrc = p_end + 1; - filldst = 1; - fillcnt = p_ptrn_lines; - } - else { - if (repl_beginning) { - if (repl_could_be_missing){ - repl_missing = TRUE; - goto hunk_done; - } - fatal3( -"Duplicate \"---\" at line %ld--check line numbers at line %ld.\n", - p_input_line, p_hunk_beg + repl_beginning); - } - else { - fatal4( -"%s \"---\" at line %ld--check line numbers at line %ld.\n", - (p_end <= p_ptrn_lines - ? "Premature" - : "Overdue" ), - p_input_line, p_hunk_beg); - } - } - } - repl_beginning = p_end; - repl_backtrack_position = ftell(pfp); - repl_patch_line = p_input_line; - p_line[p_end] = savestr(buf); - if (out_of_mem) { - p_end--; - return FALSE; - } - p_char[p_end] = '='; - for (s=buf; *s && !isdigit(*s); s++) ; - if (!*s) - goto malformed; - p_newfirst = (LINENUM) atol(s); - while (isdigit(*s)) s++; - if (*s == ',') { - for (; *s && !isdigit(*s); s++) ; - if (!*s) - goto malformed; - p_repl_lines = ((LINENUM)atol(s)) - p_newfirst + 1; - } - else if (p_newfirst) - p_repl_lines = 1; - else { - p_repl_lines = 0; - p_newfirst = 1; - } - p_max = p_repl_lines + p_end; - if (p_max > MAXHUNKSIZE) - fatal4("Hunk too large (%ld lines) at line %ld: %s", - p_max, p_input_line, buf); - while (p_max >= hunkmax) - grow_hunkmax(); - if (p_repl_lines != ptrn_copiable) - repl_could_be_missing = FALSE; - break; - } - goto change_line; - case '+': case '!': - repl_could_be_missing = FALSE; - change_line: - if (!isspace(buf[1]) && buf[1] != '>' && buf[1] != '<' && - repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - if (context > 0) { - if (context < p_context) - p_context = context; - context = -1000; - } - p_line[p_end] = savestr(buf+2); - if (out_of_mem) { - p_end--; - return FALSE; - } - break; - case '\t': case '\n': /* assume the 2 spaces got eaten */ - if (repl_beginning && repl_could_be_missing && - (!ptrn_spaces_eaten || diff_type == NEW_CONTEXT_DIFF) ) { - repl_missing = TRUE; - goto hunk_done; - } - p_line[p_end] = savestr(buf); - if (out_of_mem) { - p_end--; - return FALSE; - } - if (p_end != p_ptrn_lines + 1) { - ptrn_spaces_eaten |= (repl_beginning != 0); - context++; - if (!repl_beginning) - ptrn_copiable++; - p_char[p_end] = ' '; - } - break; - case ' ': - if (!isspace(buf[1]) && - repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - context++; - if (!repl_beginning) - ptrn_copiable++; - p_line[p_end] = savestr(buf+2); - if (out_of_mem) { - p_end--; - return FALSE; - } - break; - default: - if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - goto malformed; - } - /* set up p_len for strncmp() so we don't have to */ - /* assume null termination */ - if (p_line[p_end]) - p_len[p_end] = strlen(p_line[p_end]); - else - p_len[p_end] = 0; - } - - hunk_done: - if (p_end >=0 && !repl_beginning) - fatal2("No --- found in patch at line %ld\n", pch_hunk_beg()); - - if (repl_missing) { - - /* reset state back to just after --- */ - p_input_line = repl_patch_line; - for (p_end--; p_end > repl_beginning; p_end--) - free(p_line[p_end]); - Fseek(pfp, repl_backtrack_position, 0); - - /* redundant 'new' context lines were omitted - set */ - /* up to fill them in from the old file context */ - fillsrc = 1; - filldst = repl_beginning+1; - fillcnt = p_repl_lines; - p_end = p_max; - } - - if (diff_type == CONTEXT_DIFF && - (fillcnt || (p_first > 1 && ptrn_copiable > 2*p_context)) ) { - if (verbose) - say1("\ -(Fascinating--this is really a new-style context diff but without the telltale\n\ -extra asterisks on the *** line that usually indicate the new style...)\n"); - diff_type = NEW_CONTEXT_DIFF; - } - - /* if there were omitted context lines, fill them in now */ - if (fillcnt) { - p_bfake = filldst; /* remember where not to free() */ - p_efake = filldst + fillcnt - 1; - while (fillcnt-- > 0) { - while (fillsrc <= p_end && p_char[fillsrc] != ' ') - fillsrc++; - if (fillsrc > p_end) - fatal2("Replacement text or line numbers mangled in hunk at line %ld\n", - p_hunk_beg); - p_line[filldst] = p_line[fillsrc]; - p_char[filldst] = p_char[fillsrc]; - p_len[filldst] = p_len[fillsrc]; - fillsrc++; filldst++; - } - while (fillsrc <= p_end && fillsrc != repl_beginning && - p_char[fillsrc] != ' ') - fillsrc++; -#ifdef DEBUGGING - if (debug & 64) - printf("fillsrc %ld, filldst %ld, rb %ld, e+1 %ld\n", - fillsrc,filldst,repl_beginning,p_end+1); -#endif - assert(fillsrc==p_end+1 || fillsrc==repl_beginning); - assert(filldst==p_end+1 || filldst==repl_beginning); - } - } - else { /* normal diff--fake it up */ - char hunk_type; - Reg3 int i; - LINENUM min, max; - long line_beginning = ftell(pfp); - - p_context = 0; - ret = pgets(buf, sizeof buf, pfp); - p_input_line++; - if (ret == Nullch || !isdigit(*buf)) { - next_intuit_at(line_beginning,p_input_line); - return FALSE; - } - p_first = (LINENUM)atol(buf); - for (s=buf; isdigit(*s); s++) ; - if (*s == ',') { - p_ptrn_lines = (LINENUM)atol(++s) - p_first + 1; - while (isdigit(*s)) s++; - } - else - p_ptrn_lines = (*s != 'a'); - hunk_type = *s; - if (hunk_type == 'a') - p_first++; /* do append rather than insert */ - min = (LINENUM)atol(++s); - for (; isdigit(*s); s++) ; - if (*s == ',') - max = (LINENUM)atol(++s); - else - max = min; - if (hunk_type == 'd') - min++; - p_end = p_ptrn_lines + 1 + max - min + 1; - if (p_end > MAXHUNKSIZE) - fatal4("Hunk too large (%ld lines) at line %ld: %s", - p_end, p_input_line, buf); - while (p_end >= hunkmax) - grow_hunkmax(); - p_newfirst = min; - p_repl_lines = max - min + 1; - Sprintf(buf, "*** %ld,%ld\n", p_first, p_first + p_ptrn_lines - 1); - p_line[0] = savestr(buf); - if (out_of_mem) { - p_end = -1; - return FALSE; - } - p_char[0] = '*'; - for (i=1; i<=p_ptrn_lines; i++) { - ret = pgets(buf, sizeof buf, pfp); - p_input_line++; - if (ret == Nullch) - fatal2("Unexpected end of file in patch at line %ld.\n", - p_input_line); - if (*buf != '<') - fatal2("< expected at line %ld of patch.\n", p_input_line); - p_line[i] = savestr(buf+2); - if (out_of_mem) { - p_end = i-1; - return FALSE; - } - p_len[i] = strlen(p_line[i]); - p_char[i] = '-'; - } - if (hunk_type == 'c') { - ret = pgets(buf, sizeof buf, pfp); - p_input_line++; - if (ret == Nullch) - fatal2("Unexpected end of file in patch at line %ld.\n", - p_input_line); - if (*buf != '-') - fatal2("--- expected at line %ld of patch.\n", p_input_line); - } - Sprintf(buf, "--- %ld,%ld\n", min, max); - p_line[i] = savestr(buf); - if (out_of_mem) { - p_end = i-1; - return FALSE; - } - p_char[i] = '='; - for (i++; i<=p_end; i++) { - ret = pgets(buf, sizeof buf, pfp); - p_input_line++; - if (ret == Nullch) - fatal2("Unexpected end of file in patch at line %ld.\n", - p_input_line); - if (*buf != '>') - fatal2("> expected at line %ld of patch.\n", p_input_line); - p_line[i] = savestr(buf+2); - if (out_of_mem) { - p_end = i-1; - return FALSE; - } - p_len[i] = strlen(p_line[i]); - p_char[i] = '+'; - } - } - if (reverse) /* backwards patch? */ - if (!pch_swap()) - say1("Not enough memory to swap next hunk!\n"); -#ifdef DEBUGGING - if (debug & 2) { - int i; - char special; - - for (i=0; i <= p_end; i++) { - if (i == p_ptrn_lines) - special = '^'; - else - special = ' '; - fprintf(stderr, "%3d %c %c %s", i, p_char[i], special, p_line[i]); - Fflush(stderr); - } - } -#endif - if (p_end+1 < hunkmax) /* paranoia reigns supreme... */ - p_char[p_end+1] = '^'; /* add a stopper for apply_hunk */ - return TRUE; - -malformed: - fatal3("Malformed patch at line %ld: %s", p_input_line, buf); - /* about as informative as "Syntax error" in C */ - return FALSE; /* for lint */ -} - -/* Input a line from the patch file, worrying about indentation. */ - -char * -pgets(bf,sz,fp) -char *bf; -int sz; -FILE *fp; -{ - char *ret = fgets(bf, sz, fp); - Reg1 char *s; - Reg2 int indent = 0; - - if (p_indent && ret != Nullch) { - for (s=buf; indent < p_indent && (*s == ' ' || *s == '\t'); s++) { - if (*s == '\t') - indent += 8 - (indent % 7); - else - indent++; - } - if (buf != s) - Strcpy(buf, s); - } - return ret; -} - -/* Reverse the old and new portions of the current hunk. */ - -bool -pch_swap() -{ - char **tp_line; /* the text of the hunk */ - short *tp_len; /* length of each line */ - char *tp_char; /* +, -, and ! */ - Reg1 LINENUM i; - Reg2 LINENUM n; - bool blankline = FALSE; - Reg3 char *s; - - i = p_first; - p_first = p_newfirst; - p_newfirst = i; - - /* make a scratch copy */ - - tp_line = p_line; - tp_len = p_len; - tp_char = p_char; - p_line = Null(char**); /* force set_hunkmax to allocate again */ - p_len = Null(short*); - p_char = Nullch; - set_hunkmax(); - if (p_line == Null(char**) || p_len == Null(short*) || p_char == Nullch) { -#ifndef lint - if (p_line == Null(char**)) - free((char*)p_line); - p_line = tp_line; - if (p_len == Null(short*)) - free((char*)p_len); - p_len = tp_len; -#endif - if (p_char == Nullch) - free((char*)p_char); - p_char = tp_char; - return FALSE; /* not enough memory to swap hunk! */ - } - - /* now turn the new into the old */ - - i = p_ptrn_lines + 1; - if (tp_char[i] == '\n') { /* account for possible blank line */ - blankline = TRUE; - i++; - } - if (p_efake >= 0) { /* fix non-freeable ptr range */ - n = p_end - i + 1; - if (p_efake > i) - n = -n; - p_efake += n; - p_bfake += n; - } - for (n=0; i <= p_end; i++,n++) { - p_line[n] = tp_line[i]; - p_char[n] = tp_char[i]; - if (p_char[n] == '+') - p_char[n] = '-'; - p_len[n] = tp_len[i]; - } - if (blankline) { - i = p_ptrn_lines + 1; - p_line[n] = tp_line[i]; - p_char[n] = tp_char[i]; - p_len[n] = tp_len[i]; - n++; - } - assert(p_char[0] == '='); - p_char[0] = '*'; - for (s=p_line[0]; *s; s++) - if (*s == '-') - *s = '*'; - - /* now turn the old into the new */ - - assert(tp_char[0] == '*'); - tp_char[0] = '='; - for (s=tp_line[0]; *s; s++) - if (*s == '*') - *s = '-'; - for (i=0; n <= p_end; i++,n++) { - p_line[n] = tp_line[i]; - p_char[n] = tp_char[i]; - if (p_char[n] == '-') - p_char[n] = '+'; - p_len[n] = tp_len[i]; - } - assert(i == p_ptrn_lines + 1); - i = p_ptrn_lines; - p_ptrn_lines = p_repl_lines; - p_repl_lines = i; -#ifndef lint - if (tp_line == Null(char**)) - free((char*)tp_line); - if (tp_len == Null(short*)) - free((char*)tp_len); -#endif - if (tp_char == Nullch) - free((char*)tp_char); - return TRUE; -} - -/* Return the specified line position in the old file of the old context. */ - -LINENUM -pch_first() -{ - return p_first; -} - -/* Return the number of lines of old context. */ - -LINENUM -pch_ptrn_lines() -{ - return p_ptrn_lines; -} - -/* Return the probable line position in the new file of the first line. */ - -LINENUM -pch_newfirst() -{ - return p_newfirst; -} - -/* Return the number of lines in the replacement text including context. */ - -LINENUM -pch_repl_lines() -{ - return p_repl_lines; -} - -/* Return the number of lines in the whole hunk. */ - -LINENUM -pch_end() -{ - return p_end; -} - -/* Return the number of context lines before the first changed line. */ - -LINENUM -pch_context() -{ - return p_context; -} - -/* Return the length of a particular patch line. */ - -short -pch_line_len(line) -LINENUM line; -{ - return p_len[line]; -} - -/* Return the control character (+, -, *, !, etc) for a patch line. */ - -char -pch_char(line) -LINENUM line; -{ - return p_char[line]; -} - -/* Return a pointer to a particular patch line. */ - -char * -pfetch(line) -LINENUM line; -{ - return p_line[line]; -} - -/* Return where in the patch file this hunk began, for error messages. */ - -LINENUM -pch_hunk_beg() -{ - return p_hunk_beg; -} - -/* Apply an ed script by feeding ed itself. */ - -void -do_ed_script() -{ - Reg1 char *t; - Reg2 long beginning_of_this_line; - Reg3 bool this_line_is_command = FALSE; - Reg4 FILE *pipefp; - FILE *popen(); - - if (!skip_rest_of_patch) { - Unlink(TMPOUTNAME); - copy_file(filearg[0], TMPOUTNAME); - if (verbose) - Sprintf(buf, "/bin/ed %s", TMPOUTNAME); - else - Sprintf(buf, "/bin/ed - %s", TMPOUTNAME); - pipefp = popen(buf, "w"); - } - for (;;) { - beginning_of_this_line = ftell(pfp); - if (pgets(buf, sizeof buf, pfp) == Nullch) { - next_intuit_at(beginning_of_this_line,p_input_line); - break; - } - p_input_line++; - for (t=buf; isdigit(*t) || *t == ','; t++) ; - this_line_is_command = (isdigit(*buf) && - (*t == 'd' || *t == 'c' || *t == 'a') ); - if (this_line_is_command) { - if (!skip_rest_of_patch) - fputs(buf, pipefp); - if (*t != 'd') { - while (pgets(buf, sizeof buf, pfp) != Nullch) { - p_input_line++; - if (!skip_rest_of_patch) - fputs(buf, pipefp); - if (strEQ(buf, ".\n")) - break; - } - } - } - else { - next_intuit_at(beginning_of_this_line,p_input_line); - break; - } - } - if (skip_rest_of_patch) - return; - fprintf(pipefp, "w\n"); - fprintf(pipefp, "q\n"); - Fflush(pipefp); - Pclose(pipefp); - ignore_signals(); - if (move_file(TMPOUTNAME, outname) < 0) { - toutkeep = TRUE; - chmod(TMPOUTNAME, filemode); - } - else - chmod(outname, filemode); - set_signals(); -} diff --git a/usr.bin/patch/pch.h b/usr.bin/patch/pch.h deleted file mode 100644 index 97a5b28..0000000 --- a/usr.bin/patch/pch.h +++ /dev/null @@ -1,36 +0,0 @@ -/* $Header: pch.h,v 2.0.1.1 87/01/30 22:47:16 lwall Exp $ - * - * $Log: pch.h,v $ - * Revision 2.0.1.1 87/01/30 22:47:16 lwall - * Added do_ed_script(). - * - * Revision 2.0 86/09/17 15:39:57 lwall - * Baseline for netwide release. - * - */ - -EXT FILE *pfp INIT(Nullfp); /* patch file pointer */ - -void re_patch(); -void open_patch_file(); -void set_hunkmax(); -void grow_hunkmax(); -bool there_is_another_patch(); -int intuit_diff_type(); -void next_intuit_at(); -void skip_to(); -bool another_hunk(); -bool pch_swap(); -char *pfetch(); -short pch_line_len(); -LINENUM pch_first(); -LINENUM pch_ptrn_lines(); -LINENUM pch_newfirst(); -LINENUM pch_repl_lines(); -LINENUM pch_end(); -LINENUM pch_context(); -LINENUM pch_hunk_beg(); -char pch_char(); -char *pfetch(); -char *pgets(); -void do_ed_script(); diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c deleted file mode 100644 index 5582d18..0000000 --- a/usr.bin/patch/util.c +++ /dev/null @@ -1,339 +0,0 @@ -#include "EXTERN.h" -#include "common.h" -#include "INTERN.h" -#include "util.h" - -/* 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) - fatal2("patch: internal error, can't reopen %s\n", from); - while ((i=read(fromfd, buf, sizeof buf)) > 0) - if (write(1, buf, i) != 1) - fatal1("patch: write failed\n"); - Close(fromfd); - return 0; - } - - Strcpy(bakname, to); - Strcat(bakname, origext?origext:ORIGEXT); - 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 */ - while (stat(bakname, &filestat) >= 0 && - to_device == filestat.st_dev && to_inode == filestat.st_ino) { - 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) { - say3("patch: can't backup %s, output is in %s\n", - to, from); - return -1; - } - 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) { - say3("patch: can't create %s, output is in %s.\n", - to, from); - return -1; - } - fromfd = open(from, 0); - if (fromfd < 0) - fatal2("patch: internal error, can't reopen %s\n", from); - while ((i=read(fromfd, buf, sizeof buf)) > 0) - if (write(tofd, buf, i) != i) - fatal1("patch: write failed\n"); - 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) - fatal2("patch: can't create %s.\n", to); - fromfd = open(from, 0); - if (fromfd < 0) - fatal2("patch: internal error, can't reopen %s\n", from); - while ((i=read(fromfd, buf, sizeof buf)) > 0) - if (write(tofd, buf, i) != i) - fatal2("patch: write (%s) failed\n", 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("patch: out of memory (savestr)\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*/ -ask(pat) char *pat; { ; } - -#else - -/* Vanilla terminal output (buffered). */ - -void -say(pat,arg1,arg2,arg3) -char *pat; -int 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; -int arg1,arg2,arg3; -{ - void my_exit(); - - say(pat, arg1, arg2, arg3); - my_exit(1); -} - -/* Get a response from the user, somehow or other. */ - -void -ask(pat,arg1,arg2,arg3) -char *pat; -int 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() -{ - void my_exit(); - -#ifndef lint - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) - Signal(SIGHUP, my_exit); - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - Signal(SIGINT, my_exit); -#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. */ - -void -makedirs(filename,striplast) -Reg1 char *filename; -bool striplast; -{ - char tmpbuf[256]; - Reg2 char *s = tmpbuf; - char *dirv[20]; - Reg3 int i; - Reg4 int dirvp = 0; - - 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++) { - while (*s) s++; - *s++ = ' '; - strcpy(s, tmpbuf); - *dirv[i] = '/'; - } - system(buf); -} - -/* Make filenames more reasonable. */ - -char * -fetchname(at,strip_leading,assume_exists) -char *at; -int strip_leading; -int assume_exists; -{ - char *s; - char *name; - Reg1 char *t; - char tmpbuf[200]; - - if (!at) - return Nullch; - s = savestr(at); - for (t=s; isspace(*t); t++) ; - name = t; -#ifdef DEBUGGING - if (debug & 128) - say4("fetchname %s %d %d\n",name,strip_leading,assume_exists); -#endif - if (strnEQ(name, "/dev/null", 9)) /* so files can be created by diffing */ - return Nullch; /* against /dev/null. */ - for (; *t && !isspace(*t); t++) - if (*t == '/') - if (--strip_leading >= 0) - name = t+1; - *t = '\0'; - if (name != s && *s != '/') { - name[-1] = '\0'; - if (stat(s, &filestat) && filestat.st_mode & S_IFDIR) { - name[-1] = '/'; - name=s; - } - } - name = savestr(name); - Sprintf(tmpbuf, "RCS/%s", name); - free(s); - if (stat(name, &filestat) < 0 && !assume_exists) { - Strcat(tmpbuf, RCSSUFFIX); - if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+4, &filestat) < 0) { - Sprintf(tmpbuf, "SCCS/%s%s", SCCSPREFIX, name); - if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+5, &filestat) < 0) { - free(name); - name = Nullch; - } - } - } - return name; -} diff --git a/usr.bin/patch/util.h b/usr.bin/patch/util.h deleted file mode 100644 index 9896c63..0000000 --- a/usr.bin/patch/util.h +++ /dev/null @@ -1,74 +0,0 @@ -/* $Header: util.h,v 2.0 86/09/17 15:40:06 lwall Exp $ - * - * $Log: util.h,v $ - * Revision 2.0 86/09/17 15:40:06 lwall - * Baseline for netwide release. - * - */ - -/* and for those machine that can't handle a variable argument list */ - -#ifdef CANVARARG - -#define say1 say -#define say2 say -#define say3 say -#define say4 say -#define ask1 ask -#define ask2 ask -#define ask3 ask -#define ask4 ask -#define fatal1 fatal -#define fatal2 fatal -#define fatal3 fatal -#define fatal4 fatal - -#else /* hope they allow multi-line macro actual arguments */ - -#ifdef lint - -#define say1(a) say(a, 0, 0, 0) -#define say2(a,b) say(a, (b)==(b), 0, 0) -#define say3(a,b,c) say(a, (b)==(b), (c)==(c), 0) -#define say4(a,b,c,d) say(a, (b)==(b), (c)==(c), (d)==(d)) -#define ask1(a) ask(a, 0, 0, 0) -#define ask2(a,b) ask(a, (b)==(b), 0, 0) -#define ask3(a,b,c) ask(a, (b)==(b), (c)==(c), 0) -#define ask4(a,b,c,d) ask(a, (b)==(b), (c)==(c), (d)==(d)) -#define fatal1(a) fatal(a, 0, 0, 0) -#define fatal2(a,b) fatal(a, (b)==(b), 0, 0) -#define fatal3(a,b,c) fatal(a, (b)==(b), (c)==(c), 0) -#define fatal4(a,b,c,d) fatal(a, (b)==(b), (c)==(c), (d)==(d)) - -#else /* lint */ - /* if this doesn't work, try defining CANVARARG above */ -#define say1(a) say(a, Nullch, Nullch, Nullch) -#define say2(a,b) say(a, b, Nullch, Nullch) -#define say3(a,b,c) say(a, b, c, Nullch) -#define say4 say -#define ask1(a) ask(a, Nullch, Nullch, Nullch) -#define ask2(a,b) ask(a, b, Nullch, Nullch) -#define ask3(a,b,c) ask(a, b, c, Nullch) -#define ask4 ask -#define fatal1(a) fatal(a, Nullch, Nullch, Nullch) -#define fatal2(a,b) fatal(a, b, Nullch, Nullch) -#define fatal3(a,b,c) fatal(a, b, c, Nullch) -#define fatal4 fatal - -#endif /* lint */ - -/* if neither of the above work, join all multi-line macro calls. */ -#endif - -EXT char serrbuf[BUFSIZ]; /* buffer for stderr */ - -char *fetchname(); -int move_file(); -void copy_file(); -void say(); -void fatal(); -void ask(); -char *savestr(); -void set_signals(); -void ignore_signals(); -void makedirs(); -- cgit v1.1