📄 diff.c
字号:
specify_value (&starting_file, optarg, "-S"); break; case 't': expand_tabs = true; break; case 'T': initial_tab = true; break; case 'u': specify_style (OUTPUT_UNIFIED); if (context < 3) context = 3; break; case 'v': version_etc (stdout, "diff", PACKAGE_NAME, PACKAGE_VERSION, "Paul Eggert", "Mike Haertel", "David Hayes", "Richard Stallman", "Len Tower", (char *) 0); check_stdout (); return EXIT_SUCCESS; case 'w': ignore_white_space = IGNORE_ALL_SPACE; break; case 'x': add_exclude (excluded, optarg, exclude_options ()); break; case 'X': if (add_exclude_file (add_exclude, excluded, optarg, exclude_options (), '\n')) pfatal_with_name (optarg); break; case 'y': specify_style (OUTPUT_SDIFF); break; case 'W': numval = strtoumax (optarg, &numend, 10); if (! (0 < numval && numval <= SIZE_MAX) || *numend) try_help ("invalid width `%s'", optarg); if (width != numval) { if (width) fatal ("conflicting width options"); width = numval; } break; case BINARY_OPTION:#if HAVE_SETMODE_DOS binary = true; set_binary_mode (STDOUT_FILENO, true);#endif break; case FROM_FILE_OPTION: specify_value (&from_file, optarg, "--from-file"); break; case HELP_OPTION: usage (); check_stdout (); return EXIT_SUCCESS; case HORIZON_LINES_OPTION: numval = strtoumax (optarg, &numend, 10); if (*numend) try_help ("invalid horizon length `%s'", optarg); horizon_lines = MAX (horizon_lines, MIN (numval, LIN_MAX)); break; case IGNORE_FILE_NAME_CASE_OPTION: ignore_file_name_case = true; break; case INHIBIT_HUNK_MERGE_OPTION: /* This option is obsolete, but accept it for backward compatibility. */ break; case LEFT_COLUMN_OPTION: left_column = true; break; case LINE_FORMAT_OPTION: specify_style (OUTPUT_IFDEF); for (i = 0; i < sizeof line_format / sizeof *line_format; i++) specify_value (&line_format[i], optarg, "--line-format"); break; case NO_IGNORE_FILE_NAME_CASE_OPTION: ignore_file_name_case = false; break; case NORMAL_OPTION: specify_style (OUTPUT_NORMAL); break; case SDIFF_MERGE_ASSIST_OPTION: specify_style (OUTPUT_SDIFF); sdiff_merge_assist = true; break; case STRIP_TRAILING_CR_OPTION: strip_trailing_cr = true; break; case SUPPRESS_COMMON_LINES_OPTION: suppress_common_lines = true; break; case TABSIZE_OPTION: numval = strtoumax (optarg, &numend, 10); if (! (0 < numval && numval <= SIZE_MAX) || *numend) try_help ("invalid tabsize `%s'", optarg); if (tabsize != numval) { if (tabsize) fatal ("conflicting tabsize options"); tabsize = numval; } break; case TO_FILE_OPTION: specify_value (&to_file, optarg, "--to-file"); break; case UNCHANGED_LINE_FORMAT_OPTION: case OLD_LINE_FORMAT_OPTION: case NEW_LINE_FORMAT_OPTION: specify_style (OUTPUT_IFDEF); c -= UNCHANGED_LINE_FORMAT_OPTION; specify_value (&line_format[c], optarg, line_format_option[c]); break; case UNCHANGED_GROUP_FORMAT_OPTION: case OLD_GROUP_FORMAT_OPTION: case NEW_GROUP_FORMAT_OPTION: case CHANGED_GROUP_FORMAT_OPTION: specify_style (OUTPUT_IFDEF); c -= UNCHANGED_GROUP_FORMAT_OPTION; specify_value (&group_format[c], optarg, group_format_option[c]); break; default: try_help (0, 0); } prev = c; } if (output_style == OUTPUT_UNSPECIFIED) { if (show_c_function) { specify_style (OUTPUT_CONTEXT); if (ocontext < 0) context = 3; } else specify_style (OUTPUT_NORMAL); } if (output_style != OUTPUT_CONTEXT || hard_locale (LC_TIME)) {#ifdef ST_MTIM_NSEC time_format = "%Y-%m-%d %H:%M:%S.%N %z";#else time_format = "%Y-%m-%d %H:%M:%S %z";#endif } else { /* See POSIX 1003.1-2001 for this format. */ time_format = "%a %b %e %T %Y"; } if (0 <= ocontext) { bool modern_usage = 200112 <= posix2_version (); if ((output_style == OUTPUT_CONTEXT || output_style == OUTPUT_UNIFIED) && (context < ocontext || (ocontext < context && ! explicit_context))) { if (modern_usage) { error (0, 0, _("`-%ld' option is obsolete; use `-%c %ld'"), (long int) ocontext, output_style == OUTPUT_CONTEXT ? 'C' : 'U', (long int) ocontext); try_help (0, 0); } context = ocontext; } else { if (modern_usage) { error (0, 0, _("`-%ld' option is obsolete; omit it"), (long int) ocontext); try_help (0, 0); } } } if (! tabsize) tabsize = 8; if (! width) width = 130; { /* Maximize first the half line width, and then the gutter width, according to the following constraints: 1. Two half lines plus a gutter must fit in a line. 2. If the half line width is nonzero: a. The gutter width is at least GUTTER_WIDTH_MINIMUM. b. If tabs are not expanded to spaces, a half line plus a gutter is an integral number of tabs, so that tabs in the right column line up. */ intmax_t t = expand_tabs ? 1 : tabsize; intmax_t w = width; intmax_t off = (w + t + GUTTER_WIDTH_MINIMUM) / (2 * t) * t; sdiff_half_width = MAX (0, MIN (off - GUTTER_WIDTH_MINIMUM, w - off)), sdiff_column2_offset = sdiff_half_width ? off : w; } /* Make the horizon at least as large as the context, so that shift_boundaries has more freedom to shift the first and last hunks. */ if (horizon_lines < context) horizon_lines = context; summarize_regexp_list (&function_regexp_list); summarize_regexp_list (&ignore_regexp_list); if (output_style == OUTPUT_IFDEF) { for (i = 0; i < sizeof line_format / sizeof *line_format; i++) if (!line_format[i]) line_format[i] = "%l\n"; if (!group_format[OLD]) group_format[OLD] = group_format[CHANGED] ? group_format[CHANGED] : "%<"; if (!group_format[NEW]) group_format[NEW] = group_format[CHANGED] ? group_format[CHANGED] : "%>"; if (!group_format[UNCHANGED]) group_format[UNCHANGED] = "%="; if (!group_format[CHANGED]) group_format[CHANGED] = concat (group_format[OLD], group_format[NEW], ""); } no_diff_means_no_output = (output_style == OUTPUT_IFDEF ? (!*group_format[UNCHANGED] || (strcmp (group_format[UNCHANGED], "%=") == 0 && !*line_format[UNCHANGED])) : (output_style != OUTPUT_SDIFF) | suppress_common_lines); files_can_be_treated_as_binary = (brief & binary & ~ (ignore_blank_lines | ignore_case | strip_trailing_cr | (ignore_regexp_list.regexps || ignore_white_space))); switch_string = option_list (argv + 1, optind - 1); if (from_file) { if (to_file) fatal ("--from-file and --to-file both specified"); else for (; optind < argc; optind++) { int status = compare_files ((struct comparison *) 0, from_file, argv[optind]); if (exit_status < status) exit_status = status; } } else { if (to_file) for (; optind < argc; optind++) { int status = compare_files ((struct comparison *) 0, argv[optind], to_file); if (exit_status < status) exit_status = status; } else { if (argc - optind != 2) { if (argc - optind < 2) try_help ("missing operand after `%s'", argv[argc - 1]); else try_help ("extra operand `%s'", argv[optind + 2]); } exit_status = compare_files ((struct comparison *) 0, argv[optind], argv[optind + 1]); } } /* Print any messages that were saved up for last. */ print_message_queue (); check_stdout (); exit (exit_status); return exit_status;}/* Append to REGLIST the regexp PATTERN. */static voidadd_regexp (struct regexp_list *reglist, char const *pattern){ size_t patlen = strlen (pattern); char const *m = re_compile_pattern (pattern, patlen, reglist->buf); if (m != 0) error (0, 0, "%s: %s", pattern, m); else { char *regexps = reglist->regexps; size_t len = reglist->len; bool multiple_regexps = reglist->multiple_regexps = regexps != 0; size_t newlen = reglist->len = len + 2 * multiple_regexps + patlen; size_t size = reglist->size; if (size <= newlen) { if (!size) size = 1; do size *= 2; while (size <= newlen); reglist->size = size; reglist->regexps = regexps = xrealloc (regexps, size); } if (multiple_regexps) { regexps[len++] = '\\'; regexps[len++] = '|'; } memcpy (regexps + len, pattern, patlen + 1); }}/* Ensure that REGLIST represents the disjunction of its regexps. This is done here, rather than earlier, to avoid O(N^2) behavior. */static voidsummarize_regexp_list (struct regexp_list *reglist){ if (reglist->regexps) { /* At least one regexp was specified. Allocate a fastmap for it. */ reglist->buf->fastmap = xmalloc (1 << CHAR_BIT); if (reglist->multiple_regexps) { /* Compile the disjunction of the regexps. (If just one regexp was specified, it is already compiled.) */ char const *m = re_compile_pattern (reglist->regexps, reglist->len, reglist->buf); if (m != 0) error (EXIT_TROUBLE, 0, "%s: %s", reglist->regexps, m); } }}static voidtry_help (char const *reason_msgid, char const *operand){ if (reason_msgid) error (0, 0, _(reason_msgid), operand); error (EXIT_TROUBLE, 0, _("Try `%s --help' for more information."), program_name); abort ();}static voidcheck_stdout (void){ if (ferror (stdout)) fatal ("write failed"); else if (fclose (stdout) != 0) pfatal_with_name (_("standard output"));}static char const * const option_help_msgid[] = { N_("Compare files line by line."), "", N_("-i --ignore-case Ignore case differences in file contents."), N_("--ignore-file-name-case Ignore case when comparing file names."), N_("--no-ignore-file-name-case Consider case when comparing file names."), N_("-E --ignore-tab-expansion Ignore changes due to tab expansion."), N_("-b --ignore-space-change Ignore changes in the amount of white space."), N_("-w --ignore-all-space Ignore all white space."), N_("-B --ignore-blank-lines Ignore changes whose lines are all blank."), N_("-I RE --ignore-matching-lines=RE Ignore changes whose lines all match RE."), N_("--strip-trailing-cr Strip trailing carriage return on input."),#if HAVE_SETMODE_DOS N_("--binary Read and write data in binary mode."),#endif N_("-a --text Treat all files as text."), "", N_("-c -C NUM --context[=NUM] Output NUM (default 3) lines of copied context.\n\-u -U NUM --unified[=NUM] Output NUM (default 3) lines of unified context.\n\ --label LABEL Use LABEL instead of file name.\n\ -p --show-c-function Show which C function each change is in.\n\ -F RE --show-function-line=RE Show the most recent line matching RE."), N_("-q --brief Output only whether files differ."), N_("-e --ed Output an ed script."), N_("--normal Output a normal diff."), N_("-n --rcs Output an RCS format diff."), N_("-y --side-by-side Output in two columns.\n\ -W NUM --width=NUM Output at most NUM (default 130) print columns.\n\ --left-column Output only the left column of common lines.\n\ --suppress-common-lines Do not output common lines."), N_("-D NAME --ifdef=NAME Output merged file to show `#ifdef NAME' diffs."), N_("--GTYPE-group-format=GFMT Similar, but format GTYPE input groups with GFMT."), N_("--line-format=LFMT Similar, but format all input lines with LFMT."), N_("--LTYPE-line-format=LFMT Similar, but format LTYPE input lines with LFMT."), N_(" LTYPE is `old', `new', or `unchanged'. GTYPE is LTYPE or `changed'."), N_(" GFMT may contain:\n\ %< lines from FILE1\n\ %> lines from FILE2\n\ %= lines common to FILE1 and FILE2\n\ %[-][WIDTH][.[PREC]]{doxX}LETTER printf-style spec for LETTER\n\ LETTERs are as follows for new group, lower case for old group:\n\ F first line number\n\ L last line number\n\ N number of lines = L-F+1\n\ E F-1\n\ M L+1"), N_(" LFMT may contain:\n\ %L contents of line\n\ %l contents of line, excluding any trailing newline\n\ %[-][WIDTH][.[PREC]]{doxX}n printf-style spec for input line number"), N_(" Either GFMT or LFMT may contain:\n\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -