📄 patch.c
字号:
static voidreinitialize_almost_everything (void){ re_patch(); re_input(); input_lines = 0; last_frozen_line = 0; if (inname) { free (inname); inname = 0; } last_offset = 0; diff_type = NO_DIFF; if (revision) { free(revision); revision = 0; } reverse = reverse_flag_specified; skip_rest_of_patch = false;}static char const shortopts[] = "bB:cd:D:eEfF:g:i:lnNo:p:r:RstTuvV:x:Y:z:Z";static struct option const longopts[] ={ {"backup", no_argument, NULL, 'b'}, {"prefix", required_argument, NULL, 'B'}, {"context", no_argument, NULL, 'c'}, {"directory", required_argument, NULL, 'd'}, {"ifdef", required_argument, NULL, 'D'}, {"ed", no_argument, NULL, 'e'}, {"remove-empty-files", no_argument, NULL, 'E'}, {"force", no_argument, NULL, 'f'}, {"fuzz", required_argument, NULL, 'F'}, {"get", no_argument, NULL, 'g'}, {"input", required_argument, NULL, 'i'}, {"ignore-whitespace", no_argument, NULL, 'l'}, {"normal", no_argument, NULL, 'n'}, {"forward", no_argument, NULL, 'N'}, {"output", required_argument, NULL, 'o'}, {"strip", required_argument, NULL, 'p'}, {"reject-file", required_argument, NULL, 'r'}, {"reverse", no_argument, NULL, 'R'}, {"quiet", no_argument, NULL, 's'}, {"silent", no_argument, NULL, 's'}, {"batch", no_argument, NULL, 't'}, {"set-time", no_argument, NULL, 'T'}, {"unified", no_argument, NULL, 'u'}, {"version", no_argument, NULL, 'v'}, {"version-control", required_argument, NULL, 'V'}, {"debug", required_argument, NULL, 'x'}, {"basename-prefix", required_argument, NULL, 'Y'}, {"suffix", required_argument, NULL, 'z'}, {"set-utc", no_argument, NULL, 'Z'}, {"dry-run", no_argument, NULL, CHAR_MAX + 1}, {"verbose", no_argument, NULL, CHAR_MAX + 2}, {"binary", no_argument, NULL, CHAR_MAX + 3}, {"help", no_argument, NULL, CHAR_MAX + 4}, {"backup-if-mismatch", no_argument, NULL, CHAR_MAX + 5}, {"no-backup-if-mismatch", no_argument, NULL, CHAR_MAX + 6}, {"posix", no_argument, NULL, CHAR_MAX + 7}, {"quoting-style", required_argument, NULL, CHAR_MAX + 8}, {NULL, no_argument, NULL, 0}};static char const *const option_help[] ={"Input options:",""," -p NUM --strip=NUM Strip NUM leading components from file names."," -F LINES --fuzz LINES Set the fuzz factor to LINES for inexact matching."," -l --ignore-whitespace Ignore white space changes between patch and input.",""," -c --context Interpret the patch as a context difference."," -e --ed Interpret the patch as an ed script."," -n --normal Interpret the patch as a normal difference."," -u --unified Interpret the patch as a unified difference.",""," -N --forward Ignore patches that appear to be reversed or already applied."," -R --reverse Assume patches were created with old and new files swapped.",""," -i PATCHFILE --input=PATCHFILE Read patch from PATCHFILE instead of stdin.","","Output options:",""," -o FILE --output=FILE Output patched files to FILE."," -r FILE --reject-file=FILE Output rejects to FILE.",""," -D NAME --ifdef=NAME Make merged if-then-else output using NAME."," -E --remove-empty-files Remove output files that are empty after patching.",""," -Z --set-utc Set times of patched files, assuming diff uses UTC (GMT)."," -T --set-time Likewise, assuming local time.",""," --quoting-style=WORD output file names using quoting style WORD."," Valid WORDs are: literal, shell, shell-always, c, escape."," Default is taken from QUOTING_STYLE env variable, or 'shell' if unset.","","Backup and version control options:",""," -b --backup Back up the original contents of each file."," --backup-if-mismatch Back up if the patch does not match exactly."," --no-backup-if-mismatch Back up mismatches only if otherwise requested.",""," -V STYLE --version-control=STYLE Use STYLE version control."," STYLE is either 'simple', 'numbered', or 'existing'."," -B PREFIX --prefix=PREFIX Prepend PREFIX to backup file names."," -Y PREFIX --basename-prefix=PREFIX Prepend PREFIX to backup file basenames."," -z SUFFIX --suffix=SUFFIX Append SUFFIX to backup file names.",""," -g NUM --get=NUM Get files from RCS etc. if positive; ask if negative.","","Miscellaneous options:",""," -t --batch Ask no questions; skip bad-Prereq patches; assume reversed."," -f --force Like -t, but ignore bad-Prereq patches, and assume unreversed."," -s --quiet --silent Work silently unless an error occurs."," --verbose Output extra information about the work being done."," --dry-run Do not actually change any files; just print what would happen."," --posix Conform to the POSIX standard.",""," -d DIR --directory=DIR Change the working directory to DIR first.",#if HAVE_SETMODE_DOS" --binary Read and write data in binary mode.",#else" --binary Read and write data in binary mode (no effect on this platform).",#endif""," -v --version Output version info."," --help Output this help.","","Report bugs to <" PACKAGE_BUGREPORT ">.",0};static voidusage (FILE *stream, int status){ char const * const *p; if (status != 0) { fprintf (stream, "%s: Try `%s --help' for more information.\n", program_name, Argv[0]); } else { fprintf (stream, "Usage: %s [OPTION]... [ORIGFILE [PATCHFILE]]\n\n", Argv[0]); for (p = option_help; *p; p++) fprintf (stream, "%s\n", *p); } exit (status);}/* Process switches and filenames. */static voidget_some_switches (void){ register int optc; if (rejname) free (rejname); rejname = 0; if (optind == Argc) return; while ((optc = getopt_long (Argc, Argv, shortopts, longopts, (int *) 0)) != -1) { switch (optc) { case 'b': make_backups = true; /* Special hack for backward compatibility with CVS 1.9. If the last 4 args are `-b SUFFIX ORIGFILE PATCHFILE', treat `-b' as if it were `-b -z'. */ if (Argc - optind == 3 && strcmp (Argv[optind - 1], "-b") == 0 && ! (Argv[optind + 0][0] == '-' && Argv[optind + 0][1]) && ! (Argv[optind + 1][0] == '-' && Argv[optind + 1][1]) && ! (Argv[optind + 2][0] == '-' && Argv[optind + 2][1])) { optarg = Argv[optind++]; if (verbosity != SILENT) say ("warning: the `-b %s' option is obsolete; use `-b -z %s' instead\n", optarg, optarg); goto case_z; } break; case 'B': if (!*optarg) fatal ("backup prefix is empty"); origprae = savestr (optarg); break; case 'c': diff_type = CONTEXT_DIFF; break; case 'd': if (chdir(optarg) < 0) pfatal ("Can't change to directory %s", quotearg (optarg)); break; case 'D': do_defines = savestr (optarg); break; case 'e': diff_type = ED_DIFF; break; case 'E': remove_empty_files = true; break; case 'f': force = true; break; case 'F': maxfuzz = numeric_string (optarg, false, "fuzz factor"); break; case 'g': patch_get = numeric_string (optarg, true, "get option value"); break; case 'i': patchname = savestr (optarg); break; case 'l': canonicalize = true; break; case 'n': diff_type = NORMAL_DIFF; break; case 'N': noreverse = true; break; case 'o': if (strcmp (optarg, "-") == 0) fatal ("can't output patches to standard output"); outfile = savestr (optarg); break; case 'p': strippath = numeric_string (optarg, false, "strip count"); break; case 'r': rejname = savestr (optarg); break; case 'R': reverse = true; reverse_flag_specified = true; break; case 's': verbosity = SILENT; break; case 't': batch = true; break; case 'T': set_time = true; break; case 'u': diff_type = UNI_DIFF; break; case 'v': version(); exit (0); break; case 'V': version_control = optarg; version_control_context = "--version-control or -V option"; break;#if DEBUGGING case 'x': debug = numeric_string (optarg, true, "debugging option"); break;#endif case 'Y': if (!*optarg) fatal ("backup basename prefix is empty"); origbase = savestr (optarg); break; case 'z': case_z: if (!*optarg) fatal ("backup suffix is empty"); simple_backup_suffix = savestr (optarg); break; case 'Z': set_utc = true; break; case CHAR_MAX + 1: dry_run = true; break; case CHAR_MAX + 2: verbosity = VERBOSE; break; case CHAR_MAX + 3:#if HAVE_SETMODE_DOS binary_transput = O_BINARY;#endif break; case CHAR_MAX + 4: usage (stdout, 0); case CHAR_MAX + 5: backup_if_mismatch = true; break; case CHAR_MAX + 6: backup_if_mismatch = false; break; case CHAR_MAX + 7: posixly_correct = true; break; case CHAR_MAX + 8: { int i = argmatch (optarg, quoting_style_args, 0, 0); if (i < 0) { invalid_arg ("quoting style", optarg, i); usage (stderr, 2); } set_quoting_style ((struct quoting_options *) 0, (enum quoting_style) i); } break; default: usage (stderr, 2); } } /* Process any filename args. */ if (optind < Argc) { inname = savestr (Argv[optind++]); invc = -1; if (optind < Argc) { patchname = savestr (Argv[optind++]); if (optind < Argc) { fprintf (stderr, "%s: %s: extra operand\n", program_name, quotearg (Argv[optind])); usage (stderr, 2); } } }}/* Handle STRING (possibly negative if NEGATIVE_ALLOWED is nonzero) of type ARGTYPE_MSGID by converting it to an integer, returning the result. */static intnumeric_string (char const *string, bool negative_allowed, char const *argtype_msgid){ int value = 0; char const *p = string; int sign = *p == '-' ? -1 : 1; p += *p == '-' || *p == '+'; do { int v10 = value * 10; int digit = *p - '0'; int signed_digit = sign * digit; int next_value = v10 + signed_digit; if (9 < (unsigned) digit) fatal ("%s %s is not a number", argtype_msgid, quotearg (string)); if (v10 / 10 != value || (next_value < v10) != (signed_digit < 0)) fatal ("%s %s is too large", argtype_msgid, quotearg (string)); value = next_value; } while (*++p); if (value < 0 && ! negative_allowed) fatal ("%s %s is negative", argtype_msgid, quotearg (string)); return value;}/* Attempt to find the right place to apply this hunk of patch. */static LINENUMlocate_hunk (LINENUM fuzz){ register LINENUM first_guess = pch_first () + last_offset; register LINENUM offset; LINENUM pat_lines = pch_ptrn_lines(); LINENUM prefix_context = pch_prefix_context (); LINENUM suffix_context = pch_suffix_context (); LINENUM context = (prefix_context < suffix_context ? suffix_context : prefix_context); LINENUM prefix_fuzz = fuzz + prefix_context - context; LINENUM suffix_fuzz = fuzz + suffix_context - context; LINENUM max_where = input_lines - (pat_lines - suffix_fuzz) + 1; LINENUM min_where = last_frozen_line + 1 - (prefix_context - prefix_fuzz); LINENUM max_pos_offset = max_where - first_guess; LINENUM max_neg_offset = first_guess - min_where; LINENUM max_offset = (max_pos_offset < max_neg_offset ? max_neg_offset : max_pos_offset); if (!pat_lines) /* null range matches always */ return first_guess; /* Do not try lines <= 0. */ if (first_guess <= max_neg_offset) max_neg_offset = first_guess - 1; if (prefix_fuzz < 0) { /* Can only match start of file. */ if (suffix_fuzz < 0) /* Can only match entire file. */ if (pat_lines != input_lines || prefix_context < last_frozen_line) return 0; offset = 1 - first_guess; if (last_frozen_line <= prefix_context && offset <= max_pos_offset && patch_match (first_guess, offset, (LINENUM) 0, suffix_fuzz)) { last_offset += offset; return first_guess + offset; } else return 0; } if (suffix_fuzz < 0) { /* Can only match end of file. */ offset = first_guess - (input_lines - pat_lines + 1); if (offset <= max_neg_offset && patch_match (first_guess, -offset, prefix_fuzz, (LINENUM) 0)) { last_offset -= offset; return first_guess - offset; } else return 0; } for (offset = 0; offset <= max_offset; offset++) { char numbuf0[LINENUM_LENGTH_BOUND + 1]; char numbuf1[LINENUM_LENGTH_BOUND + 1]; if (offset <= max_pos_offset && patch_match (first_guess, offset, prefix_fuzz, suffix_fuzz)) { if (debug & 1) say ("Offset changing from %s to %s\n", format_linenum (numbuf0, last_offset), format_linenum (numbuf1, last_offset + offset)); last_offset += offset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -