1 /* Support routines for GNU DIFF.
3 Copyright (C) 1988-1989, 1992-1995, 1998, 2001-2002, 2004, 2006, 2009-2013
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/>. */
24 #include <system-quote.h>
26 #include "xvasprintf.h"
28 char const pr_program[] = PR_PROGRAM;
30 /* Queue up one-line messages to be printed at the end,
31 when -l is specified. Each message is recorded with a 'struct msg'. */
36 char args[1]; /* Format + 4 args, each '\0' terminated, concatenated. */
39 /* Head of the chain of queues messages. */
41 static struct msg *msg_chain;
43 /* Tail of the chain of queues messages. */
45 static struct msg **msg_chain_end = &msg_chain;
47 /* Use when a system call returns non-zero status.
48 NAME should normally be the file name. */
51 perror_with_name (char const *name)
53 error (0, errno, "%s", name);
56 /* Use when a system call returns non-zero status and that is fatal. */
59 pfatal_with_name (char const *name)
62 print_message_queue ();
63 error (EXIT_TROUBLE, e, "%s", name);
67 /* Print an error message containing MSGID, then exit. */
70 fatal (char const *msgid)
72 print_message_queue ();
73 error (EXIT_TROUBLE, 0, "%s", _(msgid));
77 /* Like printf, except if -l in effect then save the message and print later.
78 This is used for things like "Only in ...". */
81 message (char const *format_msgid, char const *arg1, char const *arg2)
83 message5 (format_msgid, arg1, arg2, 0, 0);
87 message5 (char const *format_msgid, char const *arg1, char const *arg2,
88 char const *arg3, char const *arg4)
96 size_t total_size = offsetof (struct msg, args);
99 arg[0] = format_msgid;
102 arg[3] = arg3 ? arg3 : "";
103 arg[4] = arg4 ? arg4 : "";
105 for (i = 0; i < 5; i++)
106 total_size += size[i] = strlen (arg[i]) + 1;
108 new = xmalloc (total_size);
110 for (i = 0, p = new->args; i < 5; p += size[i++])
111 memcpy (p, arg[i], size[i]);
113 *msg_chain_end = new;
115 msg_chain_end = &new->next;
119 if (sdiff_merge_assist)
121 printf (_(format_msgid), arg1, arg2, arg3, arg4);
125 /* Output all the messages that were saved up by calls to 'message'. */
128 print_message_queue (void)
132 struct msg *m = msg_chain;
136 struct msg *next = m->next;
138 for (i = 0; i < 4; i++)
139 arg[i + 1] = arg[i] + strlen (arg[i]) + 1;
140 printf (_(arg[0]), arg[1], arg[2], arg[3], arg[4]);
146 /* Call before outputting the results of comparing files NAME0 and NAME1
147 to set up OUTFILE, the stdio stream for the output to go to.
149 Usually, OUTFILE is just stdout. But when -l was specified
150 we fork off a 'pr' and make OUTFILE a pipe to it.
151 'pr' then outputs to our stdout. */
153 static char const *current_name0;
154 static char const *current_name1;
155 static bool currently_recursive;
158 setup_output (char const *name0, char const *name1, bool recursive)
160 current_name0 = name0;
161 current_name1 = name1;
162 currently_recursive = recursive;
166 #if HAVE_WORKING_FORK
170 static char c_escape_char (char c)
173 case '\a': return 'a';
174 case '\b': return 'b';
175 case '\t': return 't';
176 case '\n': return 'n';
177 case '\v': return 'v';
178 case '\f': return 'f';
179 case '\r': return 'r';
180 case '"': return '"';
181 case '\\': return '\\';
188 c_escape (char const *str)
192 bool must_quote = false;
194 for (s = str; *s; s++)
203 switch (c_escape_char (*s))
216 if (must_quote || plus)
218 size_t s_len = s - str;
219 char *buffer = xmalloc (s_len + plus + 3);
223 for (s = str; *s; s++)
226 char escape = c_escape_char (c);
235 *b++ = ((c >> 6) & 03) + '0';
236 *b++ = ((c >> 3) & 07) + '0';
237 *b++ = ((c >> 0) & 07) + '0';
262 names[0] = c_escape (current_name0);
263 names[1] = c_escape (current_name1);
265 /* Construct the header of this piece of diff. */
266 /* POSIX 1003.1-2001 specifies this format. But there are some bugs in
267 the standard: it says that we must print only the last component
268 of the pathnames, and it requires two spaces after "diff" if
269 there are no options. These requirements are silly and do not
270 match historical practice. */
271 name = xasprintf ("diff%s %s %s", switch_string, names[0], names[1]);
277 if (fflush (stdout) != 0)
278 pfatal_with_name (_("write failed"));
280 argv[0] = pr_program;
285 /* Make OUTFILE a pipe to a subsidiary 'pr'. */
287 #if HAVE_WORKING_FORK
290 if (pipe (pipes) != 0)
291 pfatal_with_name ("pipe");
295 pfatal_with_name ("fork");
300 if (pipes[0] != STDIN_FILENO)
302 if (dup2 (pipes[0], STDIN_FILENO) < 0)
303 pfatal_with_name ("dup2");
307 execv (pr_program, (char **) argv);
308 _exit (errno == ENOENT ? 127 : 126);
313 outfile = fdopen (pipes[1], "w");
315 pfatal_with_name ("fdopen");
318 char *command = system_quote_argv (SCI_SYSTEM, (char **) argv);
320 outfile = popen (command, "w");
322 pfatal_with_name (command);
330 /* If -l was not specified, output the diff straight to 'stdout'. */
334 /* If handling multiple files (because scanning a directory),
335 print which files the following output is about. */
336 if (currently_recursive)
337 printf ("%s\n", name);
342 /* A special header is needed at the beginning of context output. */
343 switch (output_style)
346 print_context_header (files, (char const *const *)names, false);
350 print_context_header (files, (char const *const *)names, true);
357 if (names[0] != current_name0)
359 if (names[1] != current_name1)
363 /* Call after the end of output of diffs for one file.
364 Close OUTFILE and get rid of the 'pr' subfork. */
369 if (outfile != 0 && outfile != stdout)
374 if (ferror (outfile))
375 fatal ("write failed");
376 #if ! HAVE_WORKING_FORK
377 wstatus = pclose (outfile);
381 if (fclose (outfile) != 0)
382 pfatal_with_name (_("write failed"));
383 if (waitpid (pr_pid, &wstatus, 0) < 0)
384 pfatal_with_name ("waitpid");
386 status = (! werrno && WIFEXITED (wstatus)
387 ? WEXITSTATUS (wstatus)
390 error (EXIT_TROUBLE, werrno,
392 ? "subsidiary program '%s' could not be invoked"
394 ? "subsidiary program '%s' not found"
396 ? "subsidiary program '%s' failed"
397 : "subsidiary program '%s' failed (exit status %d)"),
404 /* Compare two lines (typically one from each input file)
405 according to the command line options.
406 For efficiency, this is invoked only when the lines do not match exactly
407 but an option like -i might cause us to ignore the difference.
408 Return nonzero if the lines differ. */
411 lines_differ (char const *s1, char const *s2)
413 register char const *t1 = s1;
414 register char const *t2 = s2;
419 register unsigned char c1 = *t1++;
420 register unsigned char c2 = *t2++;
422 /* Test for exact char equality first, since it's a common case. */
425 switch (ignore_white_space)
427 case IGNORE_ALL_SPACE:
428 /* For -w, just skip past any white space. */
429 while (isspace (c1) && c1 != '\n') c1 = *t1++;
430 while (isspace (c2) && c2 != '\n') c2 = *t2++;
433 case IGNORE_SPACE_CHANGE:
434 /* For -b, advance past any sequence of white space in
435 line 1 and consider it just one space, or nothing at
436 all if it is at the end of the line. */
451 /* Likewise for line 2. */
468 /* If we went too far when doing the simple test
469 for equality, go back to the first non-white-space
470 character in both sides and try again. */
471 if (c2 == ' ' && c1 != '\n'
473 && isspace ((unsigned char) t1[-2]))
478 if (c1 == ' ' && c2 != '\n'
480 && isspace ((unsigned char) t2[-2]))
489 case IGNORE_TRAILING_SPACE:
490 case IGNORE_TAB_EXPANSION_AND_TRAILING_SPACE:
491 if (isspace (c1) && isspace (c2))
497 while ((c = *p) != '\n' && isspace (c))
505 while ((c = *p) != '\n' && isspace (c))
510 /* Both lines have nothing but whitespace left. */
513 if (ignore_white_space == IGNORE_TRAILING_SPACE)
516 case IGNORE_TAB_EXPANSION:
517 if ((c1 == ' ' && c2 == '\t')
518 || (c1 == '\t' && c2 == ' '))
520 size_t column2 = column;
526 column += tabsize - column % tabsize;
535 column2 += tabsize - column2 % tabsize;
539 if (column != column2)
544 case IGNORE_NO_WHITE_SPACE:
548 /* Lowercase all letters if -i is specified. */
562 column += c1 == '\t' ? tabsize - column % tabsize : 1;
568 /* Find the consecutive changes at the start of the script START.
569 Return the last link before the first gap. */
571 struct change * _GL_ATTRIBUTE_CONST
572 find_change (struct change *start)
577 struct change * _GL_ATTRIBUTE_CONST
578 find_reverse_change (struct change *start)
583 /* Divide SCRIPT into pieces by calling HUNKFUN and
584 print each piece with PRINTFUN.
585 Both functions take one arg, an edit script.
587 HUNKFUN is called with the tail of the script
588 and returns the last link that belongs together with the start
591 PRINTFUN takes a subscript which belongs together (with a null
592 link at the end) and prints it. */
595 print_script (struct change *script,
596 struct change * (*hunkfun) (struct change *),
597 void (*printfun) (struct change *))
599 struct change *next = script;
603 struct change *this, *end;
605 /* Find a set of changes that belong together. */
607 end = (*hunkfun) (next);
609 /* Disconnect them from the rest of the changes,
610 making them a hunk, and remember the rest for next iteration. */
617 /* Print this hunk. */
620 /* Reconnect the script so it will all be freed properly. */
625 /* Print the text of a single line LINE,
626 flagging it with the characters in LINE_FLAG (which say whether
627 the line is inserted, deleted, changed, etc.). LINE_FLAG must not
628 end in a blank, unless it is a single blank. */
631 print_1_line (char const *line_flag, char const *const *line)
633 char const *base = line[0], *limit = line[1]; /* Help the compiler. */
634 FILE *out = outfile; /* Help the compiler some more. */
635 char const *flag_format = 0;
637 /* If -T was specified, use a Tab between the line-flag and the text.
638 Otherwise use a Space (as Unix diff does).
639 Print neither space nor tab if line-flags are empty.
640 But omit trailing blanks if requested. */
642 if (line_flag && *line_flag)
644 char const *flag_format_1 = flag_format = initial_tab ? "%s\t" : "%s ";
645 char const *line_flag_1 = line_flag;
647 if (suppress_blank_empty && **line == '\n')
649 flag_format_1 = "%s";
651 /* This hack to omit trailing blanks takes advantage of the
652 fact that the only way that LINE_FLAG can end in a blank
653 is when LINE_FLAG consists of a single blank. */
654 line_flag_1 += *line_flag_1 == ' ';
657 fprintf (out, flag_format_1, line_flag_1);
660 output_1_line (base, limit, flag_format, line_flag);
662 if ((!line_flag || line_flag[0]) && limit[-1] != '\n')
663 fprintf (out, "\n\\ %s\n", _("No newline at end of file"));
666 /* Output a line from BASE up to LIMIT.
667 With -t, expand white space characters to spaces, and if FLAG_FORMAT
668 is nonzero, output it with argument LINE_FLAG after every
669 internal carriage return, so that tab stops continue to line up. */
672 output_1_line (char const *base, char const *limit, char const *flag_format,
673 char const *line_flag)
676 fwrite (base, sizeof (char), limit - base, outfile);
679 register FILE *out = outfile;
680 register unsigned char c;
681 register char const *t = base;
682 register size_t column = 0;
683 size_t tab_size = tabsize;
690 size_t spaces = tab_size - column % tab_size;
700 if (flag_format && t < limit && *t != '\n')
701 fprintf (out, flag_format, line_flag);
713 column += isprint (c) != 0;
720 char const change_letter[] = { 0, 'd', 'a', 'c' };
722 /* Translate an internal line number (an index into diff's table of lines)
723 into an actual line number in the input file.
724 The internal line number is I. FILE points to the data on the file.
726 Internal line numbers count from 0 starting after the prefix.
727 Actual line numbers count from 1 within the entire file. */
729 lin _GL_ATTRIBUTE_PURE
730 translate_line_number (struct file_data const *file, lin i)
732 return i + file->prefix_lines + 1;
735 /* Translate a line number range. This is always done for printing,
736 so for convenience translate to long int rather than lin, so that the
737 caller can use printf with "%ld" without casting. */
740 translate_range (struct file_data const *file,
742 long int *aptr, long int *bptr)
744 *aptr = translate_line_number (file, a - 1) + 1;
745 *bptr = translate_line_number (file, b + 1) - 1;
748 /* Print a pair of line numbers with SEPCHAR, translated for file FILE.
749 If the two numbers are identical, print just one number.
751 Args A and B are internal line numbers.
752 We print the translated (real) line numbers. */
755 print_number_range (char sepchar, struct file_data *file, lin a, lin b)
757 long int trans_a, trans_b;
758 translate_range (file, a, b, &trans_a, &trans_b);
760 /* Note: we can have B < A in the case of a range of no lines.
761 In this case, we should print the line number before the range,
763 if (trans_b > trans_a)
764 fprintf (outfile, "%ld%c%ld", trans_a, sepchar, trans_b);
766 fprintf (outfile, "%ld", trans_b);
769 /* Look at a hunk of edit script and report the range of lines in each file
770 that it applies to. HUNK is the start of the hunk, which is a chain
771 of 'struct change'. The first and last line numbers of file 0 are stored in
772 *FIRST0 and *LAST0, and likewise for file 1 in *FIRST1 and *LAST1.
773 Note that these are internal line numbers that count from 0.
775 If no lines from file 0 are deleted, then FIRST0 is LAST0+1.
777 Return UNCHANGED if only ignorable lines are inserted or deleted,
778 OLD if lines of file 0 are deleted,
779 NEW if lines of file 1 are inserted,
780 and CHANGED if both kinds of changes are found. */
783 analyze_hunk (struct change *hunk,
784 lin *first0, lin *last0,
785 lin *first1, lin *last1)
789 lin show_from, show_to;
791 bool trivial = ignore_blank_lines || ignore_regexp.fastmap;
792 size_t trivial_length = ignore_blank_lines - 1;
793 /* If 0, ignore zero-length lines;
794 if SIZE_MAX, do not ignore lines just because of their length. */
796 bool skip_white_space =
797 ignore_blank_lines && IGNORE_TRAILING_SPACE <= ignore_white_space;
798 bool skip_leading_white_space =
799 skip_white_space && IGNORE_SPACE_CHANGE <= ignore_white_space;
801 char const * const *linbuf0 = files[0].linbuf; /* Help the compiler. */
802 char const * const *linbuf1 = files[1].linbuf;
804 show_from = show_to = 0;
806 *first0 = hunk->line0;
807 *first1 = hunk->line1;
812 l0 = next->line0 + next->deleted - 1;
813 l1 = next->line1 + next->inserted - 1;
814 show_from += next->deleted;
815 show_to += next->inserted;
817 for (i = next->line0; i <= l0 && trivial; i++)
819 char const *line = linbuf0[i];
820 char const *newline = linbuf0[i + 1] - 1;
821 size_t len = newline - line;
822 char const *p = line;
823 if (skip_white_space)
824 for (; *p != '\n'; p++)
825 if (! isspace ((unsigned char) *p))
827 if (! skip_leading_white_space)
831 if (newline - p != trivial_length
832 && (! ignore_regexp.fastmap
833 || re_search (&ignore_regexp, line, len, 0, len, 0) < 0))
837 for (i = next->line1; i <= l1 && trivial; i++)
839 char const *line = linbuf1[i];
840 char const *newline = linbuf1[i + 1] - 1;
841 size_t len = newline - line;
842 char const *p = line;
843 if (skip_white_space)
844 for (; *p != '\n'; p++)
845 if (! isspace ((unsigned char) *p))
847 if (! skip_leading_white_space)
851 if (newline - p != trivial_length
852 && (! ignore_regexp.fastmap
853 || re_search (&ignore_regexp, line, len, 0, len, 0) < 0))
857 while ((next = next->link) != 0);
862 /* If all inserted or deleted lines are ignorable,
863 tell the caller to ignore this hunk. */
868 return (show_from ? OLD : UNCHANGED) | (show_to ? NEW : UNCHANGED);
871 /* Concatenate three strings, returning a newly malloc'd string. */
874 concat (char const *s1, char const *s2, char const *s3)
876 char *new = xmalloc (strlen (s1) + strlen (s2) + strlen (s3) + 1);
877 sprintf (new, "%s%s%s", s1, s2, s3);
881 /* Yield a new block of SIZE bytes, initialized to zero. */
886 void *p = xmalloc (size);
892 debug_script (struct change *sp)
896 for (; sp; sp = sp->link)
898 long int line0 = sp->line0;
899 long int line1 = sp->line1;
900 long int deleted = sp->deleted;
901 long int inserted = sp->inserted;
902 fprintf (stderr, "%3ld %3ld delete %ld insert %ld\n",
903 line0, line1, deleted, inserted);