📄 util.c
字号:
if (c1 == ' ' && c2 != '\n' && s2 + 1 < t2 && isspace ((unsigned char) t2[-2])) { --t2; continue; } } break; case IGNORE_TAB_EXPANSION: if ((c1 == ' ' && c2 == '\t') || (c1 == '\t' && c2 == ' ')) { size_t column2 = column; for (;; c1 = *t1++) { if (c1 == ' ') column++; else if (c1 == '\t') column += tabsize - column % tabsize; else break; } for (;; c2 = *t2++) { if (c2 == ' ') column2++; else if (c2 == '\t') column2 += tabsize - column2 % tabsize; else break; } if (column != column2) return true; } break; case IGNORE_NO_WHITE_SPACE: break; } /* Lowercase all letters if -i is specified. */ if (ignore_case) { c1 = tolower (c1); c2 = tolower (c2); } if (c1 != c2) break; } if (c1 == '\n') return false; column += c1 == '\t' ? tabsize - column % tabsize : 1; } return true;}/* Find the consecutive changes at the start of the script START. Return the last link before the first gap. */struct change *find_change (struct change *start){ return start;}struct change *find_reverse_change (struct change *start){ return start;}/* Divide SCRIPT into pieces by calling HUNKFUN and print each piece with PRINTFUN. Both functions take one arg, an edit script. HUNKFUN is called with the tail of the script and returns the last link that belongs together with the start of the tail. PRINTFUN takes a subscript which belongs together (with a null link at the end) and prints it. */voidprint_script (struct change *script, struct change * (*hunkfun) (struct change *), void (*printfun) (struct change *)){ struct change *next = script; while (next) { struct change *this, *end; /* Find a set of changes that belong together. */ this = next; end = (*hunkfun) (next); /* Disconnect them from the rest of the changes, making them a hunk, and remember the rest for next iteration. */ next = end->link; end->link = 0;#ifdef DEBUG debug_script (this);#endif /* Print this hunk. */ (*printfun) (this); /* Reconnect the script so it will all be freed properly. */ end->link = next; }}/* Print the text of a single line LINE, flagging it with the characters in LINE_FLAG (which say whether the line is inserted, deleted, changed, etc.). */voidprint_1_line (char const *line_flag, char const *const *line){ char const *base = line[0], *limit = line[1]; /* Help the compiler. */ FILE *out = outfile; /* Help the compiler some more. */ char const *flag_format = 0; /* If -T was specified, use a Tab between the line-flag and the text. Otherwise use a Space (as Unix diff does). Print neither space nor tab if line-flags are empty. */ if (line_flag && *line_flag) { flag_format = initial_tab ? "%s\t" : "%s "; fprintf (out, flag_format, line_flag); } output_1_line (base, limit, flag_format, line_flag); if ((!line_flag || line_flag[0]) && limit[-1] != '\n') fprintf (out, "\n\\ %s\n", _("No newline at end of file"));}/* Output a line from BASE up to LIMIT. With -t, expand white space characters to spaces, and if FLAG_FORMAT is nonzero, output it with argument LINE_FLAG after every internal carriage return, so that tab stops continue to line up. */voidoutput_1_line (char const *base, char const *limit, char const *flag_format, char const *line_flag){ if (!expand_tabs) fwrite (base, sizeof (char), limit - base, outfile); else { register FILE *out = outfile; register unsigned char c; register char const *t = base; register size_t column = 0; size_t tab_size = tabsize; while (t < limit) switch ((c = *t++)) { case '\t': { size_t spaces = tab_size - column % tab_size; column += spaces; do putc (' ', out); while (--spaces); } break; case '\r': putc (c, out); if (flag_format && t < limit && *t != '\n') fprintf (out, flag_format, line_flag); column = 0; break; case '\b': if (column == 0) continue; column--; putc (c, out); break; default: column += isprint (c) != 0; putc (c, out); break; } }}char const change_letter[] = { 0, 'd', 'a', 'c' };/* Translate an internal line number (an index into diff's table of lines) into an actual line number in the input file. The internal line number is I. FILE points to the data on the file. Internal line numbers count from 0 starting after the prefix. Actual line numbers count from 1 within the entire file. */lintranslate_line_number (struct file_data const *file, lin i){ return i + file->prefix_lines + 1;}/* Translate a line number range. This is always done for printing, so for convenience translate to long int rather than lin, so that the caller can use printf with "%ld" without casting. */voidtranslate_range (struct file_data const *file, lin a, lin b, long int *aptr, long int *bptr){ *aptr = translate_line_number (file, a - 1) + 1; *bptr = translate_line_number (file, b + 1) - 1;}/* Print a pair of line numbers with SEPCHAR, translated for file FILE. If the two numbers are identical, print just one number. Args A and B are internal line numbers. We print the translated (real) line numbers. */voidprint_number_range (char sepchar, struct file_data *file, lin a, lin b){ long int trans_a, trans_b; translate_range (file, a, b, &trans_a, &trans_b); /* Note: we can have B < A in the case of a range of no lines. In this case, we should print the line number before the range, which is B. */ if (trans_b > trans_a) fprintf (outfile, "%ld%c%ld", trans_a, sepchar, trans_b); else fprintf (outfile, "%ld", trans_b);}/* Look at a hunk of edit script and report the range of lines in each file that it applies to. HUNK is the start of the hunk, which is a chain of `struct change'. The first and last line numbers of file 0 are stored in *FIRST0 and *LAST0, and likewise for file 1 in *FIRST1 and *LAST1. Note that these are internal line numbers that count from 0. If no lines from file 0 are deleted, then FIRST0 is LAST0+1. Return UNCHANGED if only ignorable lines are inserted or deleted, OLD if lines of file 0 are deleted, NEW if lines of file 1 are inserted, and CHANGED if both kinds of changes are found. */enum changesanalyze_hunk (struct change *hunk, lin *first0, lin *last0, lin *first1, lin *last1){ struct change *next; lin l0, l1; lin show_from, show_to; lin i; bool trivial = ignore_blank_lines || ignore_regexp.fastmap; size_t trivial_length = ignore_blank_lines - 1; /* If 0, ignore zero-length lines; if SIZE_MAX, do not ignore lines just because of their length. */ bool skip_leading_white_space = (ignore_blank_lines && IGNORE_SPACE_CHANGE <= ignore_white_space); char const * const *linbuf0 = files[0].linbuf; /* Help the compiler. */ char const * const *linbuf1 = files[1].linbuf; show_from = show_to = 0; *first0 = hunk->line0; *first1 = hunk->line1; next = hunk; do { l0 = next->line0 + next->deleted - 1; l1 = next->line1 + next->inserted - 1; show_from += next->deleted; show_to += next->inserted; for (i = next->line0; i <= l0 && trivial; i++) { char const *line = linbuf0[i]; char const *newline = linbuf0[i + 1] - 1; size_t len = newline - line; char const *p = line; if (skip_leading_white_space) while (isspace ((unsigned char) *p) && *p != '\n') p++; if (newline - p != trivial_length && (! ignore_regexp.fastmap || re_search (&ignore_regexp, line, len, 0, len, 0) < 0)) trivial = 0; } for (i = next->line1; i <= l1 && trivial; i++) { char const *line = linbuf1[i]; char const *newline = linbuf1[i + 1] - 1; size_t len = newline - line; char const *p = line; if (skip_leading_white_space) while (isspace ((unsigned char) *p) && *p != '\n') p++; if (newline - p != trivial_length && (! ignore_regexp.fastmap || re_search (&ignore_regexp, line, len, 0, len, 0) < 0)) trivial = 0; } } while ((next = next->link) != 0); *last0 = l0; *last1 = l1; /* If all inserted or deleted lines are ignorable, tell the caller to ignore this hunk. */ if (trivial) return UNCHANGED; return (show_from ? OLD : UNCHANGED) | (show_to ? NEW : UNCHANGED);}/* Concatenate three strings, returning a newly malloc'd string. */char *concat (char const *s1, char const *s2, char const *s3){ char *new = xmalloc (strlen (s1) + strlen (s2) + strlen (s3) + 1); sprintf (new, "%s%s%s", s1, s2, s3); return new;}/* Yield a new block of SIZE bytes, initialized to zero. */void *zalloc (size_t size){ void *p = xmalloc (size); memset (p, 0, size); return p;}/* Yield the newly malloc'd pathname of the file in DIR whose filename is FILE. */char *dir_file_pathname (char const *dir, char const *file){ char const *base = base_name (dir); bool omit_slash = !*base || base[strlen (base) - 1] == '/'; return concat (dir, "/" + omit_slash, file);}voiddebug_script (struct change *sp){ fflush (stdout); for (; sp; sp = sp->link) { long int line0 = sp->line0; long int line1 = sp->line1; long int deleted = sp->deleted; long int inserted = sp->inserted; fprintf (stderr, "%3ld %3ld delete %ld insert %ld\n", line0, line1, deleted, inserted); } fflush (stderr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -