toybox

changeset 362:d15520819347

Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
author Rob Landley <rob@landley.net>
date Sun, 29 Nov 2009 22:14:06 -0600
parents e5b5c6293f58
children 2428870ce50c
files toys/patch.c
diffstat 1 files changed, 40 insertions(+), 33 deletions(-) [+]
line diff
     1.1 --- a/toys/patch.c	Fri Oct 23 17:42:13 2009 -0500
     1.2 +++ b/toys/patch.c	Sun Nov 29 22:14:06 2009 -0600
     1.3 @@ -50,7 +50,7 @@
     1.4  	char *infile;
     1.5  	long prefix;
     1.6  
     1.7 -	struct double_list *plines, *flines;
     1.8 +	struct double_list *current_hunk;
     1.9  	long oldline, oldlen, newline, newlen, linenum;
    1.10  	int context, state, filein, fileout, filepatch, hunknum;
    1.11  	char *tempname;
    1.12 @@ -88,18 +88,18 @@
    1.13  
    1.14  static void fail_hunk(void)
    1.15  {
    1.16 -	if (!TT.plines) return;
    1.17 -	TT.plines->prev->next = 0;
    1.18 +	if (!TT.current_hunk) return;
    1.19 +	TT.current_hunk->prev->next = 0;
    1.20  
    1.21 -	fdprintf(2, "Hunk %d FAILED.\n", TT.hunknum);
    1.22 +	fdprintf(2, "Hunk %d FAILED %ld/%ld.\n", TT.hunknum, TT.oldline, TT.newline);
    1.23  	toys.exitval = 1;
    1.24  
    1.25  	// If we got to this point, we've seeked to the end.  Discard changes to
    1.26  	// this file and advance to next file.
    1.27  
    1.28  	TT.state = 2;
    1.29 -	llist_free(TT.plines, do_line);
    1.30 -	TT.plines = NULL;
    1.31 +	llist_free(TT.current_hunk, do_line);
    1.32 +	TT.current_hunk = NULL;
    1.33  	delete_tempfile(TT.filein, TT.fileout, &TT.tempname);
    1.34  	TT.state = 0;
    1.35  }
    1.36 @@ -107,38 +107,38 @@
    1.37  static int apply_hunk(void)
    1.38  {
    1.39  	struct double_list *plist, *buf = NULL, *check;
    1.40 -	int i = 0, backwards = 0, matcheof = 0,
    1.41 -		reverse = toys.optflags & FLAG_REVERSE;
    1.42 +	int matcheof = 0, reverse = toys.optflags & FLAG_REVERSE, backwarn = 0;
    1.43  
    1.44  	// Break doubly linked list so we can use singly linked traversal function.
    1.45 -	TT.plines->prev->next = NULL;
    1.46 +	TT.current_hunk->prev->next = NULL;
    1.47  
    1.48  	// Match EOF if there aren't as many ending context lines as beginning
    1.49 -	for (plist = TT.plines; plist; plist = plist->next) {
    1.50 -		if (plist->data[0]==' ') i++;
    1.51 -		else i = 0;
    1.52 +	for (plist = TT.current_hunk; plist; plist = plist->next) {
    1.53 +		if (plist->data[0]==' ') matcheof++;
    1.54 +		else matcheof = 0;
    1.55  	}
    1.56 -	if (i < TT.context) matcheof++;
    1.57 +	matcheof = matcheof < TT.context;
    1.58  
    1.59 -	// Search for a place to apply this hunk.  Match all context lines and
    1.60 -	// lines to be removed.
    1.61 -	plist = TT.plines;
    1.62 +	// Loop through input data searching for this hunk.  Match all context
    1.63 +	// lines and all lines to be removed until we've found the end of a
    1.64 +	// complete hunk.
    1.65 +	plist = TT.current_hunk;
    1.66  	buf = NULL;
    1.67 -	i = 0;
    1.68 -
    1.69 -	// Start of for loop
    1.70  	if (TT.context) for (;;) {
    1.71  		char *data = get_line(TT.filein);
    1.72  
    1.73  		TT.linenum++;
    1.74  
    1.75 -		// Skip lines of the hunk we'd be adding.
    1.76 +		// Figure out which line of hunk to compare with next.  (Skip lines
    1.77 +		// of the hunk we'd be adding.)
    1.78  		while (plist && *plist->data == "+-"[reverse]) {
    1.79  			if (data && !strcmp(data, plist->data+1)) {
    1.80 -				if (++backwards == TT.context)
    1.81 +				if (!backwarn) {
    1.82  					fdprintf(2,"Possibly reversed hunk %d at %ld\n",
    1.83  						TT.hunknum, TT.linenum);
    1.84 -			} else backwards=0;
    1.85 +					backwarn++;
    1.86 +				}
    1.87 +			}
    1.88  			plist = plist->next;
    1.89  		}
    1.90  
    1.91 @@ -153,23 +153,30 @@
    1.92  		}
    1.93  		check = dlist_add(&buf, data);
    1.94  
    1.95 +		// Compare this line with next expected line of hunk.
    1.96  		// todo: teach the strcmp() to ignore whitespace.
    1.97  
    1.98 +		// A match can fail because the next line doesn't match, or because
    1.99 +		// we hit the end of a hunk that needed EOF, and this isn't EOF.
   1.100 +
   1.101 +		// If match failed, flush first line of buffered data and
   1.102 +		// recheck buffered data for a new match until we find one or run
   1.103 +		// out of buffer.
   1.104 +
   1.105  		for (;;) {
   1.106 -			// If we hit the end of a hunk that needed EOF and this isn't EOF,
   1.107 -			// or next line doesn't match, flush first line of buffered data and
   1.108 -			// recheck match until we find a new match or run out of buffer.
   1.109 +			if (!plist || strcmp(check->data, plist->data+1)) {
   1.110 +				// Match failed.  Write out first line of buffered data and
   1.111 +				// recheck remaining buffered data for a new match.
   1.112  	
   1.113 -			if (!plist || strcmp(check->data, plist->data+1)) {
   1.114 -				// First line isn't a match, write it out.
   1.115  				TT.state = 3;
   1.116  				check = llist_pop(&buf);
   1.117  				check->prev->next = buf;
   1.118  				buf->prev = check->prev;
   1.119  				do_line(check);
   1.120 -				plist = TT.plines;
   1.121 +				plist = TT.current_hunk;
   1.122  
   1.123 -				// Out of buffered lines?
   1.124 +				// If we've reached the end of the buffer without confirming a
   1.125 +				// match, read more lines.
   1.126  				if (check==buf) {
   1.127  					buf = 0;
   1.128  					break;
   1.129 @@ -185,10 +192,10 @@
   1.130  		}
   1.131  	}
   1.132  out:
   1.133 -	// Got it.  Emit changed data.
   1.134 +	// We have a match.  Emit changed data.
   1.135  	TT.state = "-+"[reverse];
   1.136 -	llist_free(TT.plines, do_line);
   1.137 -	TT.plines = NULL;
   1.138 +	llist_free(TT.current_hunk, do_line);
   1.139 +	TT.current_hunk = NULL;
   1.140  	TT.state = 1;
   1.141  done:
   1.142  	if (buf) {
   1.143 @@ -229,7 +236,7 @@
   1.144  		// Are we assembling a hunk?
   1.145  		if (state >= 2) {
   1.146  			if (*patchline==' ' || *patchline=='+' || *patchline=='-') {
   1.147 -				dlist_add(&TT.plines, patchline);
   1.148 +				dlist_add(&TT.current_hunk, patchline);
   1.149  
   1.150  				if (*patchline != '+') TT.oldlen--;
   1.151  				if (*patchline != '-') TT.newlen--;