diff options
Diffstat (limited to 'src/context.c')
-rw-r--r-- | src/context.c | 207 |
1 files changed, 97 insertions, 110 deletions
diff --git a/src/context.c b/src/context.c index 17164b3..7c127dd 100644 --- a/src/context.c +++ b/src/context.c @@ -1,7 +1,7 @@ /* Context-format output routines for GNU DIFF. Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1998, 2001, - 2002, 2004 Free Software Foundation, Inc. + 2002, 2004, 2006 Free Software Foundation, Inc. This file is part of GNU DIFF. @@ -22,73 +22,70 @@ #include "diff.h" #include <inttostr.h> +#include <stat-time.h> +#include <strftime.h> -#ifdef ST_MTIM_NSEC -# define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC) -#else -# define TIMESPEC_NS(timespec) 0 -#endif +static char const *find_function (char const * const *, lin); +static struct change *find_hunk (struct change *); +static void mark_ignorable (struct change *); +static void pr_context_hunk (struct change *); +static void pr_unidiff_hunk (struct change *); -size_t nstrftime (char *, size_t, char const *, struct tm const *, int, int); +/* Last place find_function started searching from. */ +static lin find_function_last_search; -static char const *find_function (char const * const *, lin, struct diffopt *); -static struct change *find_hunk (struct change *, struct diffopt const *opt); -static void mark_ignorable (struct change *, struct diffopt *); -static void pr_context_hunk (struct change *, struct diffopt *); -static void pr_unidiff_hunk (struct change *, struct diffopt *); +/* The value find_function returned when it started searching there. */ +static lin find_function_last_match; /* Print a label for a context diff, with a file name and date or a label. */ static void print_context_label (char const *mark, struct file_data *inf, - char const *label, - struct diffopt const *opt) + char const *label) { if (label) - fprintf (opt->out, "%s %s\n", mark, label); + fprintf (outfile, "%s %s\n", mark, label); else { char buf[MAX (INT_STRLEN_BOUND (int) + 32, INT_STRLEN_BOUND (time_t) + 11)]; struct tm const *tm = localtime (&inf->stat.st_mtime); - int nsec = TIMESPEC_NS (inf->stat.st_mtim); - if (! (tm && nstrftime (buf, sizeof buf, opt->time_format, tm, 0, nsec))) + int nsec = get_stat_mtime_ns (&inf->stat); + if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, 0, nsec))) { long int sec = inf->stat.st_mtime; - verify (info_preserved, sizeof inf->stat.st_mtime <= sizeof sec); + verify (sizeof inf->stat.st_mtime <= sizeof sec); sprintf (buf, "%ld.%.9d", sec, nsec); } - fprintf (opt->out, "%s %s\t%s\n", mark, inf->name, buf); + fprintf (outfile, "%s %s\t%s\n", mark, inf->name, buf); } } /* Print a header for a context diff, with the file names and dates. */ void -print_context_header (struct file_data inf[], bool unidiff, - struct diffopt const *opt) +print_context_header (struct file_data inf[], bool unidiff) { if (unidiff) { - print_context_label ("---", &inf[0], opt->file_label[0], opt); - print_context_label ("+++", &inf[1], opt->file_label[1], opt); + print_context_label ("---", &inf[0], file_label[0]); + print_context_label ("+++", &inf[1], file_label[1]); } else { - print_context_label ("***", &inf[0], opt->file_label[0], opt); - print_context_label ("---", &inf[1], opt->file_label[1], opt); + print_context_label ("***", &inf[0], file_label[0]); + print_context_label ("---", &inf[1], file_label[1]); } } /* Print an edit script in context format. */ void -print_context_script (struct change *script, bool unidiff, - struct diffopt *opt) +print_context_script (struct change *script, bool unidiff) { - if (opt->ignore_blank_lines || opt->ignore_regexp) - mark_ignorable (script, opt); + if (ignore_blank_lines || ignore_regexp.fastmap) + mark_ignorable (script); else { struct change *e; @@ -96,13 +93,13 @@ print_context_script (struct change *script, bool unidiff, e->ignore = false; } - opt->find_function.last_search = - opt->file[0].prefix_lines; - opt->find_function.last_match = LIN_MAX; + find_function_last_search = - files[0].prefix_lines; + find_function_last_match = LIN_MAX; if (unidiff) - print_script (script, find_hunk, pr_unidiff_hunk, opt); + print_script (script, find_hunk, pr_unidiff_hunk); else - print_script (script, find_hunk, pr_context_hunk, opt); + print_script (script, find_hunk, pr_context_hunk); } /* Print a pair of line numbers with a comma, translated for file FILE. @@ -112,8 +109,7 @@ print_context_script (struct change *script, bool unidiff, We print the translated (real) line numbers. */ static void -print_context_number_range (FILE *out, struct file_data const *file, - lin a, lin b) +print_context_number_range (struct file_data const *file, lin a, lin b) { long int trans_a, trans_b; translate_range (file, a, b, &trans_a, &trans_b); @@ -128,9 +124,9 @@ print_context_number_range (FILE *out, struct file_data const *file, specification. */ if (trans_b <= trans_a) - fprintf (out, "%ld", trans_b); + fprintf (outfile, "%ld", trans_b); else - fprintf (out, "%ld,%ld", trans_a, trans_b); + fprintf (outfile, "%ld,%ld", trans_a, trans_b); } /* Print FUNCTION in a context header. */ @@ -147,13 +143,12 @@ print_context_function (FILE *out, char const *function) /* Print a portion of an edit script in context format. HUNK is the beginning of the portion to be printed. The end is marked by a `link' that has been nulled out. - OPT is the diff options. Prints out lines from both files, and precedes each line with the appropriate flag-character. */ static void -pr_context_hunk (struct change *hunk, struct diffopt *opt) +pr_context_hunk (struct change *hunk) { lin first0, last0, first1, last1, i; char const *prefix; @@ -162,32 +157,31 @@ pr_context_hunk (struct change *hunk, struct diffopt *opt) /* Determine range of line numbers involved in each file. */ - enum changes changes = analyze_hunk (hunk, &first0, &last0, &first1, &last1, - opt); + enum changes changes = analyze_hunk (hunk, &first0, &last0, &first1, &last1); if (! changes) return; /* Include a context's width before and after. */ - i = - opt->file[0].prefix_lines; - first0 = MAX (first0 - opt->context, i); - first1 = MAX (first1 - opt->context, i); - if (last0 < opt->file[0].valid_lines - opt->context) - last0 += opt->context; + i = - files[0].prefix_lines; + first0 = MAX (first0 - context, i); + first1 = MAX (first1 - context, i); + if (last0 < files[0].valid_lines - context) + last0 += context; else - last0 = opt->file[0].valid_lines - 1; - if (last1 < opt->file[1].valid_lines - opt->context) - last1 += opt->context; + last0 = files[0].valid_lines - 1; + if (last1 < files[1].valid_lines - context) + last1 += context; else - last1 = opt->file[1].valid_lines - 1; + last1 = files[1].valid_lines - 1; /* If desired, find the preceding function definition line in file 0. */ - function = 0; - if (opt->function_regexp) - function = find_function (opt->file[0].linbuf, first0, opt); + function = NULL; + if (function_regexp.fastmap) + function = find_function (files[0].linbuf, first0); - begin_output (opt); - out = opt->out; + begin_output (); + out = outfile; fprintf (out, "***************"); @@ -195,7 +189,7 @@ pr_context_hunk (struct change *hunk, struct diffopt *opt) print_context_function (out, function); fprintf (out, "\n*** "); - print_context_number_range (opt->out, &opt->file[0], first0, last0); + print_context_number_range (&files[0], first0, last0); fprintf (out, " ****\n"); if (changes & OLD) @@ -219,12 +213,12 @@ pr_context_hunk (struct change *hunk, struct diffopt *opt) Otherwise it is "deleted". */ prefix = (next->inserted > 0 ? "!" : "-"); - print_1_line (prefix, &opt->file[0].linbuf[i], opt); + print_1_line (prefix, &files[0].linbuf[i]); } } fprintf (out, "--- "); - print_context_number_range (opt->out, &opt->file[1], first1, last1); + print_context_number_range (&files[1], first1, last1); fprintf (out, " ----\n"); if (changes & NEW) @@ -248,7 +242,7 @@ pr_context_hunk (struct change *hunk, struct diffopt *opt) Otherwise it is "inserted". */ prefix = (next->deleted > 0 ? "!" : "+"); - print_1_line (prefix, &opt->file[1].linbuf[i], opt); + print_1_line (prefix, &files[1].linbuf[i]); } } } @@ -258,13 +252,10 @@ pr_context_hunk (struct change *hunk, struct diffopt *opt) If the numbers are equal, print just one number. Args A and B are internal line numbers. - We print the translated (real) line numbers. - - OPT is the diff options. */ + We print the translated (real) line numbers. */ static void -print_unidiff_number_range (FILE *out, struct file_data const *file, - lin a, lin b) +print_unidiff_number_range (struct file_data const *file, lin a, lin b) { long int trans_a, trans_b; translate_range (file, a, b, &trans_a, &trans_b); @@ -274,9 +265,9 @@ print_unidiff_number_range (FILE *out, struct file_data const *file, which is B. It would be more logical to print A, but 'patch' expects B in order to detect diffs against empty files. */ if (trans_b <= trans_a) - fprintf (out, trans_b < trans_a ? "%ld,0" : "%ld", trans_b); + fprintf (outfile, trans_b < trans_a ? "%ld,0" : "%ld", trans_b); else - fprintf (out, "%ld,%ld", trans_a, trans_b - trans_a + 1); + fprintf (outfile, "%ld,%ld", trans_a, trans_b - trans_a + 1); } /* Print a portion of an edit script in unidiff format. @@ -284,12 +275,10 @@ print_unidiff_number_range (FILE *out, struct file_data const *file, The end is marked by a `link' that has been nulled out. Prints out lines from both files, and precedes each - line with the appropriate flag-character. - - OPT is the diff options. */ + line with the appropriate flag-character. */ static void -pr_unidiff_hunk (struct change *hunk, struct diffopt *opt) +pr_unidiff_hunk (struct change *hunk) { lin first0, last0, first1, last1; lin i, j, k; @@ -299,35 +288,35 @@ pr_unidiff_hunk (struct change *hunk, struct diffopt *opt) /* Determine range of line numbers involved in each file. */ - if (! analyze_hunk (hunk, &first0, &last0, &first1, &last1, opt)) + if (! analyze_hunk (hunk, &first0, &last0, &first1, &last1)) return; /* Include a context's width before and after. */ - i = - opt->file[0].prefix_lines; - first0 = MAX (first0 - opt->context, i); - first1 = MAX (first1 - opt->context, i); - if (last0 < opt->file[0].valid_lines - opt->context) - last0 += opt->context; + i = - files[0].prefix_lines; + first0 = MAX (first0 - context, i); + first1 = MAX (first1 - context, i); + if (last0 < files[0].valid_lines - context) + last0 += context; else - last0 = opt->file[0].valid_lines - 1; - if (last1 < opt->file[1].valid_lines - opt->context) - last1 += opt->context; + last0 = files[0].valid_lines - 1; + if (last1 < files[1].valid_lines - context) + last1 += context; else - last1 = opt->file[1].valid_lines - 1; + last1 = files[1].valid_lines - 1; /* If desired, find the preceding function definition line in file 0. */ - function = 0; - if (opt->function_regexp) - function = find_function (opt->file[0].linbuf, first0, opt); + function = NULL; + if (function_regexp.fastmap) + function = find_function (files[0].linbuf, first0); - begin_output (opt); - out = opt->out; + begin_output (); + out = outfile; fprintf (out, "@@ -"); - print_unidiff_number_range (opt->out, &opt->file[0], first0, last0); + print_unidiff_number_range (&files[0], first0, last0); fprintf (out, " +"); - print_unidiff_number_range (opt->out, &opt->file[1], first1, last1); + print_unidiff_number_range (&files[1], first1, last1); fprintf (out, " @@"); if (function) @@ -346,8 +335,8 @@ pr_unidiff_hunk (struct change *hunk, struct diffopt *opt) if (!next || i < next->line0) { - putc (opt->initial_tab ? '\t' : ' ', out); - print_1_line (0, &opt->file[0].linbuf[i++], opt); + putc (initial_tab ? '\t' : ' ', out); + print_1_line (NULL, &files[0].linbuf[i++]); j++; } else @@ -358,9 +347,9 @@ pr_unidiff_hunk (struct change *hunk, struct diffopt *opt) while (k--) { putc ('-', out); - if (opt->initial_tab) + if (initial_tab) putc ('\t', out); - print_1_line (0, &opt->file[0].linbuf[i++], opt); + print_1_line (NULL, &files[0].linbuf[i++]); } /* Then output the inserted part. */ @@ -369,9 +358,9 @@ pr_unidiff_hunk (struct change *hunk, struct diffopt *opt) while (k--) { putc ('+', out); - if (opt->initial_tab) + if (initial_tab) putc ('\t', out); - print_1_line (0, &opt->file[1].linbuf[j++], opt); + print_1_line (NULL, &files[1].linbuf[j++]); } /* We're done with this hunk, so on to the next! */ @@ -386,7 +375,7 @@ pr_unidiff_hunk (struct change *hunk, struct diffopt *opt) to the `struct change' for the last change before those lines. */ static struct change * -find_hunk (struct change *start, struct diffopt const *opt) +find_hunk (struct change *start) { struct change *prev; lin top0, top1; @@ -396,8 +385,8 @@ find_hunk (struct change *start, struct diffopt const *opt) changes, but only CONTEXT if one is ignorable. Watch out for integer overflow, though. */ lin non_ignorable_threshold = - (LIN_MAX - 1) / 2 < opt->context ? LIN_MAX : 2 * opt->context + 1; - lin ignorable_threshold = opt->context; + (LIN_MAX - 1) / 2 < context ? LIN_MAX : 2 * context + 1; + lin ignorable_threshold = context; do { @@ -426,7 +415,7 @@ find_hunk (struct change *start, struct diffopt const *opt) are ignorable lines. */ static void -mark_ignorable (struct change *script, struct diffopt *opt) +mark_ignorable (struct change *script) { while (script) { @@ -438,7 +427,7 @@ mark_ignorable (struct change *script, struct diffopt *opt) /* Determine whether this change is ignorable. */ script->ignore = ! analyze_hunk (script, - &first0, &last0, &first1, &last1, opt); + &first0, &last0, &first1, &last1); /* Reconnect the chain as before. */ script->link = next; @@ -449,17 +438,15 @@ mark_ignorable (struct change *script, struct diffopt *opt) } /* Find the last function-header line in LINBUF prior to line number LINENUM. - This is a line containing a match for the regexp in `opt->function_regexp'. - OPT is the diff options. - Return the address of the text, or 0 if no function-header is found. */ + This is a line containing a match for the regexp in `function_regexp'. + Return the address of the text, or NULL if no function-header is found. */ static char const * -find_function (char const * const *linbuf, lin linenum, - struct diffopt *opt) +find_function (char const * const *linbuf, lin linenum) { lin i = linenum; - lin last = opt->find_function.last_search; - opt->find_function.last_search = i; + lin last = find_function_last_search; + find_function_last_search = i; while (last <= --i) { @@ -470,16 +457,16 @@ find_function (char const * const *linbuf, lin linenum, /* FIXME: re_search's size args should be size_t, not int. */ int len = MIN (linelen, INT_MAX); - if (0 <= re_search (opt->function_regexp, line, len, 0, len, 0)) + if (0 <= re_search (&function_regexp, line, len, 0, len, NULL)) { - opt->find_function.last_match = i; + find_function_last_match = i; return line; } } /* If we search back to where we started searching the previous time, find the line we found last time. */ - if (opt->find_function.last_match != LIN_MAX) - return linbuf[opt->find_function.last_match]; + if (find_function_last_match != LIN_MAX) + return linbuf[find_function_last_match]; - return 0; + return NULL; } |