diff options
author | ache <ache@FreeBSD.org> | 1998-01-04 20:25:29 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 1998-01-04 20:25:29 +0000 |
commit | 438e7809d9a5e4652a1c25b8bb102ed3dfc83e40 (patch) | |
tree | b510a25e5213b4bf7f0564a778758ba21b5ea77a /contrib/patch/pch.c | |
parent | 4b6324645f7223db0870236240d6e99eb4cda757 (diff) | |
download | FreeBSD-src-438e7809d9a5e4652a1c25b8bb102ed3dfc83e40.zip FreeBSD-src-438e7809d9a5e4652a1c25b8bb102ed3dfc83e40.tar.gz |
Raw import of patch 2.5
Diffstat (limited to 'contrib/patch/pch.c')
-rw-r--r-- | contrib/patch/pch.c | 80 |
1 files changed, 61 insertions, 19 deletions
diff --git a/contrib/patch/pch.c b/contrib/patch/pch.c index 64a627a..f5c0ce0 100644 --- a/contrib/patch/pch.c +++ b/contrib/patch/pch.c @@ -1,6 +1,6 @@ /* reading patches */ -/* $Id: pch.c,v 1.23 1997/06/17 06:52:12 eggert Exp $ */ +/* $Id: pch.c,v 1.26 1997/07/21 17:59:46 eggert Exp $ */ /* Copyright 1986, 1987, 1988 Larry Wall @@ -38,6 +38,7 @@ If not, write to the Free Software Foundation, static FILE *pfp; /* patch file pointer */ static int p_says_nonexistent[2]; /* [0] for old file, [1] for new; value is 0 for nonempty, 1 for empty, 2 for nonexistent */ +static int p_rfc934_nesting; /* RFC 934 nesting level */ static time_t p_timestamp[2]; /* timestamps in patch headers */ static off_t p_filesize; /* size of the patch file */ static LINENUM p_first; /* 1st line number */ @@ -67,11 +68,11 @@ enum nametype { OLD, NEW, INDEX, NONE }; static enum diff intuit_diff_type PARAMS ((void)); static enum nametype best_name PARAMS ((char * const *, int const *)); static int prefix_components PARAMS ((char *, int)); -static size_t pget_line PARAMS ((int)); +static size_t pget_line PARAMS ((int, int)); static size_t get_line PARAMS ((void)); static bool incomplete_line PARAMS ((void)); static bool grow_hunkmax PARAMS ((void)); -static void malformed PARAMS ((void)); +static void malformed PARAMS ((void)) __attribute__ ((noreturn)); static void next_intuit_at PARAMS ((file_offset, LINENUM)); static void skip_to PARAMS ((file_offset, LINENUM)); @@ -142,6 +143,8 @@ open_patch_file(filename) pfatal ("fstat"); } p_filesize = st.st_size; + if (p_filesize != (file_offset) p_filesize) + fatal ("patch file is too long"); next_intuit_at (file_pos, (LINENUM) 1); set_hunkmax(); } @@ -197,6 +200,8 @@ there_is_another_patch() say (p_base ? " Ignoring the trailing garbage.\ndone\n" : " I can't seem to find a patch in there anywhere.\n"); + if (! p_base && p_filesize) + fatal ("Only garbage was found in the patch input."); return FALSE; } if (skip_rest_of_patch) @@ -219,8 +224,13 @@ there_is_another_patch() if (p_indent) say ("(Patch is indented %d space%s.)\n", p_indent, p_indent==1?"":"s"); if (! inname) - say ("can't find file to patch at input line %ld\n", - p_sline); + { + say ("can't find file to patch at input line %ld\n", + p_sline); + say (strippath == INT_MAX + ? "Perhaps you should have used the -p or --strip option?\n" + : "Perhaps you used the wrong -p or --strip option?\n"); + } } skip_to(p_start,p_sline); @@ -286,6 +296,7 @@ intuit_diff_type() version_controlled[OLD] = -1; version_controlled[NEW] = -1; version_controlled[INDEX] = -1; + p_rfc934_nesting = 0; p_timestamp[OLD] = p_timestamp[NEW] = (time_t) -1; p_says_nonexistent[OLD] = p_says_nonexistent[NEW] = 0; Fseek (pfp, p_base, SEEK_SET); @@ -296,7 +307,7 @@ intuit_diff_type() stars_last_line = stars_this_line; this_line = file_tell (pfp); indent = 0; - if (! pget_line (0)) { + if (! pget_line (0, 0)) { if (first_command_line >= 0) { /* nothing but deletes!? */ p_start = first_command_line; @@ -307,8 +318,7 @@ intuit_diff_type() else { p_start = this_line; p_sline = p_input_line; - retval = NO_DIFF; - goto scan_exit; + return NO_DIFF; } } for (s = buf; *s == ' ' || *s == '\t' || *s == 'X'; s++) { @@ -328,8 +338,6 @@ intuit_diff_type() } if (!stars_last_line && strnEQ(s, "*** ", 4)) name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]); - else if (strnEQ(s, "--- ", 4)) - name[NEW] = fetchname (s+4, strippath, &p_timestamp[NEW]); else if (strnEQ(s, "+++ ", 4)) /* Swap with NEW below. */ name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]); @@ -349,7 +357,21 @@ intuit_diff_type() revision = savestr (revision); *t = oldc; } - } + } else + { + for (t = s; t[0] == '-' && t[1] == ' '; t += 2) + continue; + if (strnEQ(t, "--- ", 4)) + { + time_t timestamp = (time_t) -1; + name[NEW] = fetchname (t+4, strippath, ×tamp); + if (timestamp != (time_t) -1) + { + p_timestamp[NEW] = timestamp; + p_rfc934_nesting = (t - s) >> 1; + } + } + } if ((diff_type == NO_DIFF || diff_type == ED_DIFF) && first_command_line >= 0 && strEQ(s, ".\n") ) { @@ -1424,19 +1446,21 @@ another_hunk (difftype, rev) static size_t get_line () { - return pget_line (p_indent); + return pget_line (p_indent, p_rfc934_nesting); } /* Input a line from the patch file, worrying about indentation. Strip up to INDENT characters' worth of leading indentation. + Then remove up to RFC934_NESTING instances of leading "- ". Ignore any partial lines at end of input, but warn about them. Succeed if a line was read; it is terminated by "\n\0" for convenience. Return the number of characters read, including '\n' but not '\0'. Return -1 if we ran out of memory. */ static size_t -pget_line (indent) +pget_line (indent, rfc934_nesting) int indent; + int rfc934_nesting; { register FILE *fp = pfp; register int c; @@ -1465,6 +1489,23 @@ pget_line (indent) i = 0; b = buf; + + while (c == '-' && 0 <= --rfc934_nesting) + { + c = getc (fp); + if (c == EOF) + goto patch_ends_in_middle_of_line; + if (c != ' ') + { + i = 1; + b[0] = '-'; + break; + } + c = getc (fp); + if (c == EOF) + goto patch_ends_in_middle_of_line; + } + s = bufsize; for (;;) @@ -1487,17 +1528,18 @@ pget_line (indent) break; c = getc (fp); if (c == EOF) - { - if (ferror (fp)) - read_fatal (); - say ("patch unexpectedly ends in middle of line\n"); - return 0; - } + goto patch_ends_in_middle_of_line; } b[i] = '\0'; p_input_line++; return i; + + patch_ends_in_middle_of_line: + if (ferror (fp)) + read_fatal (); + say ("patch unexpectedly ends in middle of line\n"); + return 0; } static bool |