1 /* Support routines for GNU DIFF.
3 Copyright (C) 1988-1989, 1992-1995, 1998, 2001-2002, 2004, 2006, 2009-2011
4 Free Software Foundation, Inc.
6 This file is part of GNU DIFF.
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27 char const pr_program[] = PR_PROGRAM;
29 /* Queue up one-line messages to be printed at the end,
30 when -l is specified. Each message is recorded with a `struct msg'. */
35 char args[1]; /* Format + 4 args, each '\0' terminated, concatenated. */
38 /* Head of the chain of queues messages. */
40 static struct msg *msg_chain;
42 /* Tail of the chain of queues messages. */
44 static struct msg **msg_chain_end = &msg_chain;
46 /* Use when a system call returns non-zero status.
47 NAME should normally be the file name. */
50 perror_with_name (char const *name)
52 error (0, errno, "%s", name);
55 /* Use when a system call returns non-zero status and that is fatal. */
58 pfatal_with_name (char const *name)
61 print_message_queue ();
62 error (EXIT_TROUBLE, e, "%s", name);
66 /* Print an error message containing MSGID, then exit. */
69 fatal (char const *msgid)
71 print_message_queue ();
72 error (EXIT_TROUBLE, 0, "%s", _(msgid));
76 /* Like printf, except if -l in effect then save the message and print later.
77 This is used for things like "Only in ...". */
80 message (char const *format_msgid, char const *arg1, char const *arg2)
82 message5 (format_msgid, arg1, arg2, 0, 0);
86 message5 (char const *format_msgid, char const *arg1, char const *arg2,
87 char const *arg3, char const *arg4)
95 size_t total_size = offsetof (struct msg, args);
98 arg[0] = format_msgid;
101 arg[3] = arg3 ? arg3 : "";
102 arg[4] = arg4 ? arg4 : "";
104 for (i = 0; i < 5; i++)
105 total_size += size[i] = strlen (arg[i]) + 1;
107 new = xmalloc (total_size);
109 for (i = 0, p = new->args; i < 5; p += size[i++])
110 memcpy (p, arg[i], size[i]);
112 *msg_chain_end = new;
114 msg_chain_end = &new->next;
118 if (sdiff_merge_assist)
120 printf (_(format_msgid), arg1, arg2, arg3, arg4);
124 /* Output all the messages that were saved up by calls to `message'. */
127 print_message_queue (void)
131 struct msg *m = msg_chain;
135 struct msg *next = m->next;
137 for (i = 0; i < 4; i++)
138 arg[i + 1] = arg[i] + strlen (arg[i]) + 1;
139 printf (_(arg[0]), arg[1], arg[2], arg[3], arg[4]);
145 /* Call before outputting the results of comparing files NAME0 and NAME1
146 to set up OUTFILE, the stdio stream for the output to go to.
148 Usually, OUTFILE is just stdout. But when -l was specified
149 we fork off a `pr' and make OUTFILE a pipe to it.
150 `pr' then outputs to our stdout. */
152 static char const *current_name0;
153 static char const *current_name1;
154 static bool currently_recursive;
157 setup_output (char const *name0, char const *name1, bool recursive)
159 current_name0 = name0;
160 current_name1 = name1;
161 currently_recursive = recursive;
165 #if HAVE_WORKING_FORK
177 /* Construct the header of this piece of diff. */
178 name = xmalloc (strlen (current_name0) + strlen (current_name1)
179 + strlen (switch_string) + 7);
181 /* POSIX 1003.1-2001 specifies this format. But there are some bugs in
182 the standard: it says that we must print only the last component
183 of the pathnames, and it requires two spaces after "diff" if
184 there are no options. These requirements are silly and do not
185 match historical practice. */
186 sprintf (name, "diff%s %s %s", switch_string, current_name0, current_name1);
190 if (fflush (stdout) != 0)
191 pfatal_with_name (_("write failed"));
193 /* Make OUTFILE a pipe to a subsidiary `pr'. */
195 #if HAVE_WORKING_FORK
198 if (pipe (pipes) != 0)
199 pfatal_with_name ("pipe");
203 pfatal_with_name ("fork");
208 if (pipes[0] != STDIN_FILENO)
210 if (dup2 (pipes[0], STDIN_FILENO) < 0)
211 pfatal_with_name ("dup2");
215 execl (pr_program, pr_program, "-h", name, (char *) 0);
216 _exit (errno == ENOENT ? 127 : 126);
221 outfile = fdopen (pipes[1], "w");
223 pfatal_with_name ("fdopen");
226 char *command = xmalloc (sizeof pr_program - 1 + 7
227 + shell_quote_length (name) + 1);
229 sprintf (command, "%s -f -h ", pr_program);
230 p = command + sizeof pr_program - 1 + 7;
231 p = shell_quote_copy (p, name);
234 outfile = popen (command, "w");
236 pfatal_with_name (command);
244 /* If -l was not specified, output the diff straight to `stdout'. */
248 /* If handling multiple files (because scanning a directory),
249 print which files the following output is about. */
250 if (currently_recursive)
251 printf ("%s\n", name);
256 /* A special header is needed at the beginning of context output. */
257 switch (output_style)
260 print_context_header (files, false);
264 print_context_header (files, true);
272 /* Call after the end of output of diffs for one file.
273 Close OUTFILE and get rid of the `pr' subfork. */
278 if (outfile != 0 && outfile != stdout)
283 if (ferror (outfile))
284 fatal ("write failed");
285 #if ! HAVE_WORKING_FORK
286 wstatus = pclose (outfile);
290 if (fclose (outfile) != 0)
291 pfatal_with_name (_("write failed"));
292 if (waitpid (pr_pid, &wstatus, 0) < 0)
293 pfatal_with_name ("waitpid");
295 status = (! werrno && WIFEXITED (wstatus)
296 ? WEXITSTATUS (wstatus)
299 error (EXIT_TROUBLE, werrno,
301 ? "subsidiary program `%s' could not be invoked"
303 ? "subsidiary program `%s' not found"
305 ? "subsidiary program `%s' failed"
306 : "subsidiary program `%s' failed (exit status %d)"),
313 /* Compare two lines (typically one from each input file)
314 according to the command line options.
315 For efficiency, this is invoked only when the lines do not match exactly
316 but an option like -i might cause us to ignore the difference.
317 Return nonzero if the lines differ. */
320 lines_differ (char const *s1, char const *s2)
322 register char const *t1 = s1;
323 register char const *t2 = s2;
328 register unsigned char c1 = *t1++;
329 register unsigned char c2 = *t2++;
331 /* Test for exact char equality first, since it's a common case. */
334 switch (ignore_white_space)
336 case IGNORE_ALL_SPACE:
337 /* For -w, just skip past any white space. */
338 while (isspace (c1) && c1 != '\n') c1 = *t1++;
339 while (isspace (c2) && c2 != '\n') c2 = *t2++;
342 case IGNORE_SPACE_CHANGE:
343 /* For -b, advance past any sequence of white space in
344 line 1 and consider it just one space, or nothing at
345 all if it is at the end of the line. */
360 /* Likewise for line 2. */
377 /* If we went too far when doing the simple test
378 for equality, go back to the first non-white-space
379 character in both sides and try again. */
380 if (c2 == ' ' && c1 != '\n'
382 && isspace ((unsigned char) t1[-2]))
387 if (c1 == ' ' && c2 != '\n'
389 && isspace ((unsigned char) t2[-2]))
398 case IGNORE_TRAILING_SPACE:
399 case IGNORE_TAB_EXPANSION_AND_TRAILING_SPACE:
400 if (isspace (c1) && isspace (c2))
406 while ((c = *p) != '\n' && isspace (c))
414 while ((c = *p) != '\n' && isspace (c))
419 /* Both lines have nothing but whitespace left. */
422 if (ignore_white_space == IGNORE_TRAILING_SPACE)
425 case IGNORE_TAB_EXPANSION:
426 if ((c1 == ' ' && c2 == '\t')
427 || (c1 == '\t' && c2 == ' '))
429 size_t column2 = column;
435 column += tabsize - column % tabsize;
444 column2 += tabsize - column2 % tabsize;
448 if (column != column2)
453 case IGNORE_NO_WHITE_SPACE:
457 /* Lowercase all letters if -i is specified. */
471 column += c1 == '\t' ? tabsize - column % tabsize : 1;
477 /* Find the consecutive changes at the start of the script START.
478 Return the last link before the first gap. */
481 find_change (struct change *start)
487 find_reverse_change (struct change *start)
492 /* Divide SCRIPT into pieces by calling HUNKFUN and
493 print each piece with PRINTFUN.
494 Both functions take one arg, an edit script.
496 HUNKFUN is called with the tail of the script
497 and returns the last link that belongs together with the start
500 PRINTFUN takes a subscript which belongs together (with a null
501 link at the end) and prints it. */
504 print_script (struct change *script,
505 struct change * (*hunkfun) (struct change *),
506 void (*printfun) (struct change *))
508 struct change *next = script;
512 struct change *this, *end;
514 /* Find a set of changes that belong together. */
516 end = (*hunkfun) (next);
518 /* Disconnect them from the rest of the changes,
519 making them a hunk, and remember the rest for next iteration. */
526 /* Print this hunk. */
529 /* Reconnect the script so it will all be freed properly. */
534 /* Print the text of a single line LINE,
535 flagging it with the characters in LINE_FLAG (which say whether
536 the line is inserted, deleted, changed, etc.). LINE_FLAG must not
537 end in a blank, unless it is a single blank. */
540 print_1_line (char const *line_flag, char const *const *line)
542 char const *base = line[0], *limit = line[1]; /* Help the compiler. */
543 FILE *out = outfile; /* Help the compiler some more. */
544 char const *flag_format = 0;
546 /* If -T was specified, use a Tab between the line-flag and the text.
547 Otherwise use a Space (as Unix diff does).
548 Print neither space nor tab if line-flags are empty.
549 But omit trailing blanks if requested. */
551 if (line_flag && *line_flag)
553 char const *flag_format_1 = flag_format = initial_tab ? "%s\t" : "%s ";
554 char const *line_flag_1 = line_flag;
556 if (suppress_blank_empty && **line == '\n')
558 flag_format_1 = "%s";
560 /* This hack to omit trailing blanks takes advantage of the
561 fact that the only way that LINE_FLAG can end in a blank
562 is when LINE_FLAG consists of a single blank. */
563 line_flag_1 += *line_flag_1 == ' ';
566 fprintf (out, flag_format_1, line_flag_1);
569 output_1_line (base, limit, flag_format, line_flag);
571 if ((!line_flag || line_flag[0]) && limit[-1] != '\n')
572 fprintf (out, "\n\\ %s\n", _("No newline at end of file"));
575 /* Output a line from BASE up to LIMIT.
576 With -t, expand white space characters to spaces, and if FLAG_FORMAT
577 is nonzero, output it with argument LINE_FLAG after every
578 internal carriage return, so that tab stops continue to line up. */
581 output_1_line (char const *base, char const *limit, char const *flag_format,
582 char const *line_flag)
585 fwrite (base, sizeof (char), limit - base, outfile);
588 register FILE *out = outfile;
589 register unsigned char c;
590 register char const *t = base;
591 register size_t column = 0;
592 size_t tab_size = tabsize;
599 size_t spaces = tab_size - column % tab_size;
609 if (flag_format && t < limit && *t != '\n')
610 fprintf (out, flag_format, line_flag);
622 column += isprint (c) != 0;
629 char const change_letter[] = { 0, 'd', 'a', 'c' };
631 /* Translate an internal line number (an index into diff's table of lines)
632 into an actual line number in the input file.
633 The internal line number is I. FILE points to the data on the file.
635 Internal line numbers count from 0 starting after the prefix.
636 Actual line numbers count from 1 within the entire file. */
639 translate_line_number (struct file_data const *file, lin i)
641 return i + file->prefix_lines + 1;
644 /* Translate a line number range. This is always done for printing,
645 so for convenience translate to long int rather than lin, so that the
646 caller can use printf with "%ld" without casting. */
649 translate_range (struct file_data const *file,
651 long int *aptr, long int *bptr)
653 *aptr = translate_line_number (file, a - 1) + 1;
654 *bptr = translate_line_number (file, b + 1) - 1;
657 /* Print a pair of line numbers with SEPCHAR, translated for file FILE.
658 If the two numbers are identical, print just one number.
660 Args A and B are internal line numbers.
661 We print the translated (real) line numbers. */
664 print_number_range (char sepchar, struct file_data *file, lin a, lin b)
666 long int trans_a, trans_b;
667 translate_range (file, a, b, &trans_a, &trans_b);
669 /* Note: we can have B < A in the case of a range of no lines.
670 In this case, we should print the line number before the range,
672 if (trans_b > trans_a)
673 fprintf (outfile, "%ld%c%ld", trans_a, sepchar, trans_b);
675 fprintf (outfile, "%ld", trans_b);
678 /* Look at a hunk of edit script and report the range of lines in each file
679 that it applies to. HUNK is the start of the hunk, which is a chain
680 of `struct change'. The first and last line numbers of file 0 are stored in
681 *FIRST0 and *LAST0, and likewise for file 1 in *FIRST1 and *LAST1.
682 Note that these are internal line numbers that count from 0.
684 If no lines from file 0 are deleted, then FIRST0 is LAST0+1.
686 Return UNCHANGED if only ignorable lines are inserted or deleted,
687 OLD if lines of file 0 are deleted,
688 NEW if lines of file 1 are inserted,
689 and CHANGED if both kinds of changes are found. */
692 analyze_hunk (struct change *hunk,
693 lin *first0, lin *last0,
694 lin *first1, lin *last1)
698 lin show_from, show_to;
700 bool trivial = ignore_blank_lines || ignore_regexp.fastmap;
701 size_t trivial_length = ignore_blank_lines - 1;
702 /* If 0, ignore zero-length lines;
703 if SIZE_MAX, do not ignore lines just because of their length. */
705 bool skip_white_space =
706 ignore_blank_lines && IGNORE_TRAILING_SPACE <= ignore_white_space;
707 bool skip_leading_white_space =
708 skip_white_space && IGNORE_SPACE_CHANGE <= ignore_white_space;
710 char const * const *linbuf0 = files[0].linbuf; /* Help the compiler. */
711 char const * const *linbuf1 = files[1].linbuf;
713 show_from = show_to = 0;
715 *first0 = hunk->line0;
716 *first1 = hunk->line1;
721 l0 = next->line0 + next->deleted - 1;
722 l1 = next->line1 + next->inserted - 1;
723 show_from += next->deleted;
724 show_to += next->inserted;
726 for (i = next->line0; i <= l0 && trivial; i++)
728 char const *line = linbuf0[i];
729 char const *newline = linbuf0[i + 1] - 1;
730 size_t len = newline - line;
731 char const *p = line;
732 if (skip_white_space)
733 for (; *p != '\n'; p++)
734 if (! isspace ((unsigned char) *p))
736 if (! skip_leading_white_space)
740 if (newline - p != trivial_length
741 && (! ignore_regexp.fastmap
742 || re_search (&ignore_regexp, line, len, 0, len, 0) < 0))
746 for (i = next->line1; i <= l1 && trivial; i++)
748 char const *line = linbuf1[i];
749 char const *newline = linbuf1[i + 1] - 1;
750 size_t len = newline - line;
751 char const *p = line;
752 if (skip_white_space)
753 for (; *p != '\n'; p++)
754 if (! isspace ((unsigned char) *p))
756 if (! skip_leading_white_space)
760 if (newline - p != trivial_length
761 && (! ignore_regexp.fastmap
762 || re_search (&ignore_regexp, line, len, 0, len, 0) < 0))
766 while ((next = next->link) != 0);
771 /* If all inserted or deleted lines are ignorable,
772 tell the caller to ignore this hunk. */
777 return (show_from ? OLD : UNCHANGED) | (show_to ? NEW : UNCHANGED);
780 /* Concatenate three strings, returning a newly malloc'd string. */
783 concat (char const *s1, char const *s2, char const *s3)
785 char *new = xmalloc (strlen (s1) + strlen (s2) + strlen (s3) + 1);
786 sprintf (new, "%s%s%s", s1, s2, s3);
790 /* Yield a new block of SIZE bytes, initialized to zero. */
795 void *p = xmalloc (size);
801 debug_script (struct change *sp)
805 for (; sp; sp = sp->link)
807 long int line0 = sp->line0;
808 long int line1 = sp->line1;
809 long int deleted = sp->deleted;
810 long int inserted = sp->inserted;
811 fprintf (stderr, "%3ld %3ld delete %ld insert %ld\n",
812 line0, line1, deleted, inserted);