Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site sdcrdcf.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!decvax!ittvax!dcdwest!sdcsvax!sdcrdcf!lwall From: lwall@sdcrdcf.UUCP (Larry Wall) Newsgroups: net.sources.bugs Subject: patch bug #2 Message-ID: <1532@sdcrdcf.UUCP> Date: Wed, 5-Dec-84 14:33:25 EST Article-I.D.: sdcrdcf.1532 Posted: Wed Dec 5 14:33:25 1984 Date-Received: Fri, 7-Dec-84 06:04:28 EST Reply-To: lwall@sdcrdcf.UUCP (Larry Wall) Organization: System Development Corp. R+D, Santa Monica Lines: 257 System: patch version 1.2 Bug #: 2 Priority: MEDIUM Subject: patch won't work on files with munged whitespace Description: Patch uses a strncmp to match context lines with the input file. This works as long as the input file hasn't been munged by an editor or some other program that translates spaces to tabs or tabs to spaces. Repeat-By: Run a source file through expand(1), and then try to do a patch on it. Fix: Add a -l switch to do "loose" string comparison. From rn, say "| patch -d DIR", where DIR is your patch source directory. Outside of rn, say "cd DIR; patch= 0)), pfetch(pline), pch_line_len(pline) )) return FALSE; --- 709,721 ----- register LINENUM pat_lines = pch_ptrn_lines(); for (pline = 1, iline=base+offset; 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; *************** *** 707,712 return FALSE; } return TRUE; } /* input file with indexable lines abstract type */ --- 721,753 ----- return FALSE; } return TRUE; + } + + /* match two lines with canonicalized white space */ + + bool + similar(a,b,len) + register char *a, *b; + register 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 */ } /* input file with indexable lines abstract type */ Index: patch.nr *************** *** 1,4 ! ''' $Header:$ ''' ''' $Log:$ .de Sh --- 1,4 ----- ! ''' $Header: patch.nr,v 1.2.1.2 84/12/05 11:06:55 lwall Exp $ ''' ''' $Log: patch.nr,v $ ''' Revision 1.2.1.2 84/12/05 11:06:55 lwall *************** *** 1,6 ''' $Header:$ ''' ! ''' $Log:$ .de Sh .br .ne 5 --- 1,15 ----- ''' $Header: patch.nr,v 1.2.1.2 84/12/05 11:06:55 lwall Exp $ ''' ! ''' $Log: patch.nr,v $ ! ''' 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 *************** *** 175,180 .I patch to interpret the patch file as an ed script. .TP 5 .B \-n forces .I patch --- 184,197 ----- .I patch to interpret the patch file as an ed script. .TP 5 + .B \-l + causes the pattern matching to be done loosely, in case the tabs and + spaces have been munged in you 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 *************** *** 251,253 .SH BUGS Could be smarter about partial matches, excessively \&deviant offsets and swapped code, but that would take an extra pass. --- 268,275 ----- .SH BUGS Could be smarter about partial matches, excessively \&deviant offsets and swapped code, but that would take an extra pass. + .PP + If you apply a patch you've already applied, + .I patch + will think it is a reversed patch, and un-apply the patch. + This could be construed as a feature.