diff options
Diffstat (limited to 'gnu/diff/util.c')
| -rw-r--r-- | gnu/diff/util.c | 703 | 
1 files changed, 0 insertions, 703 deletions
diff --git a/gnu/diff/util.c b/gnu/diff/util.c deleted file mode 100644 index e72fd4d2370b..000000000000 --- a/gnu/diff/util.c +++ /dev/null @@ -1,703 +0,0 @@ -/* Support routines for GNU DIFF. -   Copyright (C) 1988, 1989, 1992 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU DIFF; see the file COPYING.  If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */ - -#include "diff.h" - -/* Use when a system call returns non-zero status. -   TEXT should normally be the file name.  */ - -void -perror_with_name (text) -     char *text; -{ -  int e = errno; -  fprintf (stderr, "%s: ", program); -  errno = e; -  perror (text); -} - -/* Use when a system call returns non-zero status and that is fatal.  */ - -void -pfatal_with_name (text) -     char *text; -{ -  int e = errno; -  print_message_queue (); -  fprintf (stderr, "%s: ", program); -  errno = e; -  perror (text); -  exit (2); -} - -/* Print an error message from the format-string FORMAT -   with args ARG1 and ARG2.  */ - -void -error (format, arg, arg1) -     char *format; -     char *arg; -     char *arg1; -{ -  fprintf (stderr, "%s: ", program); -  fprintf (stderr, format, arg, arg1); -  fprintf (stderr, "\n"); -} - -/* Print an error message containing the string TEXT, then exit.  */ - -void -fatal (m) -     char *m; -{ -  print_message_queue (); -  error ("%s", m, 0); -  exit (2); -} - -/* Like printf, except if -l in effect then save the message and print later. -   This is used for things like "binary files differ" and "Only in ...".  */ - -void -message (format, arg1, arg2) -     char *format, *arg1, *arg2; -{ -  if (paginate_flag) -    { -      struct msg *new = (struct msg *) xmalloc (sizeof (struct msg)); -      if (msg_chain_end == 0) -	msg_chain = msg_chain_end = new; -      else -	{ -	  msg_chain_end->next = new; -	  msg_chain_end = new; -	} -      new->format = format; -      new->arg1 = concat (arg1, "", ""); -      new->arg2 = concat (arg2, "", ""); -      new->next = 0; -    } -  else -    { -      if (sdiff_help_sdiff) -	putchar (' '); -      printf (format, arg1, arg2); -    } -} - -/* Output all the messages that were saved up by calls to `message'.  */ - -void -print_message_queue () -{ -  struct msg *m; - -  for (m = msg_chain; m; m = m->next) -    printf (m->format, m->arg1, m->arg2); -} - -/* Call before outputting the results of comparing files NAME0 and NAME1 -   to set up OUTFILE, the stdio stream for the output to go to. - -   Usually, OUTFILE is just stdout.  But when -l was specified -   we fork off a `pr' and make OUTFILE a pipe to it. -   `pr' then outputs to our stdout.  */ - -static char *current_name0; -static char *current_name1; -static int current_depth; - -void -setup_output (name0, name1, depth) -     char *name0, *name1; -     int depth; -{ -  current_name0 = name0; -  current_name1 = name1; -  current_depth = depth; -  outfile = 0; -} - -void -begin_output () -{ -  char *name; - -  if (outfile != 0) -    return; - -  /* Construct the header of this piece of diff.  */ -  name = (char *) xmalloc (strlen (current_name0) + strlen (current_name1) -			   + strlen (switch_string) + 15); - -  strcpy (name, "diff"); -  strcat (name, switch_string); -  strcat (name, " "); -  strcat (name, current_name0); -  strcat (name, " "); -  strcat (name, current_name1); - -  if (paginate_flag) -    { -      int pipes[2]; -      int desc; - -      /* For a `pr' and make OUTFILE a pipe to it.  */ -      if (pipe (pipes) < 0) -	pfatal_with_name ("pipe"); - -      fflush (stdout); - -      desc = vfork (); -      if (desc < 0) -	pfatal_with_name ("vfork"); - -      if (desc == 0) -	{ -	  close (pipes[1]); -	  if (pipes[0] != fileno (stdin)) -	    { -	      if (dup2 (pipes[0], fileno (stdin)) < 0) -		pfatal_with_name ("dup2"); -	      close (pipes[0]); -	    } - -	  if (execl (PR_FILE_NAME, PR_FILE_NAME, "-f", "-h", name, 0) < 0) -	    pfatal_with_name (PR_FILE_NAME); -	} -      else -	{ -	  close (pipes[0]); -	  outfile = fdopen (pipes[1], "w"); -	}  -    } -  else -    { - -      /* If -l was not specified, output the diff straight to `stdout'.  */ - -      outfile = stdout; - -      /* If handling multiple files (because scanning a directory), -	 print which files the following output is about.  */ -      if (current_depth > 0) -	printf ("%s\n", name); -    } - -  free (name); - -  /* A special header is needed at the beginning of context output.  */ -  switch (output_style) -    { -    case OUTPUT_CONTEXT: -      print_context_header (files, 0); -      break; - -    case OUTPUT_UNIFIED: -      print_context_header (files, 1); -      break; - -    default: -      break; -    } -} - -/* Call after the end of output of diffs for one file. -   Close OUTFILE and get rid of the `pr' subfork.  */ - -void -finish_output () -{ -  if (outfile != 0 && outfile != stdout) -    { -      fclose (outfile); -      wait (0); -    } - -  outfile = 0; -} - -/* Compare two lines (typically one from each input file) -   according to the command line options. -   Return 1 if the lines differ, like `bcmp'.  */ - -int -line_cmp (s1, len1, s2, len2) -     const char *s1, *s2; -     int len1, len2; -{ -  register const unsigned char *t1, *t2; -  register unsigned char end_char = line_end_char; - -  /* Check first for exact identity. -     If that is true, return 0 immediately. -     This detects the common case of exact identity -     faster than complete comparison would.  */ - -  if (len1 == len2 && bcmp (s1, s2, len1) == 0) -    return 0; - -  /* Not exactly identical, but perhaps they match anyway -     when case or whitespace is ignored.  */ - -  if (ignore_case_flag || ignore_space_change_flag || ignore_all_space_flag) -    { -      t1 = (const unsigned char *) s1; -      t2 = (const unsigned char *) s2; - -      while (1) -	{ -	  register unsigned char c1 = *t1++; -	  register unsigned char c2 = *t2++; - -	  /* Ignore horizontal whitespace if -b or -w is specified.  */ - -	  if (ignore_all_space_flag) -	    { -	      /* For -w, just skip past any white space.  */ -	      while (Is_space (c1)) c1 = *t1++; -	      while (Is_space (c2)) c2 = *t2++; -	    } -	  else if (ignore_space_change_flag) -	    { -	      /* For -b, advance past any sequence of whitespace in line 1 -		 and consider it just one Space, or nothing at all -		 if it is at the end of the line.  */ -	      if (c1 == ' ' || c1 == '\t') -		{ -		  while (1) -		    { -		      c1 = *t1++; -		      if (c1 == end_char) -			break; -		      if (c1 != ' ' && c1 != '\t') -			{ -			  --t1; -			  c1 = ' '; -			  break; -			} -		    } -		} - -	      /* Likewise for line 2.  */ -	      if (c2 == ' ' || c2 == '\t') -		{ -		  while (1) -		    { -		      c2 = *t2++; -		      if (c2 == end_char) -			break; -		      if (c2 != ' ' && c2 != '\t') -			{ -			  --t2; -			  c2 = ' '; -			  break; -			} -		    } -		} -	    } - -	  /* Upcase all letters if -i is specified.  */ - -	  if (ignore_case_flag) -	    { -	      if (islower (c1)) -		c1 = toupper (c1); -	      if (islower (c2)) -		c2 = toupper (c2); -	    } - -	  if (c1 != c2) -	    break; -	  if (c1 == end_char) -	    return 0; -	} -    } - -  return (1); -} - -/* Find the consecutive changes at the start of the script START. -   Return the last link before the first gap.  */ - -struct change * -find_change (start) -     struct change *start; -{ -  return start; -} - -struct change * -find_reverse_change (start) -     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.  */ - -void -print_script (script, hunkfun, printfun) -     struct change *script; -     struct change * (*hunkfun) (); -     void (*printfun) (); -{ -  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 = NULL; -#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.).  */ - -void -print_1_line (line_flag, line) -     const char *line_flag; -     const char * const *line; -{ -  const char *text = line[0], *limit = line[1]; /* Help the compiler.  */ -  FILE *out = outfile; /* Help the compiler some more.  */ -  const char *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 != NULL && line_flag[0] != 0) -    { -      flag_format = tab_align_flag ? "%s\t" : "%s "; -      fprintf (out, flag_format, line_flag); -    } - -  output_1_line (text, limit, flag_format, line_flag); - -  if ((line_flag == NULL || line_flag[0] != 0) && limit[-1] != '\n' -      && line_end_char == '\n') -    fprintf (out, "\n\\ No newline at end of file\n"); -} - -/* Output a line from TEXT up to LIMIT.  Without -t, output verbatim. -   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.  */ - -void -output_1_line (text, limit, flag_format, line_flag) -     const char *text, *limit, *flag_format, *line_flag; -{ -  if (!tab_expand_flag) -    fwrite (text, sizeof (char), limit - text, outfile); -  else -    { -      register FILE *out = outfile; -      register char c; -      register const char *t = text; -      register unsigned column = 0; - -      while (t < limit) -	switch ((c = *t++)) -	  { -	  case '\t': -	    { -	      unsigned spaces = TAB_WIDTH - column % TAB_WIDTH; -	      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: -	    if (textchar[(unsigned char) c]) -	      column++; -	    /* fall into */ -	  case '\f': -	  case '\v': -	    putc (c, out); -	    break; -	  } -    } -} - -int -change_letter (inserts, deletes) -     int inserts, deletes; -{ -  if (!inserts) -    return 'd'; -  else if (!deletes) -    return 'a'; -  else -    return '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 LNUM.  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.  */ - -int -translate_line_number (file, lnum) -     struct file_data *file; -     int lnum; -{ -  return lnum + file->prefix_lines + 1; -} - -void -translate_range (file, a, b, aptr, bptr) -     struct file_data *file; -     int a, b; -     int *aptr, *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.  */ - -void -print_number_range (sepchar, file, a, b) -     char sepchar; -     struct file_data *file; -     int a, b; -{ -  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, "%d%c%d", trans_a, sepchar, trans_b); -  else -    fprintf (outfile, "%d", 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. - -   Also set *DELETES nonzero if any lines of file 0 are deleted -   and set *INSERTS nonzero if any lines of file 1 are inserted. -   If only ignorable lines are inserted or deleted, both are -   set to 0.  */ - -void -analyze_hunk (hunk, first0, last0, first1, last1, deletes, inserts) -     struct change *hunk; -     int *first0, *last0, *first1, *last1; -     int *deletes, *inserts; -{ -  int f0, l0, f1, l1, show_from, show_to; -  int i; -  int nontrivial = !(ignore_blank_lines_flag || ignore_regexp_list); -  struct change *next; - -  show_from = show_to = 0; - -  f0 = hunk->line0; -  f1 = hunk->line1; - -  for (next = hunk; next; next = next->link) -    { -      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 && ! nontrivial; i++) -	if (!ignore_blank_lines_flag || files[0].linbuf[i][0] != '\n') -	  { -	    struct regexp_list *r; -	    const char *line = files[0].linbuf[i]; -	    int len = files[0].linbuf[i + 1] - line; - -	    for (r = ignore_regexp_list; r; r = r->next) -	      if (0 <= re_search (&r->buf, line, len, 0, len, 0)) -		break;	/* Found a match.  Ignore this line.  */ -	    /* If we got all the way through the regexp list without -	       finding a match, then it's nontrivial.  */ -	    if (r == NULL) -	      nontrivial = 1; -	  } - -      for (i = next->line1; i <= l1 && ! nontrivial; i++) -	if (!ignore_blank_lines_flag || files[1].linbuf[i][0] != '\n') -	  { -	    struct regexp_list *r; -	    const char *line = files[1].linbuf[i]; -	    int len = files[1].linbuf[i + 1] - line; - -	    for (r = ignore_regexp_list; r; r = r->next) -	      if (0 <= re_search (&r->buf, line, len, 0, len, 0)) -		break;	/* Found a match.  Ignore this line.  */ -	    /* If we got all the way through the regexp list without -	       finding a match, then it's nontrivial.  */ -	    if (r == NULL) -	      nontrivial = 1; -	  } -    } - -  *first0 = f0; -  *last0 = l0; -  *first1 = f1; -  *last1 = l1; - -  /* If all inserted or deleted lines are ignorable, -     tell the caller to ignore this hunk.  */ - -  if (!nontrivial) -    show_from = show_to = 0; - -  *deletes = show_from; -  *inserts = show_to; -} - -/* malloc a block of memory, with fatal error message if we can't do it. */ - -VOID * -xmalloc (size) -     unsigned size; -{ -  register VOID *value; - -  if (size == 0) -    size = 1; - -  value = (VOID *) malloc (size); - -  if (!value) -    fatal ("virtual memory exhausted"); -  return value; -} - -/* realloc a block of memory, with fatal error message if we can't do it. */ - -VOID * -xrealloc (old, size) -     VOID *old; -     unsigned int size; -{ -  register VOID *value; - -  if (size == 0) -    size = 1; - -  value = (VOID *) realloc (old, size); - -  if (!value) -    fatal ("virtual memory exhausted"); -  return value; -} - -/* Concatenate three strings, returning a newly malloc'd string.  */ - -char * -concat (s1, s2, s3) -     char *s1, *s2, *s3; -{ -  int len = strlen (s1) + strlen (s2) + strlen (s3); -  char *new = (char *) xmalloc (len + 1); -  strcpy (new, s1); -  strcat (new, s2); -  strcat (new, s3); -  return new; -} - -void -debug_script (sp) -     struct change *sp; -{ -  fflush (stdout); -  for (; sp; sp = sp->link) -    fprintf (stderr, "%3d %3d delete %d insert %d\n", -	     sp->line0, sp->line1, sp->deleted, sp->inserted); -  fflush (stderr); -} - -#if !HAVE_MEMCHR -char * -memchr (s, c, n) -     char *s; -     int c; -     size_t n; -{ -  unsigned char *p = (unsigned char *) s, *lim = p + n; -  for (;  p < lim;  p++) -    if (*p == c) -      return (char *) p; -  return 0; -} -#endif  | 
