conslt32@ZEUS.UNL.EDU (Tim Russell) (08/04/89)
+-+-+-+ Beginning of part 4 +-+-+-+ X correct place to apply each hunk of the patch. As a first X guess, it takes the line number mentioned for the hunk, plus X or minus any offset used in applying the previous hunk. If X that is not the correct place, patch will scan both forwards X and backwards for a set of lines matching the context given X in the hunk. First patch looks for a place where all lines X of the context match. If no such place is found, and it's a X context diff, and the maximum fuzz factor is set to 1 or X more, then another scan takes place ignoring the first and X last line of context. If that fails, and the maximum fuzz X factor is set to 2 or more, the first two and last two lines X of context are ignored, and another scan is made. (The X default maximum fuzz factor is 2.) If patch cannot find a X place to install that hunk of the patch, it will put the X hunk out to a reject file, which normally is the name of the X X X XLOCAL 4.2 BSD 1 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X output file plus ".rej". (Note that the rejected hunk will X come out in context diff form whether the input patch was a X context diff or a normal diff. If the input was a normal X diff, many of the contexts will simply be null.) The line X numbers on the hunks in the reject file may be different X than in the patch file: they reflect the approximate loca- X tion patch thinks the failed hunks belong in the new file X rather than the old one. X X As each hunk is completed, you will be told whether the hunk X succeeded or failed, and which line (in the new file) patch X thought the hunk should go on. If this is different from X the line number specified in the diff you will be told the X offset. A single large offset MAY be an indication that a X hunk was installed in the wrong place. You will also be X told if a fuzz factor was used to make the match, in which X case you should also be slightly suspicious. X X If no original file is specified on the command line, patch X will try to figure out from the leading garbage what the X name of the file to edit is. In the header of a context X diff, the filename is found from lines beginning with "***" X or "---", with the shortest name of an existing file win- X ning. Only context diffs have lines like that, but if there X is an "Index:" line in the leading garbage, patch will try X to use the filename from that line. The context diff header X takes precedence over an Index line. If no filename can be X intuited from the leading garbage, you will be asked for the X name of the file to patch. X X (If the original file cannot be found, but a suitable SCCS X or RCS file is handy, patch will attempt to get or check out X the file.) X X Additionally, if the leading garbage contains a "Prereq: " X line, patch will take the first word from the prerequisites X line (normally a version number) and check the input file to X see if that word can be found. If not, patch will ask for X confirmation before proceeding. X X The upshot of all this is that you should be able to say, X while in a news interface, the following: X X `124 patch -d /usr/src/local/blurfl X X and patch a file in the blurfl directory directly from the X article containing the patch. X X If the patch file contains more than one patch, patch will X try to apply each of them as if they came from separate X patch files. This means, among other things, that it is X X X XLOCAL 4.2 BSD 2 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X assumed that the name of the file to patch must be deter- X mined for each diff listing, and that the garbage before X each diff listing will be examined for interesting things X such as filenames and revision level, as mentioned previ- X ously. You can give switches (and another original file X name) for the second and subsequent patches by separating X the corresponding argument lists by a '+'. (The argument X list for a second or subsequent patch may not specify a new X patch file, however.) X X Patch recognizes the following switches: X X -b causes the next argument to be interpreted as the X backup extension, to be used in place of ".orig". X X -c forces patch to interpret the patch file as a context X diff. X X -d causes patch to interpret the next argument as a direc- X tory, and cd to it before doing anything else. X X -D causes patch to use the "#ifdef...#endif" construct to X mark changes. The argument following will be used as X the differentiating symbol. Note that, unlike the C X compiler, there must be a space between the -D and the X argument. X X -e forces patch to interpret the patch file as an ed X script. X X -f forces patch to assume that the user knows exactly what X he or she is doing, and to not ask any questions. It X does not suppress commentary, however. Use -s for X that. X X -F<number> X sets the maximum fuzz factor. This switch only applied X to context diffs, and causes patch to ignore up to that X many lines in looking for places to install a hunk. X Note that a larger fuzz factor increases the odds of a X faulty patch. The default fuzz factor is 2, and it may X not be set to more than the number of lines of context X in the context diff, ordinarily 3. X X -l causes the pattern matching to be done loosely, in case X the tabs and spaces have been munged in your input X file. Any sequence of whitespace in the pattern line X will match any sequence in the input file. Normal X characters must still match exactly. Each line of the X context must still match a line in the input file. X X X X XLOCAL 4.2 BSD 3 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X -n forces patch to interpret the patch file as a normal X diff. X X -N causes patch to ignore patches that it thinks are X reversed or already applied. See also -R . X X -o causes the next argument to be interpreted as the out- X put file name. X X -p<number> X sets the pathname strip count, which controls how path- X names found in the patch file are treated, in case the X you keep your files in a different directory than the X person who sent out the patch. The strip count speci- X fies how many backslashes are to be stripped from the X front of the pathname. (Any intervening directory X names also go away.) For example, supposing the X filename in the patch file was X X /u/howard/src/blurfl/blurfl.c X X setting -p or -p0 gives the entire pathname unmodified, X -p1 gives X X u/howard/src/blurfl/blurfl.c X X without the leading slash, -p4 gives X X blurfl/blurfl.c X X and not specifying -p at all just gives you "blurfl.c". X Whatever you end up with is looked for either in the X current directory, or the directory specified by the -d X switch. X X -r causes the next argument to be interpreted as the X reject file name. X X -R tells patch that this patch was created with the old X and new files swapped. (Yes, I'm afraid that does hap- X pen occasionally, human nature being what it is.) Patch X will attempt to swap each hunk around before applying X it. Rejects will come out in the swapped format. The X -R switch will not work with ed diff scripts because X there is too little information to reconstruct the X reverse operation. X X If the first hunk of a patch fails, patch will reverse X the hunk to see if it can be applied that way. If it X can, you will be asked if you want to have the -R X switch set. If it can't, the patch will continue to be X X X XLOCAL 4.2 BSD 4 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X applied normally. (Note: this method cannot detect a X reversed patch if it is a normal diff and if the first X command is an append (i.e. it should have been a X delete) since appends always succeed, due to the fact X that a null context will match anywhere. Luckily, most X patches add or change lines rather than delete them, so X most reversed normal diffs will begin with a delete, X which will fail, triggering the heuristic.) X X -s makes patch do its work silently, unless an error X occurs. X X -S causes patch to ignore this patch from the patch file, X but continue on looking for the next patch in the file. X Thus X X patch -S + -S + <patchfile X X will ignore the first and second of three patches. X X -v causes patch to print out it's revision header and X patch level. X X -x<number> X sets internal debugging flags, and is of interest only X to patch patchers. X XENVIRONMENT X No environment variables are used by patch. X XFILES X /tmp/patch* X XSEE ALSO X diff(1) X XNOTES FOR PATCH SENDERS X There are several things you should bear in mind if you are X going to be sending out patches. First, you can save people X a lot of grief by keeping a patchlevel.h file which is X patched to increment the patch level as the first diff in X the patch file you send out. If you put a Prereq: line in X with the patch, it won't let them apply patches out of order X without some warning. Second, make sure you've specified X the filenames right, either in a context diff header, or X with an Index: line. If you are patching something in a X subdirectory, be sure to tell the patch user to specify a -p X switch as needed. Third, you can create a file by sending X out a diff that compares a null file to the file you want to X create. This will only work if the file you want to create X doesn't exist already in the target directory. Fourth, take X X X XLOCAL 4.2 BSD 5 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X care not to send out reversed patches, since it makes people X wonder whether they already applied the patch. Fifth, while X you may be able to get away with putting 582 diff listings X into one file, it is probably wiser to group related patches X into separate files in case something goes haywire. X XDIAGNOSTICS X Too many to list here, but generally indicative that patch X couldn't parse your patch file. X X The message "Hmm..." indicates that there is unprocessed X text in the patch file and that patch is attempting to X intuit whether there is a patch in that text and, if so, X what kind of patch it is. X XCAVEATS X Patch cannot tell if the line numbers are off in an ed X script, and can only detect bad line numbers in a normal X diff when it finds a "change" or a "delete" command. A con- X text diff using fuzz factor 3 may have the same problem. X Until a suitable interactive interface is added, you should X probably do a context diff in these cases to see if the X changes made sense. Of course, compiling without errors is X a pretty good indication that the patch worked, but not X always. X X Patch usually produces the correct results, even when it has X to do a lot of guessing. However, the results are X guaranteed to be correct only when the patch is applied to X exactly the same version of the file that the patch was gen- X erated from. X XBUGS X Could be smarter about partial matches, excessively deviant X offsets and swapped code, but that would take an extra pass. X X If code has been duplicated (for instance with #ifdef OLD- X CODE ... #else ... #endif), patch is incapable of patching X both versions, and, if it works at all, will likely patch X the wrong one, and tell you that it succeeded to boot. X X If you apply a patch you've already applied, patch will X think it is a reversed patch, and offer to un-apply the X patch. This could be construed as a feature. X X X X X X X X X X XLOCAL 4.2 BSD 6 X X X $ GOSUB UNPACK_FILE $ FILE_IS = "PATCHLEVEL.H" $ CHECKSUM_IS = 1781615383 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X#define PATCHLEVEL 9 $ GOSUB UNPACK_FILE $ FILE_IS = "PCH.C" $ CHECKSUM_IS = 830158556 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X/* $Header: pch.c,v 2.0.1.6 87/06/04 16:18:13 lwall Exp $ X * X * $Log:`009pch.c,v $ X * Revision 2.0.1.6 87/06/04 16:18:13 lwall X * pch_swap didn't swap p_bfake and p_efake. X *`032 X * Revision 2.0.1.5 87/01/30 22:47:42 lwall X * Improved responses to mangled patches. X *`032 X * Revision 2.0.1.4 87/01/05 16:59:53 lwall X * New-style context diffs caused double call to free(). X *`032 X * Revision 2.0.1.3 86/11/14 10:08:33 lwall X * Fixed problem where a long pattern wouldn't grow the hunk. X * Also restored p_input_line when backtracking so error messages are right. X *`032 X * Revision 2.0.1.2 86/11/03 17:49:52 lwall X * New-style delete triggers spurious assertion error. X *`032 X * Revision 2.0.1.1 86/10/29 15:52:08 lwall X * Could falsely report new-style context diff. X *`032 X * Revision 2.0 86/09/17 15:39:37 lwall X * Baseline for netwide release. X *`032 X */ X X#include "EXTERN.h" X#include "common.h" X#include "util.h" X#include "INTERN.h" X#include "pch.h" X X/* Patch (diff listing) abstract type. */ X Xstatic long p_filesize;`009`009`009/* size of the patch file */ Xstatic LINENUM p_first;`009`009`009/* 1st line number */ Xstatic LINENUM p_newfirst;`009`009/* 1st line number of replacement */ Xstatic LINENUM p_ptrn_lines;`009`009/* # lines in pattern */ Xstatic LINENUM p_repl_lines;`009`009/* # lines in replacement text */ Xstatic LINENUM p_end = -1;`009`009/* last line in hunk */ Xstatic LINENUM p_max;`009`009`009/* max allowed value of p_end */ Xstatic LINENUM p_context = 3;`009`009/* # of context lines */ Xstatic LINENUM p_input_line = 0;`009/* current line # from patch file */ Xstatic char **p_line = Null(char**);`009/* the text of the hunk */ -+-+-+-+-+ End of part 4 +-+-+-+-+-
fritz@unocss.UUCP (Tim Russell) (08/27/89)
+-+-+-+ Beginning of part 4 +-+-+-+ X correct place to apply each hunk of the patch. As a first X guess, it takes the line number mentioned for the hunk, plus X or minus any offset used in applying the previous hunk. If X that is not the correct place, patch will scan both forwards X and backwards for a set of lines matching the context given X in the hunk. First patch looks for a place where all lines X of the context match. If no such place is found, and it's a X context diff, and the maximum fuzz factor is set to 1 or X more, then another scan takes place ignoring the first and X last line of context. If that fails, and the maximum fuzz X factor is set to 2 or more, the first two and last two lines X of context are ignored, and another scan is made. (The X default maximum fuzz factor is 2.) If patch cannot find a X place to install that hunk of the patch, it will put the X hunk out to a reject file, which normally is the name of the X X X XLOCAL 4.2 BSD 1 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X output file plus ".rej". (Note that the rejected hunk will X come out in context diff form whether the input patch was a X context diff or a normal diff. If the input was a normal X diff, many of the contexts will simply be null.) The line X numbers on the hunks in the reject file may be different X than in the patch file: they reflect the approximate loca- X tion patch thinks the failed hunks belong in the new file X rather than the old one. X X As each hunk is completed, you will be told whether the hunk X succeeded or failed, and which line (in the new file) patch X thought the hunk should go on. If this is different from X the line number specified in the diff you will be told the X offset. A single large offset MAY be an indication that a X hunk was installed in the wrong place. You will also be X told if a fuzz factor was used to make the match, in which X case you should also be slightly suspicious. X X If no original file is specified on the command line, patch X will try to figure out from the leading garbage what the X name of the file to edit is. In the header of a context X diff, the filename is found from lines beginning with "***" X or "---", with the shortest name of an existing file win- X ning. Only context diffs have lines like that, but if there X is an "Index:" line in the leading garbage, patch will try X to use the filename from that line. The context diff header X takes precedence over an Index line. If no filename can be X intuited from the leading garbage, you will be asked for the X name of the file to patch. X X (If the original file cannot be found, but a suitable SCCS X or RCS file is handy, patch will attempt to get or check out X the file.) X X Additionally, if the leading garbage contains a "Prereq: " X line, patch will take the first word from the prerequisites X line (normally a version number) and check the input file to X see if that word can be found. If not, patch will ask for X confirmation before proceeding. X X The upshot of all this is that you should be able to say, X while in a news interface, the following: X X `124 patch -d /usr/src/local/blurfl X X and patch a file in the blurfl directory directly from the X article containing the patch. X X If the patch file contains more than one patch, patch will X try to apply each of them as if they came from separate X patch files. This means, among other things, that it is X X X XLOCAL 4.2 BSD 2 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X assumed that the name of the file to patch must be deter- X mined for each diff listing, and that the garbage before X each diff listing will be examined for interesting things X such as filenames and revision level, as mentioned previ- X ously. You can give switches (and another original file X name) for the second and subsequent patches by separating X the corresponding argument lists by a '+'. (The argument X list for a second or subsequent patch may not specify a new X patch file, however.) X X Patch recognizes the following switches: X X -b causes the next argument to be interpreted as the X backup extension, to be used in place of ".orig". X X -c forces patch to interpret the patch file as a context X diff. X X -d causes patch to interpret the next argument as a direc- X tory, and cd to it before doing anything else. X X -D causes patch to use the "#ifdef...#endif" construct to X mark changes. The argument following will be used as X the differentiating symbol. Note that, unlike the C X compiler, there must be a space between the -D and the X argument. X X -e forces patch to interpret the patch file as an ed X script. X X -f forces patch to assume that the user knows exactly what X he or she is doing, and to not ask any questions. It X does not suppress commentary, however. Use -s for X that. X X -F<number> X sets the maximum fuzz factor. This switch only applied X to context diffs, and causes patch to ignore up to that X many lines in looking for places to install a hunk. X Note that a larger fuzz factor increases the odds of a X faulty patch. The default fuzz factor is 2, and it may X not be set to more than the number of lines of context X in the context diff, ordinarily 3. X X -l causes the pattern matching to be done loosely, in case X the tabs and spaces have been munged in your input X file. Any sequence of whitespace in the pattern line X will match any sequence in the input file. Normal X characters must still match exactly. Each line of the X context must still match a line in the input file. X X X X XLOCAL 4.2 BSD 3 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X -n forces patch to interpret the patch file as a normal X diff. X X -N causes patch to ignore patches that it thinks are X reversed or already applied. See also -R . X X -o causes the next argument to be interpreted as the out- X put file name. X X -p<number> X sets the pathname strip count, which controls how path- X names found in the patch file are treated, in case the X you keep your files in a different directory than the X person who sent out the patch. The strip count speci- X fies how many backslashes are to be stripped from the X front of the pathname. (Any intervening directory X names also go away.) For example, supposing the X filename in the patch file was X X /u/howard/src/blurfl/blurfl.c X X setting -p or -p0 gives the entire pathname unmodified, X -p1 gives X X u/howard/src/blurfl/blurfl.c X X without the leading slash, -p4 gives X X blurfl/blurfl.c X X and not specifying -p at all just gives you "blurfl.c". X Whatever you end up with is looked for either in the X current directory, or the directory specified by the -d X switch. X X -r causes the next argument to be interpreted as the X reject file name. X X -R tells patch that this patch was created with the old X and new files swapped. (Yes, I'm afraid that does hap- X pen occasionally, human nature being what it is.) Patch X will attempt to swap each hunk around before applying X it. Rejects will come out in the swapped format. The X -R switch will not work with ed diff scripts because X there is too little information to reconstruct the X reverse operation. X X If the first hunk of a patch fails, patch will reverse X the hunk to see if it can be applied that way. If it X can, you will be asked if you want to have the -R X switch set. If it can't, the patch will continue to be X X X XLOCAL 4.2 BSD 4 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X applied normally. (Note: this method cannot detect a X reversed patch if it is a normal diff and if the first X command is an append (i.e. it should have been a X delete) since appends always succeed, due to the fact X that a null context will match anywhere. Luckily, most X patches add or change lines rather than delete them, so X most reversed normal diffs will begin with a delete, X which will fail, triggering the heuristic.) X X -s makes patch do its work silently, unless an error X occurs. X X -S causes patch to ignore this patch from the patch file, X but continue on looking for the next patch in the file. X Thus X X patch -S + -S + <patchfile X X will ignore the first and second of three patches. X X -v causes patch to print out it's revision header and X patch level. X X -x<number> X sets internal debugging flags, and is of interest only X to patch patchers. X XENVIRONMENT X No environment variables are used by patch. X XFILES X /tmp/patch* X XSEE ALSO X diff(1) X XNOTES FOR PATCH SENDERS X There are several things you should bear in mind if you are X going to be sending out patches. First, you can save people X a lot of grief by keeping a patchlevel.h file which is X patched to increment the patch level as the first diff in X the patch file you send out. If you put a Prereq: line in X with the patch, it won't let them apply patches out of order X without some warning. Second, make sure you've specified X the filenames right, either in a context diff header, or X with an Index: line. If you are patching something in a X subdirectory, be sure to tell the patch user to specify a -p X switch as needed. Third, you can create a file by sending X out a diff that compares a null file to the file you want to X create. This will only work if the file you want to create X doesn't exist already in the target directory. Fourth, take X X X XLOCAL 4.2 BSD 5 X X X X X X X XPATCH(1) UNIX Programmer's Manual PATCH(1) X X X X care not to send out reversed patches, since it makes people X wonder whether they already applied the patch. Fifth, while X you may be able to get away with putting 582 diff listings X into one file, it is probably wiser to group related patches X into separate files in case something goes haywire. X XDIAGNOSTICS X Too many to list here, but generally indicative that patch X couldn't parse your patch file. X X The message "Hmm..." indicates that there is unprocessed X text in the patch file and that patch is attempting to X intuit whether there is a patch in that text and, if so, X what kind of patch it is. X XCAVEATS X Patch cannot tell if the line numbers are off in an ed X script, and can only detect bad line numbers in a normal X diff when it finds a "change" or a "delete" command. A con- X text diff using fuzz factor 3 may have the same problem. X Until a suitable interactive interface is added, you should X probably do a context diff in these cases to see if the X changes made sense. Of course, compiling without errors is X a pretty good indication that the patch worked, but not X always. X X Patch usually produces the correct results, even when it has X to do a lot of guessing. However, the results are X guaranteed to be correct only when the patch is applied to X exactly the same version of the file that the patch was gen- X erated from. X XBUGS X Could be smarter about partial matches, excessively deviant X offsets and swapped code, but that would take an extra pass. X X If code has been duplicated (for instance with #ifdef OLD- X CODE ... #else ... #endif), patch is incapable of patching X both versions, and, if it works at all, will likely patch X the wrong one, and tell you that it succeeded to boot. X X If you apply a patch you've already applied, patch will X think it is a reversed patch, and offer to un-apply the X patch. This could be construed as a feature. X X X X X X X X X X XLOCAL 4.2 BSD 6 X X X $ GOSUB UNPACK_FILE $ FILE_IS = "PATCHLEVEL.H" $ CHECKSUM_IS = 1781615383 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X#define PATCHLEVEL 9 $ GOSUB UNPACK_FILE $ FILE_IS = "PCH.C" $ CHECKSUM_IS = 830158556 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X/* $Header: pch.c,v 2.0.1.6 87/06/04 16:18:13 lwall Exp $ X * X * $Log:`009pch.c,v $ X * Revision 2.0.1.6 87/06/04 16:18:13 lwall X * pch_swap didn't swap p_bfake and p_efake. X *`032 X * Revision 2.0.1.5 87/01/30 22:47:42 lwall X * Improved responses to mangled patches. X *`032 X * Revision 2.0.1.4 87/01/05 16:59:53 lwall X * New-style context diffs caused double call to free(). X *`032 X * Revision 2.0.1.3 86/11/14 10:08:33 lwall X * Fixed problem where a long pattern wouldn't grow the hunk. X * Also restored p_input_line when backtracking so error messages are right. X *`032 X * Revision 2.0.1.2 86/11/03 17:49:52 lwall X * New-style delete triggers spurious assertion error. X *`032 X * Revision 2.0.1.1 86/10/29 15:52:08 lwall X * Could falsely report new-style context diff. X *`032 X * Revision 2.0 86/09/17 15:39:37 lwall X * Baseline for netwide release. X *`032 X */ X X#include "EXTERN.h" X#include "common.h" X#include "util.h" X#include "INTERN.h" X#include "pch.h" X X/* Patch (diff listing) abstract type. */ X Xstatic long p_filesize;`009`009`009/* size of the patch file */ Xstatic LINENUM p_first;`009`009`009/* 1st line number */ Xstatic LINENUM p_newfirst;`009`009/* 1st line number of replacement */ Xstatic LINENUM p_ptrn_lines;`009`009/* # lines in pattern */ Xstatic LINENUM p_repl_lines;`009`009/* # lines in replacement text */ Xstatic LINENUM p_end = -1;`009`009/* last line in hunk */ Xstatic LINENUM p_max;`009`009`009/* max allowed value of p_end */ Xstatic LINENUM p_context = 3;`009`009/* # of context lines */ Xstatic LINENUM p_input_line = 0;`009/* current line # from patch file */ Xstatic char **p_line = Null(char**);`009/* the text of the hunk */ -+-+-+-+-+ End of part 4 +-+-+-+-+- -- ---------------------------------+-------------------------------------------- Tim Russell, Computer Operator | Internet: russell@zeus.unl.edu Campus Computing | Bitnet: russell@unoma1 University of Nebraska at Omaha | UUCP: uunet!zeus.unl.edu!russell