📄 patch.c
字号:
&& patch_match (first_guess, -offset, prefix_fuzz, suffix_fuzz)) { if (debug & 1) say ("Offset changing from %ld to %ld\n", last_offset, -offset); last_offset = -offset; return first_guess-offset; } } return 0;}/* We did not find the pattern, dump out the hunk so they can handle it. */static voidabort_hunk(){ register LINENUM i; register 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 const *stars = (int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ****" : ""; char const *minuses = (int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ----" : " -----"; 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 ' ': case '-': case '+': case '!': fprintf (rejfp, "%c ", pch_char (i)); /* fall into */ case '\n': pch_write_line (i, rejfp); break; default: fatal ("fatal internal error in abort_hunk"); } if (ferror (rejfp)) write_fatal (); }}/* We found where to apply it (we hope), so do it. */static boolapply_hunk (outstate, where) struct outstate *outstate; LINENUM where;{ register LINENUM old = 1; register LINENUM lastline = pch_ptrn_lines (); register LINENUM new = lastline+1; register enum {OUTSIDE, IN_IFNDEF, IN_IFDEF, IN_ELSE} def_state = OUTSIDE; register char const *R_do_defines = do_defines; register LINENUM pat_end = pch_end (); register FILE *fp = outstate->ofp; where--; while (pch_char(new) == '=' || pch_char(new) == '\n') new++; while (old <= lastline) { if (pch_char(old) == '-') { assert (outstate->after_newline); if (! copy_till (outstate, where + old - 1)) return FALSE; if (R_do_defines) { if (def_state == OUTSIDE) { fprintf (fp, outstate->after_newline + if_defined, R_do_defines); def_state = IN_IFNDEF; } else if (def_state == IN_IFDEF) { fprintf (fp, outstate->after_newline + else_defined); def_state = IN_ELSE; } if (ferror (fp)) write_fatal (); outstate->after_newline = pch_write_line (old, fp); outstate->zero_output = 0; } last_frozen_line++; old++; } else if (new > pat_end) { break; } else if (pch_char(new) == '+') { if (! copy_till (outstate, where + old - 1)) return FALSE; if (R_do_defines) { if (def_state == IN_IFNDEF) { fprintf (fp, outstate->after_newline + else_defined); def_state = IN_ELSE; } else if (def_state == OUTSIDE) { fprintf (fp, outstate->after_newline + if_defined, R_do_defines); def_state = IN_IFDEF; } if (ferror (fp)) write_fatal (); } outstate->after_newline = pch_write_line (new, fp); outstate->zero_output = 0; new++; } else if (pch_char(new) != pch_char(old)) { if (debug & 1) say ("oldchar = '%c', newchar = '%c'\n", pch_char (old), pch_char (new)); fatal ("Out-of-sync patch, lines %ld,%ld -- mangled text or line numbers, maybe?", pch_hunk_beg() + old, pch_hunk_beg() + new); } else if (pch_char(new) == '!') { assert (outstate->after_newline); if (! copy_till (outstate, where + old - 1)) return FALSE; assert (outstate->after_newline); if (R_do_defines) { fprintf (fp, not_defined, R_do_defines); if (ferror (fp)) write_fatal (); def_state = IN_IFNDEF; } do { if (R_do_defines) { outstate->after_newline = pch_write_line (old, fp); } last_frozen_line++; old++; } while (pch_char (old) == '!'); if (R_do_defines) { fprintf (fp, outstate->after_newline + else_defined); if (ferror (fp)) write_fatal (); def_state = IN_ELSE; } do { outstate->after_newline = pch_write_line (new, fp); new++; } while (pch_char (new) == '!'); outstate->zero_output = 0; } else { assert(pch_char(new) == ' '); old++; new++; if (R_do_defines && def_state != OUTSIDE) { fprintf (fp, outstate->after_newline + end_defined, R_do_defines); if (ferror (fp)) write_fatal (); outstate->after_newline = 1; def_state = OUTSIDE; } } } if (new <= pat_end && pch_char(new) == '+') { if (! copy_till (outstate, where + old - 1)) return FALSE; if (R_do_defines) { if (def_state == OUTSIDE) { fprintf (fp, outstate->after_newline + if_defined, R_do_defines); def_state = IN_IFDEF; } else if (def_state == IN_IFNDEF) { fprintf (fp, outstate->after_newline + else_defined); def_state = IN_ELSE; } if (ferror (fp)) write_fatal (); outstate->zero_output = 0; } do { if (! outstate->after_newline && putc ('\n', fp) == EOF) write_fatal (); outstate->after_newline = pch_write_line (new, fp); outstate->zero_output = 0; new++; } while (new <= pat_end && pch_char (new) == '+'); } if (R_do_defines && def_state != OUTSIDE) { fprintf (fp, outstate->after_newline + end_defined, R_do_defines); if (ferror (fp)) write_fatal (); outstate->after_newline = 1; } return TRUE;}/* Create an output file. */static FILE *create_output_file (name) char const *name;{ int fd = create_file (name, O_WRONLY | binary_transput, instat.st_mode); FILE *f = fdopen (fd, binary_transput ? "wb" : "w"); if (! f) pfatal ("can't create `%s'", name); return f;}/* Open the new file. */static voidinit_output (name, outstate) char const *name; struct outstate *outstate;{ outstate->ofp = name ? create_output_file (name) : (FILE *) 0; outstate->after_newline = 1; outstate->zero_output = 1;}/* Open a file to put hunks we can't locate. */static voidinit_reject(name) char const *name;{ rejfp = create_output_file (name);}/* Copy input file to output, up to wherever hunk is to be applied. */static boolcopy_till (outstate, lastline) register struct outstate *outstate; register LINENUM lastline;{ register LINENUM R_last_frozen_line = last_frozen_line; register FILE *fp = outstate->ofp; register char const *s; size_t size; if (R_last_frozen_line > lastline) { say ("misordered hunks! output would be garbled\n"); return FALSE; } while (R_last_frozen_line < lastline) { s = ifetch (++R_last_frozen_line, 0, &size); if (size) { if ((! outstate->after_newline && putc ('\n', fp) == EOF) || ! fwrite (s, sizeof *s, size, fp)) write_fatal (); outstate->after_newline = s[size - 1] == '\n'; outstate->zero_output = 0; } } last_frozen_line = R_last_frozen_line; return TRUE;}/* Finish copying the input file to the output file. */static boolspew_output (outstate) struct outstate *outstate;{ if (debug & 256) say ("il=%ld lfl=%ld\n", input_lines, last_frozen_line); if (last_frozen_line < input_lines) if (! copy_till (outstate, input_lines)) return FALSE; if (outstate->ofp && ! outfile) { if (fclose (outstate->ofp) != 0) write_fatal (); outstate->ofp = 0; } return TRUE;}/* Does the patch pattern match at line base+offset? */static boolpatch_match (base, offset, prefix_fuzz, suffix_fuzz)LINENUM base;LINENUM offset;LINENUM prefix_fuzz;LINENUM suffix_fuzz;{ register LINENUM pline = 1 + prefix_fuzz; register LINENUM iline; register LINENUM pat_lines = pch_ptrn_lines () - suffix_fuzz; size_t size; register char const *p; for (iline=base+offset+prefix_fuzz; pline <= pat_lines; pline++,iline++) { p = ifetch (iline, offset >= 0, &size); if (canonicalize) { if (!similar(p, size, pfetch(pline), pch_line_len(pline) )) return FALSE; } else if (size != pch_line_len (pline) || memcmp (p, pfetch (pline), size) != 0) return FALSE; } return TRUE;}/* Do two lines match with canonicalized white space? */static boolsimilar (a, alen, b, blen) register char const *a; register size_t alen; register char const *b; register size_t blen;{ /* Ignore presence or absence of trailing newlines. */ alen -= alen && a[alen - 1] == '\n'; blen -= blen && b[blen - 1] == '\n'; for (;;) { if (!blen || (*b == ' ' || *b == '\t')) { while (blen && (*b == ' ' || *b == '\t')) b++, blen--; if (alen) { if (!(*a == ' ' || *a == '\t')) return FALSE; do a++, alen--; while (alen && (*a == ' ' || *a == '\t')); } if (!alen || !blen) return alen == blen; } else if (!alen || *a++ != *b++) return FALSE; else alen--, blen--; }}/* Make a temporary file. */#if HAVE_MKTEMPchar *mktemp PARAMS ((char *));#endif#ifndef TMPDIR#define TMPDIR "/tmp"#endifstatic char const *make_temp (letter) int letter;{ char *r;#if HAVE_MKTEMP char const *tmpdir = getenv ("TMPDIR"); /* Unix tradition */ if (!tmpdir) tmpdir = getenv ("TMP"); /* DOS tradition */ if (!tmpdir) tmpdir = getenv ("TEMP"); /* another DOS tradition */ if (!tmpdir) tmpdir = TMPDIR; r = xmalloc (strlen (tmpdir) + 10); sprintf (r, "%s/p%cXXXXXX", tmpdir, letter); mktemp (r); if (!*r) pfatal ("mktemp");#else r = xmalloc (L_tmpnam); if (! (tmpnam (r) == r && *r)) pfatal ("tmpnam");#endif return r;}/* Fatal exit with cleanup. */voidfatal_exit (sig) int sig;{ cleanup (); if (sig) exit_with_signal (sig); exit (2);}static voidcleanup (){ unlink (TMPINNAME); unlink (TMPOUTNAME); unlink (TMPPATNAME); unlink (TMPREJNAME);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -